我目前正在开发一个使用视频作为登录页面背景的 Web 应用程序。视频本身相当短,大约 10 秒,但这并不重要,因为内容已被编辑为无缝循环。当我在 VLC 中播放视频时,除非我仔细观察,否则几乎不可能检测到视频重新开始的位置。我这样说是为了向您保证视频本身不是问题。
相反,当我将视频转换为 HLS 流时,问题就出现了。我尝试了各种选项和参数,但目前效果最好的是:ffmpeg -i video.mp4 -codec: copy -hls_time 1 -hls_list_size 0 -hls_segment_filename 'segment%1d.ts' -f hls stream.m3u8
。我无法简单地将视频作为源附加到我的应用程序中的原因是文件有点大,大约 15MB。我知道这对于移动数据和较差的连接来说并不好,但是客户坚持不能损害质量。这就是我想到以块为单位流式传输视频的地方,以便在收到第一个块后立即进行播放。另一种方法是先看海报图像一段时间,然后再进行播放。到目前为止,我对这个实现非常满意,但是,无缝循环存在这个问题。
每次视频重新播放时,都会出现轻微的延迟,但这种延迟足以破坏无缝循环。如果我将原始视频作为源,则不会出现此问题,但当我播放流媒体时,就会出现延迟。
问题:是否可以通过某种方式优化流,以减少甚至消除延迟?
如果有必要,我或许可以提供一个小的演示来说明这个问题,但这需要一些 JavaScript 代码。我认为问题不在于代码,因为我已经修改了其他不是我自己创建的 HLS 流,这些流可以在当前应用程序中无缝循环。
更新:经过更多测试后,我设法通过添加-force_key_frames expr:'gte(t,n_forced*1)'
初始命令稍微减少了延迟。它仍然不完美,但肯定比以前更好。
答案1
这不是您的视频的问题,而是 HLS 的工作方式的问题 - 需要先下载块列表,然后再下载第一个块(复数!)。
绕过这个问题的常用方法是构造一个包含多个循环的块列表(m3u8),总是一遍又一遍地引用相同的块
例如
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-ALLOW-CACHE:YES
#EXTINF:1.0000,untitled
segment0.ts
#EXTINF:1.0000,untitled
segment1.ts
#EXTINF:1.0000,untitled
segment2.ts
...
#EXTINF:1.0000,untitled
segment9.ts
#EXTINF:1.0000,untitled
segment0.ts
#EXTINF:1.0000,untitled
segment1.ts
...
#EXTINF:1.0000,untitled
segment9.ts
#EXTINF:1.0000,untitled
segment0.ts
#EXTINF:1.0000,untitled
segment1.ts
等等。这样,它就不再是重复的 10 秒视频,而是一个由相同片段组成的长而连续的视频,因此不会出现重复的问题。