Jump to content

ShellExecuteWait won't run a valid command line


Recommended Posts

This is driving me bananas. I'm trying to normalize audio in a bunch of mp4 files. Yes, I've seen the Python program ffmpeg-normalize and failed to get it to work, and MP4Gain costs money.

#include <FileConstants.au3>
#include <File.au3>

Global $FileList[2]
$FileList[0]=1
$FileList[1]="Test.mp4"
$Folder="D:\Temporary"
$PathName="C:\Program Files\FFMpeg\ffmpeg.exe"
If FileExists($Folder & "\Log.txt") Then
  FileDelete($Folder & "\Log.txt")
Endif

For $i = 1 To $FileList[0]
  $Switches = '-i "' & $Folder & "\" & $FileList[$i] & '" -af "volumedetect" -vn -sn -dn -f null null >>"' & $Folder & '\Log.txt" 2>&1'
  $LogHandle = FileOpen($Folder & "\Log.txt", $FO_APPEND)
  FileWrite($LogHandle, "============ Processing " & $FileList[$i] & "============" & @CRLF)
  FileWrite($LogHandle, 'FFMPeg command line "' & $PathName & '" ' & $Switches & @CRLF)
  FileClose($LogHandle)
  $Switches = '-i "' & $Folder & "\" & $FileList[$i] & '" -af "volumedetect" -vn -sn -dn -f null null >>"' & $Folder & '\Log.txt" 2>&1'
  $ReturnValue = ShellExecuteWait('"' & $PathName & '"',$Switches,$Folder,$SHEX_OPEN,@SW_HIDE)
  If $ReturnValue <> 0 Then
    MsgBox($MB_ICONERROR, "Error", "FFMpeg error, return code " & $ReturnValue & @CRLF & "See " & $Folder & '\Log.txt')
  EndIf
Next

which produces:

Error.png.8c320b5e56bb1e5664a3bee5e2bfb4cd.png

and Log.txt:

============ Processing Test.mp4============
FFMPeg command line "C:\Program Files\FFMpeg\ffmpeg.exe" -i "D:\Temporary\Test.mp4" -af "volumedetect" -vn -sn -dn -f null null >>"D:\Temporary\Log.txt" 2>&1

However, if I paste "C:\Program Files\FFMpeg\ffmpeg.exe" -i "D:\Temporary\Test.mp4" -af "volumedetect" -vn -sn -dn -f null null >>"D:\Temporary\Log.txt" 2>&1 into cmd.exe, Log.txt contains:

ffmpeg version N-115551-g4037d5e103-20240603 Copyright (c) 2000-2024 the FFmpeg developers
  built with gcc 13.2.0 (crosstool-NG 1.26.0.65_ecc5e41)
  configuration: --prefix=/ffbuild/prefix --pkg-config-flags=--static --pkg-config=pkg-config --cross-prefix=x86_64-w64-mingw32- --arch=x86_64 --target-os=mingw32 --enable-gpl --enable-version3 --disable-debug --disable-w32threads --enable-pthreads --enable-iconv --enable-libxml2 --enable-zlib --enable-libfreetype --enable-libfribidi --enable-gmp --enable-fontconfig --enable-libharfbuzz --enable-libvorbis --enable-opencl --disable-libpulse --enable-libvmaf --disable-libxcb --disable-xlib --enable-amf --enable-libaom --enable-libaribb24 --enable-avisynth --enable-chromaprint --enable-libdav1d --enable-libdavs2 --enable-libdvdread --enable-libdvdnav --disable-libfdk-aac --enable-ffnvcodec --enable-cuda-llvm --enable-frei0r --enable-libgme --enable-libkvazaar --enable-libaribcaption --enable-libass --enable-libbluray --enable-libjxl --enable-libmp3lame --enable-libopus --enable-librist --enable-libssh --enable-libtheora --enable-libvpx --enable-libwebp --enable-lv2 --enable-libvpl --enable-openal --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenh264 --enable-libopenjpeg --enable-libopenmpt --enable-librav1e --enable-librubberband --enable-schannel --enable-sdl2 --enable-libsoxr --enable-libsrt --enable-libsvtav1 --enable-libtwolame --enable-libuavs3d --disable-libdrm --enable-vaapi --enable-libvidstab --enable-vulkan --enable-libshaderc --enable-libplacebo --enable-libx264 --enable-libx265 --enable-libxavs2 --enable-libxvid --enable-libzimg --enable-libzvbi --extra-cflags=-DLIBTWOLAME_STATIC --extra-cxxflags= --extra-libs=-lgomp --extra-ldflags=-pthread --extra-ldexeflags= --cc=x86_64-w64-mingw32-gcc --cxx=x86_64-w64-mingw32-g++ --ar=x86_64-w64-mingw32-gcc-ar --ranlib=x86_64-w64-mingw32-gcc-ranlib --nm=x86_64-w64-mingw32-gcc-nm --extra-version=20240603
  libavutil      59. 21.100 / 59. 21.100
  libavcodec     61.  6.100 / 61.  6.100
  libavformat    61.  3.104 / 61.  3.104
  libavdevice    61.  2.100 / 61.  2.100
  libavfilter    10.  2.102 / 10.  2.102
  libswscale      8.  2.100 /  8.  2.100
  libswresample   5.  2.100 /  5.  2.100
  libpostproc    58.  2.100 / 58.  2.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'D:\Temporary\Test.mp4':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    title           : Test
    artist          : VideoProc Converter
    encoder         : Lavf57.73.100
    comment         : Test
    genre           : DVD
  Duration: 00:51:44.80, start: 0.000000, bitrate: 1737 kb/s
  Stream #0:0[0x1](und): Video: h264 (High) (avc1 / 0x31637661), yuv420p(progressive), 960x720 [SAR 1:1 DAR 4:3], 1600 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (default)
      Metadata:
        handler_name    : VideoHandler
        vendor_id       : [0][0][0][0]
  Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 44100 Hz, stereo, fltp, 128 kb/s (default)
      Metadata:
        handler_name    : SoundHandler
        vendor_id       : [0][0][0][0]
[Parsed_volumedetect_0 @ 000001965943e880] n_samples: 0
Stream mapping:
  Stream #0:1 -> #0:0 (aac (native) -> pcm_s16le (native))
Press [q] to stop, [?] for help
Output #0, null, to 'null':
  Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    title           : Test
    artist          : VideoProc Converter
    genre           : DVD
    comment         : Test
    encoder         : Lavf61.3.104
  Stream #0:0(eng): Audio: pcm_s16le, 44100 Hz, stereo, s16, 1411 kb/s (default)
      Metadata:
        handler_name    : SoundHandler
        vendor_id       : [0][0][0][0]
        encoder         : Lavc61.6.100 pcm_s16le
size=N/A time=00:19:19.48 bitrate=N/A speed=2.26e+03x    
size=N/A time=00:38:43.01 bitrate=N/A speed=2.26e+03x    
[Parsed_volumedetect_0 @ 000001965731ddc0] n_samples: 273838080
[Parsed_volumedetect_0 @ 000001965731ddc0] mean_volume: -29.0 dB
[Parsed_volumedetect_0 @ 000001965731ddc0] max_volume: -8.1 dB
[Parsed_volumedetect_0 @ 000001965731ddc0] histogram_8db: 39
[Parsed_volumedetect_0 @ 000001965731ddc0] histogram_9db: 476
[Parsed_volumedetect_0 @ 000001965731ddc0] histogram_10db: 2231
[Parsed_volumedetect_0 @ 000001965731ddc0] histogram_11db: 9378
[Parsed_volumedetect_0 @ 000001965731ddc0] histogram_12db: 30128
[Parsed_volumedetect_0 @ 000001965731ddc0] histogram_13db: 80105
[Parsed_volumedetect_0 @ 000001965731ddc0] histogram_14db: 191666
[out#0/null @ 00000196572b4140] video:0KiB audio:534840KiB subtitle:0KiB other streams:0KiB global headers:0KiB muxing overhead: unknown
size=N/A time=00:51:44.74 bitrate=N/A speed=2.28e+03x

Why won't ShellExecuteWait do that?

Edited by JonF
Link to comment
Share on other sites

  • Developers

Did you try to see if that makes a difference as you seem to be running an x64 program?

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

  • JonF changed the title to ShellExecuteWait won't run a valid command line
  • Developers
Posted (edited)

 

Change to code and use @comspec /c to run the complete commandline as you are using output piping, which I doubt is working in ShellExecute()

Edited by Jos

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

I think the problem is with redirecting the output >> to the log.file. Shellexecute and Run both seem to handle only a single command, and can't handle this kind of chaining.

 

#include <AutoItConstants.au3>

Local $sCmd = '"' & @ScriptDir & '\ffmpeg\ffmpeg.exe" -i "' & @ScriptDir & '\_5_test_CW_90.mp4" -af "volumedetect" -vn -sn -dn -f null null'
ConsoleWrite($sCmd & @CRLF)
Local $iPid = Run($sCmd, @ScriptDir, @SW_SHOW, $STDERR_MERGED)
ProcessWaitClose($iPid)
Local $sOutput = StdoutRead($iPid)
MsgBox(0, "", $sOutput)
FileWrite(@ScriptDir & '\log.txt', $sOutput)

 

Edit: Of course it's easy to redirect the stdout to a log-file in this example by adding

Edited by KaFu
Link to comment
Share on other sites

17 hours ago, KaFu said:

handle only a single command

You can run more than one command using Ampersand "&"

Run(@ComSpec & " /c Calc & Notepad", "", @SW_HIDE)

Using double "&&" the second command only executes if the first was successful.

Edited by Werty

Some guy's script + some other guy's script = my script!

Link to comment
Share on other sites

  • Developers
6 hours ago, Werty said:

You can run more than one command using Ampersand "&"

yes, but that example has a error, missing a space after /c! ;) 

SciTE4AutoIt3 Full installer Download page   - Beta files       Read before posting     How to post scriptsource   Forum etiquette  Forum Rules 
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Link to comment
Share on other sites

Lol, runs fine for some reason though, I added the space anyway. :D

/edit, and shortened it, no reason for that extra quotation mark/apostrophe.

Edited by Werty

Some guy's script + some other guy's script = my script!

Link to comment
Share on other sites

  • 2 weeks later...

I was busy with other things for a while. After fighting with number, type, and location of quote marks to account for filenames with spaces and redirected output I acknowledged defeat. I did find a solution, unfortunately not general for any program; I found FFMPeg's switch to save a report.

 

#include <FileConstants.au3>
#include <File.au3>
#include <MsgBoxConstants.au3>

Global $FileList[2]
$FileList[0]=1
$FileList[1]="Test.mp4"
$Folder="D:\Temporary"
$PathName="C:\Program Files\FFMpeg\ffmpeg.exe"
If FileExists($Folder & "\Log.txt") Then
  FileDelete($Folder & "\Log.txt")
Endif

For $i = 1 To $FileList[0]
  $Switches = ' -i "' & $Folder & "\" & $FileList[$i] & '" -filter:a volumedetect -vn -sn -dn -f null null'
  $LogHandle = FileOpen($Folder & "\Log.txt", $FO_APPEND)
  FileWrite($LogHandle, "============ Processing " & $FileList[$i] & "============" & @CRLF)
  If FileExists($Folder & "\Run_FFMPeg.bat") Then FileDelete($Folder & "\Run_FFMPeg.bat")
  FileWrite($Folder & "\Run_FFMPeg.bat",'set FFREPORT=file=ffreport.log:level=32' & @CRLF & '"' & $PathName & '"' & $Switches)
  $ReturnValue = RunWait($Folder & "\Run_FFMPeg.bat",$Folder,$SHEX_OPEN,@SW_HIDE)
  If $ReturnValue <> 0 Then
    MsgBox($MB_ICONERROR, "Error", "FFMpeg error, return code " & $ReturnValue & @CRLF & "See " & $Folder & '\Log.txt')
  EndIf
  ; Transfer the results to the main log
  $TemporaryLogHandle = Fileopen($Folder & "\ffreport.log",$FO_READ)
  $TemporaryLog = FileRead($TemporaryLogHandle)
  FileWrite($LogHandle, $TemporaryLog)
  FileClose($TemporaryLogHandle)
  FileClose($LogHandle)
Next

 

Link to comment
Share on other sites

I did.

It didn't cover stderr.

Quote

Edit: Of course it's easy to redirect the stdout to a log-file in this example by adding

didn't help much.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...