JavaCV读取视频和记录

时间:2014-12-04 10:35:51

标签: android ffmpeg javacv

我想在Android上合并mp4和mp3,我正在使用JavaCV,请先检查下面的代码,然后我解释了以下奇怪的错误:

private void test2() throws Exception {
    String path = Environment.getExternalStorageDirectory()
            .getAbsolutePath();

    int testId = 4;
    String videoPath = path + "/" + "sample" + testId + ".mp4";
    String audioPath = path + "/" + "love.mp3";
    String outputPath = path + "/" + "out" + testId + ".mp4";

    FrameGrabber grabber1 = new FFmpegFrameGrabber(videoPath);
    FrameGrabber grabber2 = new FFmpegFrameGrabber(audioPath);

    grabber1.start();
    grabber2.start();

    FrameRecorder recorder = new FFmpegFrameRecorder(outputPath,
            grabber1.getImageWidth(), grabber1.getImageHeight(),
            grabber2.getAudioChannels());

    double frameRate = grabber1.getFrameRate();
    recorder.setFrameRate(frameRate);
    recorder.setSampleRate(grabber2.getSampleRate());
    recorder.setVideoQuality(1);

    recorder.start();

    Frame frame1, frame2 = null;

    // getLengthInTime is correct, but getLengthInFrames not accurate.
    Log.d(TAG, " Video lengthInTime:" + grabber1.getLengthInTime()
            + " Video frames:" + grabber1.getLengthInFrames());

    // Record video.
    int count = 0;
    while (true) {
        frame1 = grabber1.grabFrame();
        if (frame1 == null) {
            break;
        }

        frame1.samples = null;
        recorder.record(frame1);
        count++;

        Log.d(TAG, "Video frame timestamp:" + grabber1.getTimestamp());
    }
    Log.d(TAG, " Video frame count:" + count);

    // Record audtio.
    long videoTimestamp = recorder.getTimestamp();
    while (true) {
        frame2 = grabber2.grabFrame();
        if (frame2 != null && grabber2.getTimestamp() <= videoTimestamp) {
            frame2.image = null;
            recorder.record(frame2);

            // Log.d(TAG, "Audio frame timestamp:" +
            // grabber2.getTimestamp());
        } else {
            break;
        }
    }

    // release
    recorder.stop();
    recorder.release();

    grabber1.stop();
    grabber2.stop();
}

输出的音频没问题,但视频被扼杀了。视频播放1s并停止1s,然后像这样重复播放。我通过手机摄像头录制的输入视频。

我试着计算视频帧的实际数量,我发现实数远远大于方法getLengthInFrames()得到的数字。

1 个答案:

答案 0 :(得分:1)

frameGrabber抓取ImageFrames和Sound Frames

如果您需要处理VideoFrame或其计数,请执行此操作

Frame grabFrame = frameGrabber.grabFrame();
if (grabFrame == null) {
                        // all frames are processed
                        System.out.println("!!! Failed cvQueryFrame");
                        runOnUiThread(new Runnable() {

                            @Override
                            public void run() {
                                Toast.makeText(RecordActivity.this, "Done !!!", Toast.LENGTH_SHORT).show();
                            }

                        });
                        break;
                    }
                    if (grabFrame.image != null) {
                           //This is a video Frame, Do your work here 
 }

}