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

标签 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
                }
            }
        }
    }

最佳答案

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

第二,不要对任何已知的视频算法(mpeg2、h264、hevc)使用 RGB 来编码视频包。使用 yuv420p。这同样会有些麻烦。

希望有帮助。

关于ffmpeg - 如何以编程方式从 mpg 视频中删除帧并保持音频同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48351765/

相关文章:

vb.net - 如何暂停ffmpeg而不是在没有窗口的情况下运行?

c# - 在 C# 中处理视频帧(FFMPEG 慢)

java - ffmpeg 加入两个 mp4 视频一个接一个

php - FFMPEG:如何在 FFMPEG Php 中使用 S3 url

ffmpeg - sws_scale 与媒体播放器实时调整大小的性能比较

c# - Call to Process 在 Debug 中运行良好,但在已安装的应用程序中不起作用

ffmpeg - MP4 容器中的 H.264 编码流在 WMP12 Windows 7 中无法正常播放

audio - 使用 ffmpeg 编码声音以在 Google Hangouts 应用程序中播放

c++ - 如何将视频级别分配给ffmpeg中的结构AVCodecContext?

c++ - FFmpeg + OpenAL - 无法播放视频中的流式声音