如何在 FFMPEG/C++ 中同步音频和视频

rln*_*nes 5 c++ audio video ffmpeg

我正在从我的网络中的其他 PC 接收 2 个带有时间戳的流(一个音频和一个视频)。我可以毫无问题地将视频和音频录制到单独的文件(mp4 和 aac)中。现在我试图将 2 个流放在一个 mp4 文件中,我创建了 2 个队列,一个用于音频数据包,另一个用于视频数据包,并尝试像这样同步它们:

void * muxer(void * param) {
    QPair<AVPacket, unsigned long long int> completePacketAudio;
    QPair<AVPacket, unsigned long long int> completePacketVideo;
    AVPacket pkt;
    int vts = 0;
    int ats = 0;
    while(threadMuxRun) {
        contextMutex.lock(); 
        if(audioPacketQueue.isEmpty() && videoPacketQueue.isEmpty()) {
            contextMutex.unlock();
            Sleep(0);
            continue;
        } else if(audioPacketQueue.isEmpty()) {
            completePacketVideo = videoPacketQueue.head();
            pkt = videoPacketQueue.dequeue().first;
            pkt.pts = vts;
            vts++;
            std::cout << "video ts:" << pkt.pts << std::endl;
            av_packet_rescale_ts(&pkt, video_st.st->time_base, video_st.enc->time_base);            
        } else if(videoPacketQueue.isEmpty()) {
            completePacketAudio = audioPacketQueue.head();
            pkt = audioPacketQueue.dequeue().first;
            pkt.pts = ats;
            ats++;
            std::cout << "audio ts:" << pkt.pts << std::endl;
            av_packet_rescale_ts(&pkt, audio_st.st->time_base, audio_st.enc->time_base);
        } else {
            completePacketAudio = audioPacketQueue.head();
            completePacketVideo = videoPacketQueue.head();
            if(completePacketVideo.second < completePacketAudio.second) 
            {
                pkt = completePacketVideo.first;
                pkt.pts = vts;
                vts++;
                videoPacketQueue.dequeue();
                std::cout << "video ts:" << pkt.pts << std::endl;
                av_packet_rescale_ts(&pkt, video_st.st->time_base, video_st.enc->time_base);
            } else {
                audioPacketQueue.dequeue();
                pkt = completePacketAudio.first;
                pkt.pts = ats;
                ats++;
                std::cout << "audio ts:" << pkt.pts << std::endl;
                av_packet_rescale_ts(&pkt, audio_st.st->time_base, audio_st.enc->time_base);
            }
        }
        av_interleaved_write_frame(outputContext, &pkt);
        av_free_packet(&pkt);
        contextMutex.unlock();

    }

    return NULL;
}
Run Code Online (Sandbox Code Playgroud)

我的视频比音频快 10% 左右,音频时间正确(我录制 2 分钟时有 2 分钟,但视频只有 1:48)。

如果有人可以提供小费,请提前致谢。