如何从视频文件中提取编码的传输流帧?

How to extract encoded transport stream frames from a video file?

正在寻找一种方法来从视频流(.m2t 或 .ts 文件)中提取特定帧的编码。 OpenCV 还可以轻松提取帧,但会立即对其进行解码。 给定:

我需要从文件中读取给定时间间隔内的所有帧,并按原样逐帧提供给另一个程序作为缓冲区。这里的问题是保持帧编码不变,不要 decode/encode/encapsulate 它们。

从 H.264 m2t 中选择一个帧到管道:

ffmpeg -ss 0:2:1.12 -i .\my_video.ts -c:v copy -f mpegts -frames:v 1 pipe: -y -hide_banner

显然,每一帧的时间戳都在增加。从管道将其转换为缓冲区不是问题。

问题:

  1. 这种方法是否正确提取单独的帧,因为它没有 任何 reference/recalculations 与相邻帧?
  2. 不确定标志 -f mpegts 是否真的保持框架不变。有更好的标志吗? (也许 -f null?)
  3. 如何知道提取帧的类型(i、P 或 B)?

谢谢。

这个回答稍微转移了原来的问题。但是,它完成了工作并提供了足够好的结果。

原题要求逐帧提取编码视频。建议的变体将压缩视频分批提取到标准输出中,其中包含几帧。这很容易在软件中选择,process/concatenate 稍后根据需要选择。

变体 1

此方法通过连接生成的块提供真正 流畅的视频。此方法比变体 2 消耗更多 CPU。并且电影中每个下一个块的处理时间越来越长。因此,变体 2 在性能方面更好。

ffmpeg.exe -y -nostdin -loglevel quiet -hide_banner -i "c:\temp\in.ts" -vf trim=<from_second>:<to_second> -f mpegts pipe:

键的顺序很重要,意思是:

  • -y -nostdin -loglevel quiet -hide_banner - 不要问问题,不要打印过多的输出。
  • -vf x:y - videofilter 修剪除原始文件中所需视频块的开始和停止位置之间的部分之外的所有电影。这些是花车。
  • -f mpegts - 如果输出到文件通常不需要:ffmpeg 知道从文件名导出格式。在这种情况下,结果进入管道以显式指定所需的输出格式。

变体 2

此方法通过连接生成的块提供几乎 流畅的视频。 差不多好是看得见的跳动视频,从质量上来说不是完美的方法

ffmpeg.exe -y -nostdin -loglevel quiet -hide_banner -ss <from_second> -t <chunk_duration> -i "c:\temp\in.ts" -copyts -f mpegts pipe:

不重复变体 1 中解释的选项,只有新选项:

  • -ss <from_second> - 跳过电影直到指定位置。务必在 -i 之前提供此密钥以节省处理时间。否则 ffmpeg 将读取所有电影直到指定位置,而不是跳过它。这可以以 h:mm:ss.ff 格式提供,也可以只是 float seconds.
  • -t <chunk_duration> - required/optimal 块大小。这是浮动的。如果 GOP 已知,则最好按 GOP 大小获取块。这会提高性能。
  • -copyts - 保留原始视频中视频块的时间戳。如果没有这个键,结果将只播放每个块的第一帧。欢迎更好interpretation/understanding