如何从视频中提取音频与ffmpeg?

我尝试了以下命令从视频中提取音频:

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

有人能帮忙吗?

500794 次浏览

ffmpeg -i sample.avi将为您的文件提供音频/视频格式信息。确保配置了正确的库来解析输入流。另外,要确保文件没有损坏。

命令行是正确的,工作在一个有效的视频文件。我会确保你已经安装了正确的库工作与mp3,安装蹩脚o探头与另一个音频编解码器。

通常

ffmpeg -formats

ffmpeg -codecs

会提供足够的信息让你知道更多。

如果封装到avi中的音频一开始不是mp3格式,您可能需要指定-acodec mp3作为附加参数。或者不管你的mp3编解码器是什么(在Linux系统上可能是-acodec libmp3lame)。您还可以通过指定-f mp3来“强制”将格式转换为mp3,从而获得与平台无关的相同效果,尽管不是所有版本的ffmpeg仍然支持这种切换。你的里程可能会有所不同。

提取音频流,不需要重新编码。

ffmpeg -i input-video.avi -vn -acodec copy output-audio.aac
  • -vn没有视频。
  • -acodec copy表示使用已经存在的相同音频流。

读取输出,看看它是什么编解码器,以设置正确的文件名扩展名。

要从电影文件(如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选项,它将被放置到结尾。

  • 你可以使用——选项而不是- t选项,如果你想指定范围,例如45秒:00:03:05 + 45 = 00:03:50

工作的例子:

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

< >强窗口 # EYZ0 < / p >

< >强Mac / Linux enter image description here # EYZ0 < / p >

编码mp3音频ffmpeg.org显示如下示例:

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

我从视频中提取音频,只是用视频文件名替换input.wav。EYZ1表示190 kb/秒。您可以在上面的链接中看到其他质量级别。

使用-b:a而不是-ab,因为-ab现在已经过时了,还要确保您输入的文件路径是正确的。

从视频中提取音频,我已经使用下面的命令和它的工作良好。

String[] complexCommand = {"-y", "-i", inputFileAbsolutePath, "-vn", "-ar", "44100", "-ac", "2", "-b:a", "256k", "-f", "mp3", outputFileAbsolutePath};

在这里,

  • -y -覆盖输出文件而不询问。
  • -i - FFmpeg从-i选项指定的任意数量的输入“文件”中读取
  • -vn -禁用视频录制
  • -ar -设置音频流编码时的采样率
  • -ac -设置音频通道的数量。
  • -b:a -设置音频比特率
  • -f -格式

在GitHub上查看我完整的FFmpeg android项目示例< >强这< / >强

为了提取而不进行转换,我使用上下文菜单项-作为Linux中的文件管理器自定义操作-来运行以下(在检查了视频包含的音频类型之后;例如包含ogg音频的视频):

bash -c 'ffmpeg -i "$0" -map 0:a -c:a copy "${0%%.*}".ogg' %f

它基于ffmpeg命令ffmpeg -i INPUT -map 0:a -c:a copy OUTPUT

我使用-map 0:1没有问题,但是,正如@ lord necbeard的评论中所说的,“流#EYZ1不能保证总是音频。使用#EYZ2而不是-map 0:1可以避免歧义。”

对于寻找更简单的方法从视频文件中提取音频,同时保留原始视频文件的参数的人,您可以使用:

ffmpeg -i <video_file_name.extension> <audio_file_name.extension>

例如,运行:

ffmpeg -i screencap.mov screencap.mp3

mov视频文件中提取mp3音频文件。

这是我刚才用的:

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

选项的解释:

  • 我的。MKV是一个源视频文件,你也可以使用其他格式
  • -map 0:3意味着我想从视频文件的第三流。把你的N放在那里——视频文件通常有多个音频流;你可以省略它或使用-map 0:a来获取默认的音频流。运行ffprobe my.mkv查看视频文件有哪些流。
  • MP3是一个目标音频文件名,ffmpeg从它的扩展中计算出我想要一个MP3。在我的情况下,源音频流是ac3 DTS,只是复制不是我想要的
  • 320k是理想的比特率目标
  • -vn表示我不希望目标文件中有视频

提取所有音频轨道/流

这将所有音频放入一个文件:

ffmpeg -i input.mov -map 0:a -c copy output.mov
  • -map 0:a只选择所有音频流。视频和字幕将被排除在外。
  • -c copy启用流复制模式。这复制音频,不重新编码。如果你想重新编码音频,移除-c copy
  • 选择一种支持音频格式的输出格式。看到# EYZ0。

提取一个特定的音轨/流

提取音频流#4的例子:

ffmpeg -i input.mkv -map 0:a:3 -c copy output.m4a
  • -map 0:a:3只选择音频流#4 (ffmpeg从0开始计数)。
  • -c copy启用流复制模式。这复制音频,不重新编码。如果你想重新编码音频,移除-c copy
  • 选择一种支持音频格式的输出格式。看到# EYZ0。

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

类似于上面的例子,但是没有-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个数据)。

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

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

更多示例参见FFmpeg Wiki:地图


错误

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

MP3只支持1个音频流。该错误意味着您正在尝试将多个音频流放入MP3。它也可以表示您正在尝试将非MP3音频转换为MP3。

WAVE文件只有一个流

类似于上面。

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

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

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

看到# EYZ0。

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

这是一个无用的通用错误。实际的、信息丰富的错误应该立即出现在这个通用错误消息之前。

似乎你正在从视频文件中提取音频&调到立体声频道。< br > 只提取音频(不重新编码):

ffmpeg.exe -i in.mp4 -vn -c:a copy out.m4a

提取音频&混音到立体声(没有重新编码):

ffmpeg.exe -i in.mp4 -vn -c:a copy -ac 2 out.m4a

要生成一个mp3文件,你需要重新编码音频:

ffmpeg.exe -i in.mp4 -vn -ac 2 out.mp3

-c (select codecs) &-map (select streams)选项:

< p > # EYZ0→选择最佳支持的音频(转码)
# EYZ0→最佳支持的音频(复制)
# EYZ0→所有音频从第一个(音频)输入文件(转码)
# EYZ0→第一个输入文件的第一个流(转码)
# EYZ0→来自第二个(音频)输入文件(转码)的第一个音频流
# EYZ0→来自第2(音频)输入文件(复制)的第2音频流

从几个视频剪辑创建一个音频书

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

-vn output选项禁用视频输出(自动选择或映射任何视频流)。对于全手动控制,请参阅-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