【问题标题】:Remux and segment only parts of a video file without difference in output仅重新混合和分段视频文件的一部分,输出没有差异
【发布时间】:2013-06-16 01:53:21
【问题描述】:

我有一个基于libav 的工作程序(或者ffmpeg - 专业知识在这里有用)。

它需要一个 mp4 视频,用 h264 视频/AAC 音频编码,然后将其重新混合为 MPEG TS 并将其分段为 X 秒块。类似于下面的ffmpeg命令:

ffmpeg -y -i video.mp4 -c:a copy -bsf:a aac_adtstoasc -c:v copy -bsf:v h264_mp4toannexb -flags -global_header -map 0 -f segment -segment_time 10 -segment_list playlist.m3u8 -segment_format mpegts chunk_%03d.ts

我不使用命令行的原因是我希望只生成段的一个子集。因此,如果视频产生 10 个 8 到 12 秒之间的片段(由于关键帧,这些片段永远不会完全达到所需的长度),我可能希望稍后生成 3-7 片段。

我的程序的完整代码可以在here找到。

我使用av_read_frame 从源文件中读取每一帧,重新混合(包括位过滤器进程)并写入输出文件。一旦自上次输出以来的持续时间变得接近/大于所需的段长度,我刷新输出文件,关闭它,打开下一个段并继续。

我尝试更改代码以在第一段的末尾执行av_seek_frame 并从那里开始(我也尝试从第二和第三段的末尾开始)。新段的长度相同(以秒和 pts 为单位),但与完整运行中的可比较段(在几千字节内)具有不同的大小 - 起始段(无论是第二个、第三个还是其他)也显示为比之前的可比段少 2 个数据包。

我认为 av_seek_frame 会给我一个完全匹配的结果,就好像我手动使用 av_read_frame 循环到那个帧一样,但似乎情况并非如此。

我的愿望:

  • 一种在文件中“快进”到文件中特定(近似)点的方法。
  • 从该点开始写入并使输出与完整运行提供的输出完全相同(相同大小、相同长度、相同精确字节)。

【问题讨论】:

    标签: c video ffmpeg libav


    【解决方案1】:

    搜索通常不精确,只会将您带到文件索引中列出的点(通常是视频关键帧)。您可以尝试使用AVSEEK_FLAG_BACKWARD 标志寻找,在指定点之前寻找,然后从那里读取+丢弃。

    或者,您可能想查看FFMS2,它据称提供了一个更高级别的 libav 函数包装器,具有帧精确搜索功能。

    【讨论】:

    • 我正在寻找关键帧,所以我认为那是准确的。 FFMS2 听起来确实很有趣,而且由于缺少 libav 的文档,这可能是我的可取之处。谢谢!
    • FFMS2 看起来不错,但它似乎是只读的 - 没有写入/复用。不过 API 更好用 :)
    【解决方案2】:

    我通过执行以下操作设法让它工作:

    • 在找到实际关键帧之前寻找一点(1000 dts)。
    • 循环调用av_read_frame,直到我们到达关键帧。
    • 为每个片段编写标题和尾声avformat_write_headerav_write_trailer

    最终结果是,我可以从给定的时间戳开始,我知道一个片段即将开始并创建这些片段(并在我希望的任何片段处停止,但这很简单)。生成的片段与完整运行中创建的片段相同。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-05-01
      • 2014-02-18
      • 2015-08-24
      • 2020-01-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多