我正在开发一个涉及提供各种视频内容的Web应用程序。与HTML5视频播放器不兼容的视频文件如mkv容器或H265等无法处理。尽管Web友好的音频和视频编解码器没有问题,但我在设计这些不能被HTML5视频播放器处理的视频文件的传递方案时遇到了麻烦。
到目前为止,我使用了ffmpeg在服务器上对视频文件进行转码,并创建了HLS主播放列表和VOD播放列表,在前端使用hls.js。然而,问题在于ffmpeg将播放列表视为直播流播放列表,直到整个文件转码完成后,才更改播放列表以用作VOD。因此,在转码完成之前,用户无法搜索,并且如果用户决定将视频文件快进一半,则我的服务器会不必要地转码整个文件。我正在使用以下ffmpeg命令行参数:
ffmpeg -i sample.mkv \
-c:v libx264 \
-crf 18 \
-preset ultrafast \
-maxrate 4000k \
-bufsize 8000k \
-vf "scale=1280:-1,format=yuv420p" \
-c:a copy -start_number 0 \
-hls_time 10 \
-hls_list_size 0 \
-f hls \
file.m3u8
现在为了改进这个系统,我尝试通过我的应用程序生成VOD播放列表而不是使用ffmpeg,因为格式是自说明的。Web应用程序会预先使用视频属性(如持续时间、分辨率和比特率)(这些属性已知于服务器端)生成 HLS 主列表和 VOD 播放列表,并将主列表提供给客户端。然后,客户端开始请求各个视频片段,此时服务器会单独转码并生成每个片段并进行服务。由于客户端已经拥有完整的 VOD 播放列表,因此寻求是可能的,它可以请求用户所寻求的特定片段。据我所见,好处是,如果用户决定向前寻找并在视频播放到一半时播放视频,我的服务器就不必转码整个文件。
现在我尝试使用以下命令从我的sample.mkv
手动创建10秒钟的各个片段:
ffmpeg -ss 90 \
-t 10 \
-i sample.mkv \
-g 52 \
-strict experimental \
-movflags +frag_keyframe+separate_moof+omit_tfhd_offset+empty_moov \
-c:v libx264 \
-crf 18 \
-preset ultrafast \
-maxrate 4000k \
-bufsize 8000k \
-vf "scale=1280:-1,format=yuv420p" \
-c:a copy \
fileSequence0.mp4
对于其他片段以及VOD播放列表等同样适用。
#EXTM3U
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:10
#EXT-X-VERSION:4
#EXT-X-MEDIA-SEQUENCE:0
#EXTINF:10.0,
fileSequence0.mp4
#EXTINF:10.0,
fileSequence1.mp4
...
... and so on
...
#EXT-X-ENDLIST
这段视频可以正常播放第一个片段,但后续片段无法播放。
我有几个问题:
为什么后续片段无法播放?我做错了什么?
我的技术可行吗?预设置片段持续时间会有什么问题,因为分段只能在关键帧之后进行,ffmpeg是否可以解决这个问题?
我的视频处理和生成知识非常有限。非常感谢您提供一些指导。