bytedeco/javacv

some question about FFmpegFrameGrabber

开放

#1,913 创建于 2022年10月30日

 (2 条评论) (0 个反应) (0 位负责人)Java (1,583 个派生)batch import
help wantedquestion

仓库指标

星标
 (6,985 个星标)
PR 合并指标
 (PR 指标待抓取)

描述

Hi, I'm using Javacv to grab mp4 file's frames to push rtmp server recently, In the file , have both video and audio streams. On the way, I met some questions:

  1. how to sync the audio and video frames to rtmp? Is there some util class? or some framework code example to do this?
  2. I want to push the mp4 looply, but the FFmpegFrameGrabber's restart method not works as my guess. first, cpu usage grows multi times after the function call, and stream not show on vlc correctly.

if no loop, everything is ok, but no audio and video sync only.

Here is my code, please give me some advice about my questions, Thank you!

`

    String srcfile = "./videos/video1.mp4";
    String destfile = "rtmp://127.0.0.1:1935/live/livestream";
    frameGrabber = new FFmpegFrameGrabber(srcfile);
    Frame captured_frame = null;

    try {
        frameGrabber.start();

        recorder = new FFmpegFrameRecorder(destfile, frameGrabber.getImageWidth(), frameGrabber.getImageHeight(), frameGrabber.getAudioChannels());
        //recorder.setInterleaved(true);
        recorder.setVideoOption("tune","zerolatency");
        recorder.setVideoOption("preset", "ultrafast");
        recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
        recorder.setFormat("flv");
        recorder.setFrameRate(frameGrabber.getFrameRate());
        recorder.setVideoBitrate(frameGrabber.getVideoBitrate());
        recorder.setAudioBitrate(192000);
        recorder.setAudioOptions(frameGrabber.getAudioOptions());
        recorder.setAudioQuality(0);
        recorder.setSampleRate(16000);
        recorder.setAudioCodec(avcodec.AV_CODEC_ID_AAC);
        recorder.start();

        int total_decode_time = 0;
        int total_time = 0;
        int nLoop = 0;
        while(nLoop++ < 100){    // loop push 100 times

            while (true) {
                try {
                    captured_frame = frameGrabber.grabFrame();

                    if (captured_frame == null) {
                        System.out.println("!!! Failed cvQueryFrame");
                        frameGrabber.restart();                   // restart
                        break;
                    }

                    recorder.record(captured_frame);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
       
        // stop and release grabber and recorder, ignore...
    } catch (Exception e) {
        e.printStackTrace();
    }`

贡献者指南