如何以编程方式从mpg视频中删除帧并保持音频同步?

时间:2018-01-20 01:32:30

标签: ffmpeg

我从工作中传输培训视频,但没有很好的连接并且获得了很多缓冲。我已将流式视频从PC屏幕捕获到mpg文件中。幸运的是,当视频缓冲时,它会在屏幕中央显示一个特有的缓冲图标,并且没有声音。使用ffmpeg,我已经能够编写一个c ++方法,可以逐步浏览mpeg文件的视频帧,转换为RBG帧并检测是否存在这个特征缓冲图标。

我需要做的最后一件事是生成一个新的mpeg文件,其中只有没有此缓冲图像的帧,并保持所有音频同步。我如何用ffmpeg做到这一点?

我已经在视频和音频帧上找到了dts和pts时间戳,但是不知道如何使用这些信息来重新编码没有缓冲图像的帧。重新编码应保留原始的所有属性(帧速率,分辨率,大小等)

这是我用来遍历框架并检测我想要保留哪些内容的细分代码(省略大量初始化和错误检查)

while (av_read_frame(pFormatCtx, &packet) >= 0)
    {
        // Is this a packet from the video stream?
        if (packet.stream_index == videoStream)
        {
            // Decode video frame
            avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);

            // Did we get a video frame?
            if (frameFinished)
            {
                // Convert the image from its native format to RGB
                sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data, pFrame->linesize, 0, pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
                if (ThisIsAFrameIWant(pFrameRGB))
                {
                    WRITE FRAME TO NEW MPEG KEEPING AUDIO IN SYNC
                }
            }
        }
    }

1 个答案:

答案 0 :(得分:1)

这需要一些专业知识 如果您还没有第一个,则应创建具有视频和音频流的新输出上下文(即mpeg2 + mp2) 我的经验说,如果有问题的流(你有),你可以忘记pts / dts的事情(那里的其他一些人谁更了解我的客人......)。相反,您可以将视频和音频保存在单独的缓冲区中(av_read_frame()之后的传入数据包)。对于ffplay的查找,它在某些结构中有videoqueueaudioqueue,请使用它。
对于音频,您需要在排队前进行一些处理。 Trick是音频帧(或使用av_read_frame()获得的数据包)如果不等于audio samples per frame,您应该手动执行额外的缓冲。例如,对于60hz视频,16位48000hz pcm16音频应该每帧具有48000/60 = 800个音频样本。如果你能管理这个。保持/ v同步很容易,只需确保音频和视频在缓冲区中具有相同数量的数据包。因此,如果丢弃视频数据包,请对音频执行相同操作。

第二,不要将RGB用于任何已知的视频算法(mpeg2,h264,hevc)来编码视频数据包。使用yuv420p。这也有些麻烦。

希望有所帮助。