如何使用选定的音频流将视频转换为 hls?

How to convert video to hls with selected audio streams?

我正在尝试将一些具有多个音频流的视频(不同格式,例如 mp4、mkv、avi)转换为只有一个音频的 HLS。我用 ffmpeg 尝试了不同的解决方案,但似乎没有一个是理想的。

例如 this gist 中的 ffmpeg -i in.mkv -codec: copy -f hls out.m3u8 只有在 in.mkv 有一个音频流时才有效(至少这是我的理解)。

然后我尝试了:

ffmpeg -i in.mkv -map 0:v:0 -map -0:a:0 -c copy -f hls out.m3u8

我不确定为什么这个解决方案不起作用,但取决于播放器和输入文件,视频无法正确播放(例如 hls.js 没有图像,只有偶尔的声音).

我的下一个想法是首先将 in.mkv 转换为 in_tmp.mkv,只有一个音频流,然后使用上面的要点:

ffmpeg -i in.mkv -map 0:v:0 -map -0:a:0 -c copy in_tmp.mkv
ffmpeg -i in_tmp.mkv -c copy -f hls out.m3u8

但结果与我之前的尝试相同。我的猜测是 -c copy 有问题(但坦率地说,我不太明白我在做什么)。

所以我最终使用 filter_complexconcat:

  ffmpeg -i in.mkv -filter_complex '[0:v:0][0:a:0] concat=n=1:v=1:a=1 [v] [a]' -map '[v]' -map '[a]' -f hls out.m3u8

看起来它可以工作,我试过的不同播放器都可以正确播放输出视频,但当然感觉不是最理想的:它需要很多时间并且 concat 的使用似乎非常人造的。

所以问题是如何使用或不使用 ffmpeg 仅选择一个音频流将视频转换为 HLS?

How to convert a video to HLS with only one selected audio stream?

最基本的命令:

ffmpeg -i input.mkv -c copy -f hls output.m3u8

这将使用默认的 stream selection 行为,即每种流类型选择一个流。

或使用 -map 手动 select 所需的流。此示例将 select 所有视频流和可选 select 音频流 #3(注意索引从 0 开始计数)如果音频存在:

ffmpeg -i input.mkv -c copy -map 0:v -map 0:a:3? -f hls output.m3u8

您使用 -map -0:a:0 的命令是一个否定映射,它将排除流 0:a:0

有关许多示例和更多信息,请参阅 FFmpeg Wiki: Map