android - para - crear video a partir de la secuencia de imágenes javacv
crear video en mi celular (1)
Para crear video a partir de una secuencia de imágenes en Android utilicé la librería javacv 0.6, pero encuentro un problema: normalmente funciona en teléfonos HTC Sensation (Android 4.0.1, tipo de procesador armv7) y htc Desire (Android 2.3.3, tipo de procesador arm7) , pero no funciona en htc Wildfire (Android 2.3.5, tipo de procesador armv6) teléfono, particularmente falla en esta parte del código
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(videoFilePath,
TalkingPhotoConstants.VIDEO_FRAME_WIDTH,TalkingPhotoConstants.VIDEO_FRAME_HEIGHT);
en el código adjunto.
public class MovieCreator extends AsyncTask<String, Void, Boolean> {
private opencv_core.IplImage[] iplimage;
private String audioFilePath;
private ProgressDialog progressDialog;
private Context context;
private List<TalkFrame> frames;
public MovieCreator(Context context, opencv_core.IplImage[] images, String audioFilePath,
List<TalkFrame> frames) {
this.context = context;
this.iplimage = images;
this.audioFilePath = audioFilePath;
this.frames = frames;
}
private String createMovie() {
String videoName = TalkingPhotoConstants.TMP_VIDEO_NAME;
String path = TalkingPhotoConstants.RESOURCES_TMP_FOLDER;
String videoFilePath = path + videoName;
String finalVideoName = TalkingPhotoConstants.FINAL_VIDEO_NAME +
System.currentTimeMillis() + ".mp4";
String finalVideoPath = TalkingPhotoConstants.RESOURCES_FOLDER + finalVideoName;
try {
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(videoFilePath,
TalkingPhotoConstants.VIDEO_FRAME_WIDTH,TalkingPhotoConstants.VIDEO_FRAME_HEIGHT);
//int frameCount = iplimage.length;
int frameCount = frames.size();
recorder.setAudioCodec(AV_CODEC_ID_AMR_NB);
recorder.setVideoCodec(AV_CODEC_ID_MPEG4);
recorder.setVideoBitrate(120000);
recorder.setFrameRate(TalkingPhotoConstants.VIDEO_FRAME_RATE);
recorder.setPixelFormat(AV_PIX_FMT_YUV420P);
recorder.setFormat("mp4");
recorder.start();
for (int i = 0; i < frameCount; i++) {
TalkFrame currentFrame = frames.get(i);
long duration = currentFrame.getDuration();
opencv_core.IplImage iplImage = cvLoadImage(currentFrame.getImageName());
for (int j = 0; j < TalkingPhotoConstants.VIDEO_FRAME_RATE * duration; j++) {
recorder.record(iplImage);
}
}
recorder.stop();
mergeAudioAndVideo(videoFilePath, audioFilePath, finalVideoPath);
} catch (Exception e) {
Log.e("problem", "problem", e);
finalVideoName = "";
}
return finalVideoName;
}
private boolean mergeAudioAndVideo(String videoPath, String audioPath, String outPut)
throws Exception {
boolean isCreated = true;
File file = new File(videoPath);
if (!file.exists()) {
return false;
}
FrameGrabber videoGrabber = new FFmpegFrameGrabber(videoPath);
FrameGrabber audioGrabber = new FFmpegFrameGrabber(audioPath);
videoGrabber.start();
audioGrabber.start();
FrameRecorder recorder = new FFmpegFrameRecorder(outPut,
videoGrabber.getImageWidth(), videoGrabber.getImageHeight(),
audioGrabber.getAudioChannels());
recorder.setFrameRate(videoGrabber.getFrameRate());
recorder.start();
Frame videoFrame = null, audioFrame = null;
while ((audioFrame = audioGrabber.grabFrame()) != null) {
videoFrame = videoGrabber.grabFrame();
if (videoFrame != null) {
recorder.record(videoFrame);
}
recorder.record(audioFrame);
}
recorder.stop();
videoGrabber.stop();
audioGrabber.stop();
return isCreated;
}
@Override
protected Boolean doInBackground(String... params) {
String fileName = createMovie();
boolean result = fileName.isEmpty();
if (!result) {
VideoDAO videoDAO = new VideoDAO(context);
videoDAO.open();
videoDAO.createVideo(fileName);
videoDAO.close();
}
//Utils.cleanTmpDir();
return result;
}
@Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(context);
progressDialog.setTitle("Processing...");
progressDialog.setMessage("Please wait.");
progressDialog.setCancelable(false);
progressDialog.setIndeterminate(true);
progressDialog.show();
}
@Override
protected void onPostExecute(Boolean result) {
if (progressDialog != null) {
progressDialog.dismiss();
}
}
}
No hay excepción
1. ¿Cómo puedo arreglarlo?
2. Tengo una versión que el problema está conectado con el tipo de procesador del dispositivo.
Si estoy en lo cierto, ¿cómo puedo resolverlo?
Gracias por adelantado.
JavaCV contiene algún código C nativo que es invocado por Java. Parece que tienes una versión compilada para ARMv7 pero no para ARMv6.
Para que funcione, necesitará recompilar los bits nativos de JavaCV, para el procesador al que desea enfocar (ARMv6 en este caso). Una vez que hayas hecho esto, deberías encontrar que funciona bien.
El código nativo es un problema, pero es importante para aplicaciones como esta en las que está haciendo cosas muy intensivas en CPU.