Is there an ffprobe command I can run to see if an mov file that I have is audio-only or contains video as well? I have various mov files, some of which are audio dubs and some of which are full videos.
问题:
回答1:
You can output stream information in JSON or XML:
ffprobe -show_streams -print_format json input.mov
You'll get an array of streams with a codec_type
attribute with values like audio
, video
etc.
回答2:
To output the codec_type
ffprobe -loglevel error -show_entries stream=codec_type -of default=nw=1 input.foo
Example result:
codec_type=video
codec_type=audio
If you have multiple audio or video streams the output will show multiple video or audio entries.
Same as above but output just the values
ffprobe -loglevel error -show_entries stream=codec_type -of default=nw=1=nk=1 input.foo
or:
ffprobe -loglevel error -show_entries stream=codec_type -of csv=p=0 input.foo
Example result:
video
audio
To include the stream index
ffprobe -loglevel error -show_entries stream=index,codec_type -of csv=p=0 input.foo
Example result:
0,video
1,audio
In this example the video is the first stream and the audio is the second stream which is the norm but not always the case.
Output nothing if there is no audio
ffprobe -loglevel error -select_streams a -show_entries stream=codec_type -of csv=p=0 input.foo
Example result for input with audio:
audio
If the input does not have audio then there will be no output (null output) which could be useful for scripted usage.
Other output formats
If you want different output formatting (json, ini, flat, csv, xml) see FFprobe Documentation: Writers.
回答3:
One quick way to do this is to check if the word 'Video' is in the output. Here's an example:
>>> cmd = shlex.split('%s -i %s' % (FFPROBE, video_path))
>>> p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> output = p.communicate()[1]
>>> 'Video' in output
True
I tried this for a few different files and it seemed to work on the ones I tried, though I'm sure there's a much better solution.
回答4:
To find out programmatically if a video file has audio, use avformat_open_input()
as shown here below - if audio_index
is bigger or equal to zero, then the video file has audio.
if (avformat_open_input(&pFormatCtx, filename, nullptr, nullptr) != 0) {
fprintf(stderr, "Couldn't open video file!\n");
return -1;
}
if (avformat_find_stream_info(pFormatCtx, nullptr) < 0) {
fprintf(stderr, "Couldn't find stream information!\n");
return -1;
}
av_dump_format(pFormatCtx, 0, videoState->filename, 0);
for (i = 0; i < pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO && video_index < 0)
video_index = i;
if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO && audio_index < 0)
audio_index = i;
}