检查视频文件是否包含音频

32
我试图找出视频中是否有音频,以便使用ffmpeg提取mp3。当视频不包含任何音频通道时,ffmpeg会创建一个空的mp3文件,我使用它来确定视频中是否存在音频。我相信有更好的方法来识别视频中是否存在音频。avprobe能帮助吗?有人可以指向一些资源或可能的解决方案吗?
编辑:令人惊讶的是,在运行最新版本的ffprobe的服务器上,相同的命令不起作用。它会抛出一个错误,指出“select_stream”选项无法识别。有什么想法可以纠正这个问题吗?

1
(多年后):如果其他人遇到了与编辑添加的相同错误,请检查您的命令。它应该是“select_streams”,而不是“select_stream”。 - Alfro
5个回答

39

我会使用FFprobe(它是FFMPEG的附带工具):

ffprobe -i INPUT -show_streams -select_streams a -loglevel error

如果没有音频,则不会输出任何内容。如果有音频流,则会输出以下内容:

[STREAM]

index=0

codec_name=mp3

codec_long_name=MP3(MPEG音频层3)

profile=unknown

codec_type=audio

codec_time_base=1/44100

等等

等等...

[/STREAM]

无论您使用哪种语言来自动化此过程,都应该很容易解析。


运行得非常好!相当干净利落地解决了我的问题。 - Kartos
5
这对我似乎没有用。我使用没有音频的文件仍然得到了那个输出结果。 - Matt
1
使用ffprobe版本4.2.2,您可以执行以下操作以获取JSON输出: ffprobe -i INPUT -show_streams -select_streams a -of json -loglevel error - funkycoder

8
如果是来自本地路径的普通视频文件,您可以像这样查找视频是否具有音频文件。
您需要查看MediaMetadataRetriever
通过使用METADATA_KEY_HAS_AUDIO,您可以检查视频是否具有音频。
private boolean isVideoHaveAudioTrack(String path) {
        boolean audioTrack =false;

        MediaMetadataRetriever retriever = new MediaMetadataRetriever();
        retriever.setDataSource(path);
        String hasAudioStr = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_AUDIO);
        if(hasAudioStr.equals("yes")){ 
         audioTrack=true; } 
        else{ 
        audioTrack=false; }

        return audioTrack;
    }

这里的path指的是你的视频文件路径。

PS:由于这是一个旧问题,我写下这个答案来帮助其他人,如果对他们有所帮助。


如果文件没有元数据怎么办? - ClassA

5
发现了一个解决这个问题的方法。看起来这回答了我提出的问题。
ffprobe -i input.mp4 -show_streams 2>&1 | grep 'Stream #0:1'

1
如果您确定您的音频始终是第二个流,则可以这样做。 - AJ29
只能采用这种方法,因为我的服务器上的select_streams无法正常工作。起初,我以为是由于ffmpeg等旧版本的问题,因此将其更新到最新版本。但我仍然遇到了相同的问题。你有什么想法吗? - Kartos
不好意思,我一点也不知道 :( 我回答中的命令行在我的机器上完全正常(我正在使用ffprobe版本N-56254-gb7bd688)... - AJ29
是的,这个命令在我的本地机器上也完美运行。然而,由于某种原因,在我的Ubuntu服务器上运行相同的命令会抛出以下错误:未识别选项“show_streams” 无法为选项“show_streams”设置值“-select_streams” 我正在运行ffprobe版本1.0.1,构建于2013年1月10日。 - Kartos
如果选择流对您很重要,那么您应该尝试使用更新的版本,如果不重要,则可以保持原样 ;) - AJ29

2
ffprobe -v fatal                         # set log level to fatal
        -of default=nw=1:nk=1            # use default format and hide wrappers and keys
        -show_streams                    # show info about media streams
        -select_streams a                # show only audio streams
        -show_entries stream=codec_type  # show only stream.codec_type entries
        video.mp4                        # input file

一个媒体文件包含一个音频流。
audio
1
0
0
0
0
0
0
0
0
0
0
0
und
SoundHandler

如果媒体文件中没有音频流,则返回空结果。

非媒体文件也会返回空结果。如果想要对非媒体文件和其他任何错误情况返回错误消息,请使用-v error

ffprobe -v error                         # set log level to error
        -of default=nw=1:nk=1            # use default format and hide wrappers and keys
        -show_streams                    # show info about media streams
        -select_streams a                # show only audio streams
        -show_entries stream=codec_type  # show only stream.codec_type entries
        video.mp4                        # input file

所以,你需要取代空结果:
non-media-file.zip: Invalid data found when processing input

2
如果您只想知道是否有音频,而不关心流细节,可以运行以下命令,它将提取输入文件中音频流的持续时间。如果响应为null / whitespace,则输入文件中没有音频。
命令:
ffprobe -v error -of flat=s_ -select_streams 1 -show_entries stream=duration -of default=noprint_wrappers=1:nokey=1

1
这似乎不起作用。 - Matt

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