如何使用ffmpeg从视频中提取音频?

629
我尝试了以下命令来从视频中提取音频:
ffmpeg -i Sample.avi -vn -ar 44100 -ac 2 -ab 192k -f mp3 Sample.mp3

但是我得到了以下的输出
libavutil     50.15. 1 / 50.15. 1
libavcodec    52.72. 2 / 52.72. 2
libavformat   52.64. 2 / 52.64. 2
libavdevice   52. 2. 0 / 52. 2. 0
libavfilter    1.19. 0 /  1.19. 0
libswscale     0.11. 0 /  0.11. 0
libpostproc   51. 2. 0 / 51. 2. 0
SamplE.avi: Invalid data found when processing input

有人可以帮忙吗?谢谢!

这是关于计算机任务的问题,哪里说它必须是关于编程的? - dvdmn
13个回答

870
提取音频流而不重新编码:
ffmpeg -i input-video.avi -vn -acodec copy output-audio.aac
  • -vn 表示没有视频。
  • -acodec copy 表示使用已经存在的音频流。

查看输出以确定编解码器并设置正确的文件扩展名。


135
而不是先运行FFmpeg来检查音频流,建议使用ffprobe input-video.avi。 - FlorianB
51
如果只从视频流中提取音频,那么音频的长度可能会比视频的长度短。为了确保这种情况不会发生,可以通过同一个ffmpeg命令同时提取音频和视频,例如: "ffmpeg -i vid.avi -map 0:a audio.wav -map 0:v onlyvideo.avi"。 - BlenderBender
5
可以通过添加一个指令将原始AAC编码转换为M4A格式并进行封装来扩展此答案,这样会更好。 - Gras Double
36
在这种情况下,只需在目标路径中用“.m4a”替换“.aac”。ffmpeg足够聪明,可以猜测你的意图,并将结果封装到M4A容器中 :) - Gras Double
2
顺便说一下,我编写了一个PHP脚本,这样我只需指定输入视频文件,它就会自动确定输出音频文件的扩展名:https://superuser.com/questions/1301901/ffmpeg-how-to-determine-output-extension-automatically-ca-copy/1336570#1336570 - Gras Double
显示剩余9条评论

393
为了从电影文件(例如 AVI、MP4、MOV 等)或音频文件(例如 WAV)中编码高质量的 MP3 或 MP4 音频,我发现最好使用-q:a 0进行可变比特率编码,并且最好使用-map a指定仅获取音频并排除视频/字幕。
ffmpeg -i sample.avi -q:a 0 -map a sample.mp3

如果你想从一个视频中提取一部分音频,使用-ss选项指定起始时间戳,使用-t选项指定编码持续时间,例如从3分5秒开始提取45秒的音频:

ffmpeg -i sample.avi -ss 00:03:05 -t 00:00:45.0 -q:a 0 -map a sample.mp3
  • 时间戳应该采用HH:MM:SS.xxx格式或秒数。

  • 如果不指定-t选项,则会一直执行到结束。

  • 您可以使用-to选项代替-t选项,如果要指定范围,例如 45 秒:00:03:05 + 45 = 00:03:50

工作示例:

  1. 下载ffmpeg
  2. 打开命令提示符(开始 > 运行 > CMD),或在 Mac/Linux 上打开终端
  3. 使用cd(更改目录命令)转到具有ffmeg.exe的目录,如下所示。
  4. 输入命令并等待输出文件(或排除任何错误)

Windows enter image description here

Mac/Linux enter image description here enter image description here


7
这里是-q:a值的指南:https://trac.ffmpeg.org/wiki/Encode/MP3。零是最高质量的可变比特率(VBR)设置,通常会导致平均比特率处于合理恒定比特率(CBR)范围的上部(其中320 kbit/s是最大值,可能略高于失真压缩更适宜的点)。 - Evgeni Sergeev
6
“-map a” 是什么意思? - Iulian Onofrei
6
注意:这是将音频重新编码为有损压缩格式,会略微降低质量。如果原始音频已经被压缩过,你将会使质量下降两次,这可能会有所察觉,也可能不会。 - Davidmh
2
这个命令对我有效,而上面带有“-vn”的那个则无效。 - Mmm
2
重新编码不是提取,因此这并不能回答这个问题。 - Bachsau
显示剩余3条评论

125

提取所有音轨/流

此操作将所有音频放入一个文件中:

ffmpeg -i input.mov -map 0:a -c copy output.mov
  • -map 0:a 选取所有音频流。视频和字幕将被排除。
  • -c copy 启用流拷贝模式。这会复制音频而不是重新编码。如果您希望重新编码音频,请删除-c copy
  • 选择支持您音频格式的输出格式。请参阅容器格式比较

提取特定的音轨/流

例如提取音频流#4:

ffmpeg -i input.mkv -map 0:a:3 -c copy output.m4a
  • -map 0:a:3选择了第四个音频流(ffmpeg从0开始计数)。
  • -c copy启用了流复制模式。这将复制音频而不重新编码它。如果要重新编码音频,请删除-c copy
  • 选择支持您的音频格式的输出格式。请参见容器格式比较

提取并重新编码音频/更改格式

与上面的示例类似,但没有-c copy。各种示例:

ffmpeg -i input.mp4 -map 0:a output.mp3
ffmpeg -i input.mkv -map 0:a output.m4a
ffmpeg -i input.avi -map 0:a -c:a aac output.mka
ffmpeg -i input.mp4 output.wav

提取所有音频流

此示例中的输入包含4个音频流。每个音频流将作为单独的文件输出。

ffmpeg -i input.mov -map 0:a:0 output0.wav -map 0:a:1 output1.wav -map 0:a:2 output2.wav -map 0:a:3 output3.wav

在每个输出文件名前面添加-c copy以启用流拷贝模式。


提取特定声道

使用channelsplit滤镜。例如从立体声输入中获取前右(FR)声道的示例:

ffmpeg -i stereo.wav -filter_complex "[0:a]channelsplit=channel_layout=stereo:channels=FR[right]" -map "[right]" front_right.wav
  • channel_layout是输入的声道布局。它不会自动检测,因此您必须提供布局名称。
  • channels列出要提取的声道。
  • 有关音频声道布局名称(用于channel_layout)和声道名称(用于channels),请参见ffmpeg -layouts
  • 在过滤时无法使用流复制模式(-c copy),因此音频必须重新编码。
  • 有关更多示例,请参见FFmpeg Wiki:音频声道

-map-vn之间有什么区别?

ffmpeg具有默认的流选择行为,将每种类型的流选择1个(1视频、1音频、1字幕、1数据)。

-vn是旧的、遗留的选项。它将视频从默认的流选择行为中排除。因此,音频、字幕和数据仍然会自动选择,除非使用-an-sn-dn命令告诉它们不要选择。

-map更加复杂但也更加灵活和有用。 -map禁用默认的流选择行为,ffmpeg将只包括您使用-map选项告诉它的内容。 -map还可用于排除某些流或流类型。例如,-map 0 -map -0:v将包括所有流,除了所有视频流。

有关更多示例,请参见FFmpeg Wiki:Map


错误

无效的音频流。需要恰好一个MP3音频流。

MP3仅支持1个音频流。此错误意味着您正在尝试将多个音频流放入MP3中。这也可能意味着您正在尝试将非MP3音频放入MP3中。

WAVE文件只有一个流

类似于上述情况。

无法在流#0中找到编解码器的标记,容器当前不支持该编解码器

您正在尝试将一个音频格式放入不支持它的输出中,例如将PCM(WAV)放入MP4中。

删除-c copy,选择其他输出格式(更改文件名扩展名)或手动选择编码器(例如-c:a aac)。

请参见容器格式比较表

无法为输出文件#0编写标题(编解码器参数不正确?):无效的参数

这是一个无用的、通用的错误。实际的、有信息的错误应该紧接在这个通用错误消息之前。


当您不确定有多少个音频流时,如何执行“单独提取所有音频流”的操作?我需要一种通用的方法来单独提取所有音频流。 - Raleigh L.

63
似乎你正在从视频文件中提取音频并将其混合为立体声通道。
如果只想提取音频(而不重新编码),请按照以下步骤操作:
ffmpeg -i in.mp4 -vn -c:a copy out.m4a

提取音频并混缩为立体声(无需重新编码):
ffmpeg -i in.mp4 -vn -c:a copy -ac 2 out.m4a

生成一个mp3文件,你需要重新编码音频。
ffmpeg -i in.mp4 -vn -ac 2 out.mp3

-c (选择编解码器) & -map (选择流) 选项:

-c:a -> 选择最佳支持的音频(转码)
-c:a copy -> 最佳支持的音频(复制)
-map 0:a -> 来自第一个(音频)输入文件的所有音频(转码)
-map 0:0 -> 来自第一个输入文件的第一个流(转码)
-map 1:a:0 -> 来自第二个(音频)输入文件的第一个音频流(转码)
-map 1:a:1 -c:a copy -> 来自第二个(音频)输入文件的第二个音频流(复制)


3
必须重新编码才能进行混音(或进行其他修改)。 - Gyan
这只提取第一个音轨。我如何提取第二个?(或者所有的,分别保存到文件中?) - Phil Goetz
2
@PhilGoetz:对于第一个输入文件中的第二个音频/流:-map 0:a:1 - Zimba

13

ffmpeg -i sample.avi命令可以为您的文件提供音频/视频格式信息。确保您已经配置了适当的库以解析输入流。另外,确保该文件没有损坏。


现在,当我尝试使用.mkv视频时,我得到了正确的结果。为什么对于.avi不起作用?是否有任何ffmpeg命令可以转换.avi? - user1269669
1
AVI或MKV是容器格式,可以容纳许多不同的音频/视频格式。你不是要转换AVI音频,而是要转换AVI文件中的音频轨道,但你还没有指定它。使用我上面列出的命令查看AVI文件中包含的音频轨道的类型。如果是MP3,你需要使用像LAME http://lame.sourceforge.net/这样的MP3库编译FFMPEG。 - smp

12
命令行正确,可用于有效的视频文件。请确保你已经安装了正确的库来处理mp3文件,安装lame或者探测其他音频编解码器。
通常情况下:
ffmpeg -formats
或者
ffmpeg -codecs

会提供足够的信息,以便您了解更多。


11

为编码mp3音频,ffmpeg.org 给出以下示例:

ffmpeg -i input.wav -codec:a libmp3lame -qscale:a 2 output.mp3

我只是通过将input.wav替换为视频文件名就提取出了音频。数字2表示190 kb / s的比特率。您可以在上面的链接中查看其他质量级别。


那个例子是用于将音频文件转换为不同的格式,而不是从视频中提取它。 - Iulian Onofrei
@IulianOnofrei,正如我在答案中所描述的那样,您可以用视频文件替换音频文件。这对我很有效。 - Suragch

11

如果您正在寻找从视频文件中提取音频的简单方法,同时保留原始视频文件的参数,则可以使用:

ffmpeg -i <video_file_name.extension> <audio_file_name.extension>
例如,运行:

For example, running:

ffmpeg -i screencap.mov screencap.mp3
从一个 mov 视频文件中提取出一个 mp3 音频文件。

6
简单易用。为什么其他解决方案都这么复杂?+1 - SMBiggs
2
问题是,为什么这个有删除投票?! - Iulian Onofrei
1
确实,这对我每次都有效。为什么它还不是最佳答案呢? - sourabh gupta
2
@SMBiggs:因为这会重新编码音频,导致失去质量。 - Dan Dascalescu
1
@DanDascalescu,视频文件可以包含MP3音频吗?如果是,这个命令在这种情况下是否重新编码音频? - Iulian Onofrei
2
@DanDascalescu 我不知道这个,谢谢你指出来! - SMBiggs

9

以下是我刚刚使用的内容:

ffmpeg -i my.mkv -map 0:3 -vn -b:a 320k my.mp3

选项说明:

  • my.mkv是源视频文件,您也可以使用其他格式
  • -map 0:3表示我想从视频文件中获取第3个流。将您的N放在这里--视频文件通常有多个音频流;您可以省略它或使用-map 0:a来获取默认音频流。运行ffprobe my.mkv查看视频文件有哪些流。
  • my.mp3是目标音频文件名,ffmpeg通过扩展名确定我想要一个MP3。在我的情况下,源音频流是ac3 DTS,仅仅复制不是我想要的。
  • 320k是期望的目标比特率
  • -vn表示我不希望目标文件中包含视频

6

从多个视频剪辑中创建有声读物

  1. 首先,从一堆h264文件中提取音频(.m4a格式):
for f in *.mp4; do ffmpeg -i "$f" -vn -c:a copy "$(basename "$f" .mp4).m4a"; done

-vn 输出选项禁用视频输出(自动选择或映射任何视频流)。如需完全手动控制,请参阅 -map 选项。

可选

  1. 如果有一个40秒的开头,您可以使用 -ss 参数跳过它:
for f in *.m4a; do ffmpeg -i "$f" -ss 00:00:40  -c copy crop/"$f"; done
  1. 将所有文件合并为一个:
ffmpeg -f concat -safe 0 -i <(for f in ./*.m4a; do echo "file '$PWD/$f'"; done) -c copy output.m4a

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接