ffprobe how to retrieve both audio and video info

2019-08-20 05:57发布

I can use the following to retrieve the audio and video codec and the video frame height:

ffprobe -v quiet -show_entries stream=index,codec_name,height -of csv input.mp4

But the output is on two lines and includes text that I don't need like so:

stream,0,h264,720
stream,1,mp3

The only output I want is to be in the form of:

mp3,h264,720

I've tried using -show_entries twice in the same command line, but it ignores the first call every time. I've also tried using

ffprobe -v quiet -select_streams v -show_entries stream=codec_name,height, -select_streams a -show_entries stream=codec_name

but that doesn't do anything.

How can I get the simplified output as specified above?

2条回答
聊天终结者
2楼-- · 2019-08-20 06:33

After our conversation in the comments, I think something like this is what you're looking for. It's a Batch + JScript hybrid script. I'm using JScript to parse and objectify the JSON output by ffprobe. Salt to taste, and remove echo from line 31 when you're ready for the script to act.

@if (@CodeSection == @Batch) @then
@echo off & setlocal & goto run

:usage
echo Usage: %~nx0 infile outfile
echo This script re-encodes videos to x265 + AAC encoding.
exit /b

:run
if "%~2"=="" goto usage
if not exist "%~1" goto usage

set ffprobe=ffprobe -v quiet -show_entries "stream=codec_name,height" -of json "%~1"

for /f "delims=" %%I in ('%ffprobe% ^| cscript /nologo /e:JScript "%~f0"') do set "%%~I"

if %height% lss 720 (
    echo Video is ^< 720p.  Not worth it.
    exit /b
)

set "pre=-hide_banner -fflags +genpts+discardcorrupt+fastseek -analyzeduration 100M"
set "pre=%pre% -probesize 50M -hwaccel dxva2 -y -threads 3 -v error -stats"
set "global="
set "video=-c:v libx265 -crf 22 -preset fast"
set "audio=-c:a libfdk_aac -flags +qscale -global_quality 4 -afterburner 1"

if defined hevc if defined aac (
    echo Already in x265 + AAC format.
    exit /b
)

if defined aac (
    echo Already has AAC audio.  Re-encoding video only.
    set "audio=-c:a copy"
) else if defined hevc (
    echo Already has x265 video.  Re-encoding audio only.
    set "video=-c:v copy"
)

echo ffmpeg %pre% -i "%~1" %global% %video% %audio% "%~2"

goto :EOF
@end // end Batch / begin JScript

var stdin = WSH.CreateObject('Scripting.FileSystemObject').GetStandardStream(0),
    htmlfile = WSH.CreateObject('htmlfile'),
    JSON;

htmlfile.write('<meta http-equiv="x-ua-compatible" content="IE=9" />');
htmlfile.close(JSON = htmlfile.parentWindow.JSON);

var obj = JSON.parse(stdin.ReadAll());

for (var i = obj.streams.length; i--;) {
    if (obj.streams[i].height) WSH.Echo('height=' + obj.streams[i].height);
    if (/hevc/i.test(obj.streams[i].codec_name)) WSH.Echo('hevc=true');
    if (/aac/i.test(obj.streams[i].codec_name)) WSH.Echo('aac=true');
}
查看更多
The star\"
3楼-- · 2019-08-20 06:55
set "codec=" & set "sound="
for /f "tokens=*" %%i in ('ffprobe ... ') do (
  for /f "tokens=3,4 delims=," %%a in (%%i) do (
   if not defined codec (
      set "codec=%%a"
      set "hres=%%b"
    ) else (
      if not defined sound set "sound=%%a"
    )
  )
)
echo %sound%,%codec%,%hres%

if there are blank lines before ffprobe output, you should add the skip=n keyword to for loop.

查看更多
登录 后发表回答