Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   [решено] Поместить вывод команды в переменную (http://forum.oszone.net/showthread.php?t=345531)

ateka 14-06-2020 15:24 2925046

Поместить вывод команды в переменную
 
Здравствуйте. Я пытаюсь настроить тригер на громкость аудио файла.
Команда выглядит так:
Код:

ffmpeg -i "%~1" -af "volumedetect" -f null nul
Вывод выглядит так:

Нужное число это mean_volume: -15.5 dB
Подскажите пожалуйста как в переменную _var поместить значение mean_volume.
Очень желательно до точки. То есть не 15.5 а 15
Спасибо.

megaloman 14-06-2020 15:50 2925055

ateka, Выполните команду в виде:
Код:

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

ateka 14-06-2020 16:18 2925059

Вложений: 1
Код:

ffmpeg -i "test.mp4" -af "volumedetect" -f null nul 2>temp.txt
output
Код:

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 2925061

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 2925068

Супер! Спасибо большое! Как часы!
драфт
Код:

::@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 2925106

Код:

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

ateka 15-06-2020 18:16 2925171

Цитата:

Цитата alpap
/s/^.*[:]\s[-]\?//;T;s/[.].*$//p »

Круто, спасибо!

DJ Mogarych 16-06-2020 10:41 2925239

А в Пауэршелле как запихнуть вывод ффмпега в переменную? Но только чтобы без промежуточных текстовых файлов.

Busla 16-06-2020 11:12 2925245

Цитата:

Цитата DJ Mogarych
в Пауэршелле как запихнуть вывод ффмпега в переменную? »

Код:

$result = & ffmpeg.exe

Foreigner 16-06-2020 11:17 2925246

Цитата:

Цитата DJ Mogarych
А в Пауэршелле как запихнуть вывод ффмпега в переменную? »

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

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

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

DJ Mogarych 16-06-2020 14:40 2925263

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

Foreigner 16-06-2020 16:43 2925276

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 2925282

Цитата:

Цитата DJ Mogarych
Busla, ну уж до этого я и сам мог догадаться - так не работает. »

у меня почему-то работает
и на Win10 и на Win2012R2 (не конкретно с ffmpeg, а с консольными exe)

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

Iska 16-06-2020 22:19 2925290

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

Sham 17-06-2020 06:41 2925309

Код:

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 2925322

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

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

Iska 17-06-2020 21:01 2925362

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 здесь?

Цитата:

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

С чем это связано?

Foreigner 17-06-2020 21:53 2925374

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


Время: 20:38.

Время: 20:38.
© OSzone.net 2001-