I am attempting to use javacv/ffmpeg to compress video on an Android device prior to upload. I am using this code:
FrameGrabber grabber = new FFmpegFrameGrabber(inputFile.getAbsolutePath());
grabber.start();
FFmpegFrameRecorder recorder = new FFmpegFrameRecorder(outputFile.getAbsolutePath(),
grabber.getImageWidth(), grabber.getImageHeight(),
grabber.getAudioChannels());
recorder.setVideoCodec(com.googlecode.javacv.cpp.avcodec.AV_CODEC_ID_MPEG4);
recorder.setAudioCodec(com.googlecode.javacv.cpp.avcodec.AV_CODEC_ID_PCM_S16LE);
recorder.setPixelFormat(com.googlecode.javacv.cpp.avutil.AV_PIX_FMT_YUV420P);
/* Unclear if I need these lines or not */
// recorder.setFrameRate(grabber.getFrameRate());
// recorder.setSampleRate(grabber.getSampleRate());
// recorder.setFormat("mp4");
/* End unclear lines */
recorder.start();
Frame frame;
int totalFrames = grabber.getLengthInFrames();
for (int i = 0; i < totalFrames; i++) {
frame = grabber.grabFrame();
if (frame == null) break;
recorder.record(frame);
}
recorder.stop();
grabber.stop();
This code crashes 100% of the time at FFmpegFrameGrabber line 584, which is the line:
frame.samples = samples_buf.position(0).limit(data_size / av_get_bytes_per_sample(samples_frame.format()));
This is because samples_buf is null, because samples_frame.format() does not appear to match any of the cases (AV_SAMPLE_FMT_U8, AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_FLT, AV_SAMPLE_FMT_DBL).
I attempted to avoid this crash by using the grab() method instead of the grabFrame() method, because the grab() method skips audio processing. However, the video I end up with does not play back when I extract it off the device and attempt playback in a web browser, for example.
I have tried numerous iterations of this code, including this code, all to no avail, all crashing because of line above.
Can anyone advise the shortest working path to compressing a video using javacv/ffmpeg on Android?
Thanks!