Remux和仅分割视频文件的一部分而没有输出差异

时间:2013-06-19 13:40:11

标签: c video ffmpeg libav

我有一个建立在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从源文件,remux(包括bitfilter进程)读取每一帧并写入输出文件。一旦自上一次输出后的持续时间变得接近/大于所需的段长度,我将刷新输出文件,关闭它,打开下一段并继续。

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

我认为av_seek_frame会给我一个完全匹配,好像我已经手动完成了一个av_read_frame到该帧的循环,但似乎并非如此。

我的意愿:

  • 将文件中的“快进”方式转换为文件中特定(近似值)的方法。
  • 要从那一点向前写入并使输出与输出完全相同,则完整运行提供(相同大小,相同长度,相同的精确字节)。

2 个答案:

答案 0 :(得分:1)

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

或者你可能想看一下FFMS2,它应该提供一个更高级别的包装器,围绕libav函数进行帧精确搜索。

答案 1 :(得分:0)

我设法通过以下方式让它发挥作用:

  • 在找到实际关键帧之前寻找一点(1000分)。
  • 在循环中调用av_read_frame,直到我们到达关键帧。
  • 为每个细分受众群撰写标题和预告片avformat_write_headerav_write_trailer

最终的结果是我可以从一个给定的时间戳开始,我知道一个段即将开始并创建这些段(并停在我希望的任何段,但这是微不足道的)。生成的段与完全runthrough中创建的段相同。