首页 > 解决方案 > 自包含 fmp4 片段的 HLS 播放列表

问题描述

我正在开发一个以 MPEGTS 格式存储 10 秒长视频片段的 VMS。然后可以使用 HLS 流式传输这些片段,播放列表如下所示:

#EXTM3U
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:11
#EXT-X-PLAYLIST-TYPE:EVENT
#EXT-X-START:TIME-OFFSET=1.0,PRECISE=YES
#EXTINF:10,
1602816779831000000.ts
#EXTINF:10,
1602816789831000000.ts
#EXT-X-ENDLIST

只要这些文件以 h.264 编码,这就很好用。但是,如果我尝试使用 h.265 片段创建类似的播放列表,它仅适用于我们的 Android 客户端、Apple 和 hls.js,它们决定仅使用片段 MP4 支持 h.265 HLS。

通过直接存储 fmp4 文件来“本机”支持 h.265 对我来说不是一个选择,所以我想按需将这些 MPEGTS 文件转换为 fmp4。

所以我试图做的是,返回这个播放列表(只改变文件扩展名):

#EXTM3U
#EXT-X-INDEPENDENT-SEGMENTS
#EXT-X-VERSION:6
#EXT-X-TARGETDURATION:11
#EXT-X-PLAYLIST-TYPE:EVENT
#EXT-X-START:TIME-OFFSET=1.0,PRECISE=YES
#EXTINF:10,
1602816779831000000.mp4
#EXTINF:10,
1602816789831000000.mp4
#EXT-X-ENDLIST

然后在收到请求时使用 FFMPEG 将这些 MPEGTS 文件一个一个地打包到 fmp4 中:

ffmpeg -i 1602816779831000000.ts -c copy -movflags frag_keyframe+empty_moov+default_base_moof 1602816779831000000.mp4
ffmpeg -i 1602816789831000000.ts -c copy -movflags frag_keyframe+empty_moov+default_base_moof 1602816789831000000.mp4

不幸的是,这似乎仅适用于具有单个片段的播放列表(这意味着,在我的情况下最多 10 秒)。一旦我有 2 个以上的文件,它就不起作用,其行为会根据我使用的客户端而改变:有些会播放第一个文件然后停止,有些会快进到最后一个文件然后播放这个相反,有些根本不会玩...

我了解通过 HLS 进行 fmp4 流式传输的“正常”方法是使用“媒体初始化”段并将其放在#EXT-X-MAP每个段的标头中,然后通常将其编码为 *.m4s 文件而不是 *.mp4。但是,是否有可能让 fmp4 在 HLS 上使用自包含的片段,就像我们可以用 MPEGTS 做的一样?由于具有单个条目的播放列表似乎支持这一点,我认为可能有一种方法可以做到这一点。

另外,我知道 Apple 在 HLS 规范的这一部分受到 MPEG-DASH 的启发,据我了解,这在 MPEG-DASH 中是可能的

标签: ffmpeghttp-live-streamingh.265fmp4

解决方案


推荐阅读