如何根据结果解析ffprobe输出并运行ffmpeg?

时间:2012-04-02 23:46:28

标签: bash ffmpeg

所以我在为Mac创建一个ffmpeg二进制文件时遇到了令人难以置信的麻烦,它可以满足我的所有需求。我有一个较旧的版本,可以很好地恢复h264视频没有问题,但缺少我需要的库,即libspeex。我构建了一个基于ffmpeg的git的新构建,其中包括libspeex,但在尝试使用错误的时间码(来自rtmpdump的实时转储)从.flv文件中重新启动h264时崩溃了。所以我有两个ffmpeg二进制文件,每个都做我需要的一半。这就是我当前的.command文件:

for f in ~/Desktop/Uploads/*.flv
do
/usr/local/bin/ffmpeg -i "$f" -vcodec copy -acodec libfaac -ab 128k -ar 48000 -async 1 "${f%.*}".mp4 && rmtrash "$f" || rmtrash "${f%.*}".mp4
done

这个ffmpeg二进制文件包含libspeex,因此它可以解码.flv输入文件中的speex音频。我正在寻找的是像这样的伪代码(我第一次尝试伪代码,对我来说是裸露的!):

for f in ~/Desktop/Uploads/*.flv
do
ffprobe input.flv
    if Stream #0:1 contains speex
        ffmpeg-speex -i input.flv -acodec copy -async 1 output.m4a
    fi
ffmpeg-h264 -i input.flv -vcodec copy output.mp4
MP4Box -add output.mp4 -add output.m4a finaloutput.mp4
done

这样的事情可能吗?还有其他选择吗? (任何人都想用libspeex,libfaac和libx264构建我的Mac ffmpeg?; D)欢迎所有想法!感谢。

2 个答案:

答案 0 :(得分:1)

您可以在其输出上运行grep并测试是否找到了您想要的字符串:

for f in ~/Desktop/Uploads/*.flv; do
    if ffprobe ${f} 2>&1 | egrep 'Stream #0:1.+speex'; then
        ffmpeg-speex -i ${f} -acodec copy -async 1 ${f/%.flv/.m4a}
        SPEEX_ADD="-add ${f/%.flv/.m4a}"
    fi
    ffmpeg-h264 -i ${f} -vcodec copy ${f/%.flv/.mp4}
    MP4Box -add ${f/%.flv/.mp4} ${SPEEX_ADD} ${f/%.flv/-final.mp4}
done

假设输入文件abc.flvffmpeg-speex将输出abc.m4affmpeg-h264将输出abc.mp4MP4Box将输出abc-final.mp4 }}

编辑:也固定在stderr上的grep;已修复的问题,可能会将不存在的.m4a文件作为输入提供给MP4Box

答案 1 :(得分:0)

现在发布的ffprobe版本具有-print_format标志,在您的情况下可能有用。我有一个类似的问题,我想获得视频的长度。我使用-print_format xml标志,然后在结果上使用xmllint获取值。您只需要查看ffprobe的xml输出并将string(.//format/@duration)替换为所需元素的xpath。

XML=`ffprobe -v error -hide_banner -show_format -show_streams -print_format xml "$FILEPATH"`
DATA=`echo "$XML" | xmllint --xpath "string(.//format/@duration)" -`