ffprobe как получить аудио и видео информацию и вывести ее в одну строку?

Я могу использовать следующее для получения аудио и видео кодека и высоты видеокадра:

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

Но вывод состоит из двух строк и включает в себя текст, который мне не нужен, вот так:

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

Единственный вывод, который я хочу, должен быть в форме:

mp3,h264,720

Я попытался использовать -show_entries дважды в одной командной строке, но он игнорирует первый вызов каждый раз. Я также пытался использовать

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

но это ничего не делает.

Как я могу получить упрощенный вывод, как указано выше?

2 ответа

После нашего разговора в комментариях, я думаю, что-то вроде этого - то, что вы ищете. Это гибридный скрипт Batch + JScript. Я использую JScript для анализа и объективации вывода JSON ffprobe, Посолить по вкусу и удалить echo из строки 31, когда вы будете готовы к действию сценария.

@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');
}
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%

если есть пустые строки перед ffprobe вывод, вы должны добавить skip=n ключевое слово для for петля.

Другие вопросы по тегам