如何将同一片段多次包含到 m3u8 播放列表中?

How to include same segment into m3u8 playlist multiple times?

我有几个 .ts 文件,由 ffmpeg 从实时流生成。它们都具有相同的长度(好吧,大约)。理想情况下,它们会不断生成,名称代表记录它们的日期时间(例如,“2019-04-11_10-51-40.ts”)。但它可能会发生这样的情况,由于任何技术原因,记录被停止了一段时间并且没有生成文件。

现在,我的任务是为特定日期时间范围创建这些文件的播放列表 - 如果该范围的一部分没有文件,我只需要显示黑屏。为此,我有一个黑色视频,其长度与其他文件相同。所以,我正在尝试手动创建一个 .m3u8 文件,并将这个黑色视频插入到我拥有的普通视频之间的所有间隙中。例如:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:34
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:30.07,
http://example.com/black_video.ts
#EXTINF:30.07,
http://example.com/black_video.ts
#EXTINF:33.33,
http://example.com/2019-04-11_10-51-40.ts
#EXTINF:33.33,
http://example.com/2019-04-11_10-52-15.ts
#EXTINF:25.00,
http://example.com/2019-04-11_10-52-48.ts
#EXT-X-ENDLIST

问题是,当我尝试播放此播放列表时,它无法正确播放:取决于播放器,无论序列中有多少黑色部分,都只播放一个黑色部分 (VLC) ,或者播放器在第一个黑色视频后卡住(Chrome 的扩展 "Play HLS M3u8" 或我们自己服务的播放器,基于 hls.js)。

我也试过用#EXT-X-DISCONTINUITY;在这种情况下,正在播放所有视频,但进度条在每次 #EXT-X-DISCONTINUITY 出现后下降到最开始,这也是一种不受欢迎的行为。示例:

#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:34
#EXT-X-PLAYLIST-TYPE:VOD
#EXTINF:30.07,
http://example.com/black_video.ts
#EXT-X-DISCONTINUITY
#EXTINF:30.07,
http://example.com/black_video.ts
#EXTINF:33.33,
http://example.com/2019-04-11_10-51-40.ts
#EXTINF:33.33,
http://example.com/2019-04-11_10-52-15.ts
#EXTINF:25.00,
http://example.com/2019-04-11_10-52-48.ts
#EXT-X-ENDLIST

至于黑色视频本身,我尝试了几种选择:每个 link 都指向同一个文件;每个 link 是同一个文件的不同 symlink;每个 link 都是一个单独生成的黑色视频 - none 个有效。

到目前为止,我找到的唯一方法是收集该时间范围内的所有正常视频,用黑色视频文件填充空白,然后将它们与 ffmpeg -f concat 合并为一个文件,然后将连接的文件拆分回来到零件。但是这种方法比手动创建 m3u8 文件的时间更长,所以我想避免它。

那么,手动形成的播放列表无法正常工作的原因是什么?我该如何解决?可能是播放列表本身的问题,或者播放列表在技术上没问题,但我使用的播放器可能没有完全实现规范?

TLDR: 我正在手动创建 m3u8 播放列表,我想将同一视频多次插入到该播放列表中。不幸的是,这样的播放列表没有被正确播放:取决于播放器,这个插入的视频无论被包含多少次都只播放一次,或者播放在第一个插入的视频部分之后卡住。可能是播放列表有问题,如何解决?

在 black_video.ts 文件前后添加#EXT-X-DISCONTINUITY 标签,并将#EXT-X-VERSION 标签更改为 5。这应该可以解决问题。此解决方案适用于 VLC 播放器。