PDA

Показать полную графическую версию : [решено] Поместить вывод команды в переменную


ateka
14-06-2020, 15:24
Здравствуйте. Я пытаюсь настроить тригер на громкость аудио файла.
Команда выглядит так:
ffmpeg -i "%~1" -af "volumedetect" -f null nul
https://i.imgur.com/yO0iOHl.png
Нужное число это mean_volume: -15.5 dB
Подскажите пожалуйста как в переменную _var поместить значение mean_volume.
Очень желательно до точки. То есть не 15.5 а 15
Спасибо.

megaloman
14-06-2020, 15:50
ateka, Выполните команду в виде:ffmpeg -i "%~1" -af "volumedetect" -f null nul >c:\zzzzzzzzzzzzzz.txt и приложите получившийся файл к сообщению - надо на чем-то проверить решение.

ateka
14-06-2020, 16:18
ffmpeg -i "test.mp4" -af "volumedetect" -f null nul 2>temp.txt

ffmpeg version git-2020-05-13-b12b053 Copyright (c) 2000-2020 the FFmpeg developers
built with gcc 9.3.1 (GCC) 20200513
configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libdav1d --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libsrt --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --disable-w32threads --enable-libmfx --enable-ffnvcodec --enable-cuda-llvm --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth --enable-libopenmpt --enable-amf
libavutil 56. 45.100 / 56. 45.100
libavcodec 58. 84.100 / 58. 84.100
libavformat 58. 43.100 / 58. 43.100
libavdevice 58. 9.103 / 58. 9.103
libavfilter 7. 80.100 / 7. 80.100
libswscale 5. 6.101 / 5. 6.101
libswresample 3. 6.100 / 3. 6.100
libpostproc 55. 6.100 / 55. 6.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'test.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
title : Maybe.mp4
encoder : Lavf58.43.100
Duration: 00:00:18.30, start: 0.000000, bitrate: 929 kb/s
Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p(tv, bt709), 640x350 [SAR 1:1 DAR 64:35], 791 kb/s, 30 fps, 30 tbr, 15360 tbn, 60 tbc (default)
Metadata:
handler_name : VideoHandler
Stream #0:1(und): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 128 kb/s (default)
Metadata:
handler_name : SoundHandler
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> wrapped_avframe (native))
Stream #0:1 -> #0:1 (aac (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, null, to 'nul':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.43.100
Stream #0:0(und): Video: wrapped_avframe, yuv420p, 640x350 [SAR 1:1 DAR 64:35], q=2-31, 200 kb/s, 30 fps, 30 tbn, 30 tbc (default)
Metadata:
handler_name : VideoHandler
encoder : Lavc58.84.100 wrapped_avframe
Stream #0:1(und): Audio: pcm_s16le, 48000 Hz, stereo, s16, 1536 kb/s (default)
Metadata:
handler_name : SoundHandler
encoder : Lavc58.84.100 pcm_s16le
frame= 549 fps=0.0 q=-0.0 Lsize=N/A time=00:00:18.30 bitrate=N/A speed=57.3x
video:287kB audio:3436kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: unknown
[Parsed_volumedetect_0 @ 000002a929142a80] n_samples: 1759232
[Parsed_volumedetect_0 @ 000002a929142a80] mean_volume: -47.3 dB
[Parsed_volumedetect_0 @ 000002a929142a80] max_volume: -15.9 dB
[Parsed_volumedetect_0 @ 000002a929142a80] histogram_15db: 10
[Parsed_volumedetect_0 @ 000002a929142a80] histogram_16db: 18
[Parsed_volumedetect_0 @ 000002a929142a80] histogram_17db: 14
[Parsed_volumedetect_0 @ 000002a929142a80] histogram_18db: 22
[Parsed_volumedetect_0 @ 000002a929142a80] histogram_19db: 32
[Parsed_volumedetect_0 @ 000002a929142a80] histogram_20db: 70
[Parsed_volumedetect_0 @ 000002a929142a80] histogram_21db: 114
[Parsed_volumedetect_0 @ 000002a929142a80] histogram_22db: 138
[Parsed_volumedetect_0 @ 000002a929142a80] histogram_23db: 298
[Parsed_volumedetect_0 @ 000002a929142a80] histogram_24db: 286
[Parsed_volumedetect_0 @ 000002a929142a80] histogram_25db: 382
[Parsed_volumedetect_0 @ 000002a929142a80] histogram_26db: 538

megaloman
14-06-2020, 16:37
ateka, Полноценно отладить не могу, нет ffmpeg, пробуйте:@Echo Off
cls

Set "Var= mean_volume: "
Set "FileIn=test.mp4"

FOR /F "usebackq tokens=1* delims=:" %%i IN (`ffmpeg -i "%FileIn%" -af "volumedetect" -f null nul ^|FINDSTR /I "%Var%"`) DO Set "Var=%%j"
FOR /F "tokens=1* delims=. " %%i IN ("%Var%") DO Set "Var=%%i"

Echo "%Var%"
Pause
Exit /B

ateka
14-06-2020, 17:35
Супер! Спасибо большое! Как часы!
::@Echo Off
cls

Set "Var= mean_volume: "
Set "FileIn=test.mp4"

FOR /F "usebackq tokens=2* delims=:" %%i IN (`ffmpeg -i "%FileIn%" -af "volumedetect" -f null nul 2^>^&1^|FINDSTR /I "%Var%"`) DO Set "Var=%%i"
FOR /F "tokens=1* delims=.- " %%i IN ("%Var%") DO Set "Var=%%i"

Echo ___ "%Var%" ___
Pause
Exit /B

alpap
14-06-2020, 23:43
ffmpeg -i "%~1" -af "volumedetect" -f null nul|sed -n "/mean_volume:/s/^.*[:]\s[-]\?//;T;s/[.].*$//p"

sed (http://gnuwin32.sourceforge.net/packages/sed.htm)

ateka
15-06-2020, 18:16
/s/^.*[:]\s[-]\?//;T;s/[.].*$//p »
Круто, спасибо!

DJ Mogarych
16-06-2020, 10:41
А в Пауэршелле как запихнуть вывод ффмпега в переменную? Но только чтобы без промежуточных текстовых файлов.

Busla
16-06-2020, 11:12
в Пауэршелле как запихнуть вывод ффмпега в переменную? »
$result = & ffmpeg.exe

Foreigner
16-06-2020, 11:17
А в Пауэршелле как запихнуть вывод ффмпега в переменную? »

Перенаправить stderr в stdout и удалить сообщение об ошибке:

$a = ffmpeg -i "file.flac" -af "volumedetect" -f null nul 2>&1
$a.Exception


Это в лоб, первое что приходит на ум.

DJ Mogarych
16-06-2020, 14:40
Busla, ну уж до этого я и сам мог догадаться - так не работает.
Foreigner, да, работает. Но нельзя ли без перенаправления, и почему stderr, если после выполнения команды в переменной $error ничего нет? Хочется какого-то более "родного" решения для PS, менее костыльного.

Foreigner
16-06-2020, 16:43
DJ Mogarych, Оно еще и по разному выводит -- в Windows PowerShell вообще бедово, а в Core, только попробовал, нормально:

[string[]] $a = ffmpeg -i ".\20 - Contact Lost.flac" -af "volumedetect" -f null nul 2>&1

Busla
16-06-2020, 19:19
Busla, ну уж до этого я и сам мог догадаться - так не работает. »
у меня почему-то работает
и на Win10 и на Win2012R2 (не конкретно с ffmpeg, а с консольными exe)

но вообще - это "магия", оно пытается интерпретировать строку как команду PoSh, зависит от конкретных атрибутов в том числе

Iska
16-06-2020, 22:19
Почему не пользовать стандартные методы запуска файла на исполнение, ожидание завершения и чтение потоков stdout и stderr? Только не спрашивайте как, я помнить — не помню, а сил сегодня ковыряться в документации .Net нет.

Sham
17-06-2020, 06:41
invoke-expression 'ffmpeg -i ".\20 - Contact Lost.flac" -af "volumedetect" -f null nul' -errorvariable stderr 2>$null
if ([string]$stderr -match 'mean_volume: -?(\d+)') { $matches[1] } перенаправление выводов вряд-ли "костыль"

Busla
17-06-2020, 11:55
Iska, стандартный "метод" - Start-Process, а ваша привычка на каждый чих ковыряться в .Net - это как раз нестандартный метод

К сожалению, туда встроена своя "магия", которая не всегда корректно отрабатывает.
Из широко известных примеров - 7zip при запуске через Start-Process (или прямое обращение к System.Diagnostics.Process) изредка падает.

Iska
17-06-2020, 21:01
Busla, пусть будет Start-Process, если оно позволяет сделать искомое. А оно позволяет? В случае .Net я вижу простое:
Examples

The following example uses the net use command together with a user-supplied argument to map a network resource. It then reads the standard error stream of the net command and writes it to console.using (Process myProcess = new Process())
{
ProcessStartInfo myProcessStartInfo = new ProcessStartInfo("net ", "use " + args[0]);

myProcessStartInfo.UseShellExecute = false;
myProcessStartInfo.RedirectStandardError = true;
myProcess.StartInfo = myProcessStartInfo;
myProcess.Start();

StreamReader myStreamReader = myProcess.StandardError;
// Read the standard error of net.exe and write it on to console.
Console.WriteLine(myStreamReader.ReadLine());
}
А как у нас обстоят дела со Start-Process здесь?

Из широко известных примеров - 7zip при запуске через Start-Process (или прямое обращение к System.Diagnostics.Process) изредка падает. »
С чем это связано?

Foreigner
17-06-2020, 21:53
Я так понимаю, что если ffmpeg так разработан, что он все отдает через stderr, то ничего не попишешь. Пробовал и под виндоус и под линукс. Единственное, что могу сказать, pwsh гораздо лучше обработал вывод и на ходу сменил тип на стринг-массив без потери форматирования, powershell сделало тоже самое, но криво -- текст поплыл, добавились переносы. В интернете так же много информации по этому поводу. Ну вот так они сделали. Им наверное видней.




© OSzone.net 2001-2012