video - 制作小剪辑时,FFmpeg 会下载整个直播流
问题描述
设置
我正在使用 FFmpeg 从 M3U8 视频生成视频剪辑。该命令如下所示:
ffmpeg -ss <start> -i <1080p-chunklist-url> -c:v copy -c:a copy -t <duration> -f mp4 -y out.mp4
例如,要为特定视频创建从 5 分钟标记开始的 30 秒剪辑,命令将是:
ffmpeg -ss 300 -i https://example.com/path/to/1080p/index.m3u8 -c:v copy -c:a copy -t 30 -f mp4 -y out.mp4
我已经知道的一些警告:
- 如果在
-ss
此之后,FFmpeg 将尝试下载整个 M3U8 而不仅仅是相关的 TS 文件,并将解析整个视频内容以寻找确切的时间戳。通过放在-i FFmpeg之前使用“搜索点”,这对于 HLS 视频意味着它查看 M3U8 并且只下载相关的 TS 文件-i
-ss
- TS 文件边界在 HLS 中充当“搜索点”,因此如果 TS 文件从 4:51 开始,而下一个 TS 文件从 5:01 开始,则此命令将在 4:51 而不是 5:01 开始剪辑(它更喜欢请求时间之前的第一个搜索点)
- 该
-t
参数设置精确的剪辑持续时间而不是结束位置,因此在上面的剪辑示例中,从 4:51 开始,相同的剪辑将在 5:21 而不是 5:30 结束
理论上我可以使用-to
而不是-t
指定结束时间 5:30,但实际上这并没有奏效。同样在理论上我可以强制-accurate_seeking
丢弃 4:51 到 5:00 的内容并在我想要的地方开始剪辑,但我了解到这仅适用于转码而不是 transmux
现在到我的问题的实质:
问题
当提供的 M3U8 URL 是实时流(无#EXT-X-ENDLIST
标签)时,FFmpeg 的行为不正确。在 FFmpeg 版本 4.2.1 及更早版本上,它首先下载包含我的剪辑片段的 TS 文件,然后继续下载M3U8 中的每个TS 文件,然后在等待新 TS 文件可用时挂起,在它们出现时下载它们 - 甚至小时在我想剪辑的部分结束后。在 FFmpeg 4.2.2 及更高版本上,我可以创建剪辑,只要它们在倒数第二个 TS 文件之前结束。如果直播流当前有 20 分钟的视频数据,并且我在 19:30 - 19:40 创建了一个剪辑(在倒数第二个 TS 文件的开头结束,假设 TS 文件持续时间为 10 秒),那么它的行为与 4.2.1 相同:无限等待下载整个视频。
我认为“从末尾开始的 2 个 TS 文件”规则与 FFmpeg 对视频的初始探测以获取流数据有关。在前面提到的 20 分钟长的视频中,如果我从 3:00 到 3:30(远在流结束之前)制作剪辑,它将首先下载 TS 文件 119 和 120(19:40-19:50 和 19 :50-20:00),然后它显示视频中的流列表(音频、视频、元数据),然后下载 TS 文件 19 - 21(包含我想要的剪辑的实际数据)
有没有办法修复它,以便我可以正确地在现场 M3U8 的“末端”附近制作部分剪辑?
解决方案
推荐阅读
- r - R:进度条不从 0 开始
- javascript - Raycaster 在窗口的第二个场景中没有找到相交
- angular - 获取无法读取未定义错误的属性“控件”
- spring-boot - 兔子模板确认回调不起作用
- spring - Spring aop 自定义注释在 Handler Interceptor 类中给出错误
- java - 如何修复 SQLException “找不到适合 jdbc 的驱动程序”?
- json - 当结构属性是可选的时,如何检测数据值是否为零
- c# - 从 DbSet 映射 T
使用 EF 进入 Dabase 内部表示 - mysql - 获取 1 个月内过期的记录
- scala - spark如何将数据加载到内存中