From 002913a406f6beb4fd834c38851616d18f1c0610 Mon Sep 17 00:00:00 2001 From: Conrad Zelck <git@simpel.cc> Date: Sat, 28 Mar 2020 15:33:52 +0100 Subject: [PATCH] Complete rewrite Working with ffmpeg instead sox Signed-off-by: Conrad Zelck <git@simpel.cc> --- pro_audio.au3 | 293 +++++++++++++++++++++++--------------------------- 1 file changed, 136 insertions(+), 157 deletions(-) diff --git a/pro_audio.au3 b/pro_audio.au3 index 7f92416..c24ecfb 100644 --- a/pro_audio.au3 +++ b/pro_audio.au3 @@ -1,36 +1,35 @@ #Region ;**** Directives created by AutoIt3Wrapper_GUI **** -#AutoIt3Wrapper_Icon=Icons\wav.ico -#AutoIt3Wrapper_Res_Comment=Converts Audio-Files to 48kHz 24bit. -#AutoIt3Wrapper_Res_Description=Converts Audio-Files to 48kHz 24bit. -#AutoIt3Wrapper_Res_Fileversion=1.0.0.12 +#AutoIt3Wrapper_Icon=Icons\peakmeter.ico +#AutoIt3Wrapper_Res_Comment=Converting to wav with 48kHz 24bit. +#AutoIt3Wrapper_Res_Description=Converting to wav with 48kHz 24bit. +#AutoIt3Wrapper_Res_Fileversion=1.1.0.14 #AutoIt3Wrapper_Res_Fileversion_AutoIncrement=y +#AutoIt3Wrapper_Res_CompanyName=Norddeutscher Rundfunk #AutoIt3Wrapper_Res_LegalCopyright=Conrad Zelck +#AutoIt3Wrapper_Res_SaveSource=y #AutoIt3Wrapper_Res_Language=1031 +#AutoIt3Wrapper_Res_Field=Copyright|Conrad Zelck +#AutoIt3Wrapper_Res_Field=Compile Date|%date% %time% +#AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 -w- 7 +#AutoIt3Wrapper_Run_Au3Stripper=y +#Au3Stripper_Parameters=/mo #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** #include <AutoItConstants.au3> +#include <ButtonConstants.au3> +#include <Date.au3> +#include <FileConstants.au3> +#include <GUIConstantsEx.au3> +#include <MsgBoxConstants.au3> +#include <StaticConstants.au3> #include <File.au3> #include <Array.au3> -#include <TrayCox.au3> -Opt("GuiCoordMode", 0) ;relative position to the start of the last control with "-1" +#include <Sound.au3> +#include <TrayCox.au3> ; source: https://github.com/SimpelMe/TrayCox - not needed for functionality -Global $bGUI = 1 ; GUI soll angezeigt werden -Global $hEnableGUI = TrayCreateItem("Verstecken", -1, 0) -TrayItemSetOnEvent (-1, "_Hide") -TrayCreateItem("", -1, 1) - -Local $hGUI -Local $sCurTrack, $sCurTrackMinusExt, $sCurTrackNewExt, $sCurTrackName -Local $sOutput, $sOutError, $iPID ; Auslesen STDOUT + STDERR -Local $aOutput, $aBitRate, $iBitRate, $iFaktorFileSize -Local $iOldSize, $iShouldSize, $iTempSize, $iProzent, $iProzentTemp = 0 -Local $aProzent - -FileInstall("H:\_Conrad lokal\Downloads\AutoIt3\_COX\sox\zlib1.dll", @TempDir & "\", 1) -FileInstall("H:\_Conrad lokal\Downloads\AutoIt3\_COX\sox\pthreadgc2.dll", @TempDir & "\", 1) -FileInstall("H:\_Conrad lokal\Downloads\AutoIt3\_COX\sox\libgomp-1.dll", @TempDir & "\", 1) -FileInstall("H:\_Conrad lokal\Downloads\AutoIt3\_COX\sox\libmp3lame.dll", @TempDir & "\", 1) -FileInstall("H:\_Conrad lokal\Downloads\AutoIt3\_COX\sox\libmad.dll", @TempDir & "\", 1) -FileInstall("H:\_Conrad lokal\Downloads\AutoIt3\_COX\sox\sox.exe", @TempDir & "\", 1) +Opt("GUICloseOnESC", 0) +FileInstall('K:\ffmpeg\bin\ffmpeg.exe', @TempDir & "\ffmpeg.exe", $FC_OVERWRITE) +Local $sPathFFmpeg = @TempDir & "\" +Global $g_sStdErrAll Local $aCmdLineCopy = $CmdLine Local $sAttrib @@ -47,6 +46,7 @@ EndIf Local $aOneFolderFileList Local $aFileList[0] Local $sChoosenMedia +Local $hGUI If $aCmdLineCopy[0] > 0 Then ; if already Files exist For $i = 1 to $aCmdLineCopy[0] $sAttrib = FileGetAttrib($aCmdLineCopy[$i]) @@ -60,31 +60,30 @@ If $aCmdLineCopy[0] > 0 Then ; if already Files exist Next _ArrayInsert($aFileList, 0, UBound($aFileList)) Else ; no file in $CmdLine - $hGUI = GUICreate(StringTrimRight(@ScriptName, 4) & " - Auswahl",258,63) + $hGUI = GUICreate(StringTrimRight(@ScriptName, 4) & " - Auswahl", 290, 70) GUISetFont(10) - GUICtrlCreateButton ("Ordner auswählen",10,20,-1,-1,$BS_DEFPUSHBUTTON) - GUICtrlCreateButton ("Dateien auswählen",121,-1) + Local $idButtonFiles = GUICtrlCreateButton("Dateien auswählen", 10, 20, 130, 30, $BS_DEFPUSHBUTTON) + Local $idButtonFolder = GUICtrlCreateButton("Ordner auswählen", 150, 20, 130, 30) GUISetState() Local $msg While 1 $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Then _Beenden() ; defined at TrayCox.au3 - If $msg = 3 Then ExitLoop - If $msg = 4 Then ExitLoop + If $msg = $idButtonFolder Or $msg = $idButtonFiles Then ExitLoop WEnd GUIDelete() Switch $msg - Case 3 ; choose folder + Case $idButtonFolder $sChoosenMedia = FileSelectFolder (StringTrimRight(@ScriptName, 4) & " - Ordner aussuchen", "") If @error Then - MsgBox(262144,StringTrimRight(@ScriptName, 4) & " - Abbruch","Keine Datei(en) ausgewählt") + MsgBox($MB_TOPMOST,StringTrimRight(@ScriptName, 4) & " - Abbruch","Keine Datei(en) ausgewählt") Exit EndIf $aFileList = _FileListToArrayRec($sChoosenMedia, "*.*", $FLTAR_FILES + $FLTAR_NOSYSTEM + $FLTAR_NOLINK, $FLTAR_RECUR, $FLTAR_SORT, $FLTAR_FULLPATH) - Case 4 ; choose files + Case $idButtonFiles $sChoosenMedia = FileOpenDialog(StringTrimRight(@ScriptName, 4),"", "Alle (*.*)","4") If @error Then - MsgBox(262144,StringTrimRight(@ScriptName, 4) & " - Abbruch","Keine Datei(en) ausgewählt") + MsgBox($MB_TOPMOST,StringTrimRight(@ScriptName, 4) & " - Abbruch","Keine Datei(en) ausgewählt") Exit EndIf $aFileList = StringSplit($sChoosenMedia, "|") @@ -99,153 +98,133 @@ Else ; no file in $CmdLine EndIf If $aFileList[0] <= 0 Then - MsgBox($MB_SYSTEMMODAL + $MB_ICONWARNING, @ScriptName, "Es ist keine zu wandelnde Datei zu finden.") + MsgBox($MB_TOPMOST, @ScriptName, "Es ist keine zu wandelnde Datei zu finden.") Exit EndIf -Opt("GuiOnEventMode", 1) -Local $iWidthLabel = 400 -$hGUI = GUICreate(StringTrimRight(@ScriptName, 4),$iWidthLabel + 40,150) ; 150 -GUISetFont(10) -GUISetOnEvent($GUI_EVENT_CLOSE, "_Beenden") -Local $hLabelCounter = GUICtrlCreateLabel("Dateien werden gewandelt: ", 20, 20, $iWidthLabel) -Local $hProgress = GUICtrlCreateProgress(-1, 25, $iWidthLabel) -Local $sLabelFile = GUICtrlCreateLabel(".", -1, 32, $iWidthLabel, 80) ; label has to have some text ; 80 -GUICtrlSetFont(-1,9) -GUISetState() - -Local $hTimerStart = TimerInit() - +$hGUI = GUICreate("Pro Audio", 600, 160) +Local $idLabelFileName = GUICtrlCreateLabel("", 10, 10, 580, 30, $SS_LEFTNOWORDWRAP) +GUICtrlSetFont(-1, 14, 400, 0, "Lucida Sans Typewriter") +Local $idLabelConvert = GUICtrlCreateLabel("Konvertiere Datei:", 10, 50, 580, 30) +GUICtrlSetFont(-1, 12, 400, 0, "Lucida Sans Typewriter") +Global $g_idProgress = GUICtrlCreateProgress(10, 80, 580, 20) +GUICtrlSetFont(-1, 14, 400, 0, "Lucida Sans Typewriter") +Local $g_hLabelRunningTime = GUICtrlCreateLabel("", 440, 120, 150, 30, $SS_RIGHT) +GUICtrlSetFont(-1, 14, 400, 0, "Lucida Sans Typewriter") +GUISetState(@SW_SHOW) + +Global $hTimerStart = TimerInit() + +Local $sCommand +Local $sCurTrack, $sCurTrackMinusExt, $sCurTrackNewExt +Local $iDelimiter For $i = 1 To $aFileList[0] $sCurTrack = $aFileList[$i] - ConsoleWrite("ShortName: " & $sCurTrack & @CRLF) - $sCurTrackMinusExt = StringTrimRight($sCurTrack, 4) + GUICtrlSetData($idLabelFileName, $i & "/" & $aFileList[0] & ": " & _FileName($sCurTrack)) + $iDelimiter = StringInStr($sCurTrack, ".", 0, -1) + $sCurTrackMinusExt = StringLeft($sCurTrack, $iDelimiter - 1) $sCurTrackNewExt = '_48kHz_24bit.wav' + $sCommand = '-i "' & $sCurTrack & '" -c:a pcm_s24le -ar 48000 -y ' & $sCurTrackMinusExt & $sCurTrackNewExt - $sOutput = "" ; für jede Runde löschen - $sOutError = "" ; für jede Runde löschen - $iPID = Run(@TempDir & "\sox.exe --i " & _quotePath($sCurTrack), "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) ; Metadaten auslesen - While ProcessExists($iPID) - $sOutput &= StdoutRead($iPID) - $sOutError &= StderrRead($iPID) - WEnd + _runFFmpeg('ffmpeg ' & $sCommand, $sPathFFmpeg) + GUICtrlSetData($g_idProgress, 100) ; if ffmpeg is done than set progress to 100 - sometimes last StderrRead with 100 is missed +Next +GUICtrlSetData($idLabelFileName, "Alle möglichen Dateien konvertiert.") +GUICtrlSetData($idLabelConvert, "") +WinActivate($hGUI,"") +_PlayReadySound() + +While 1 + Switch GUIGetMsg() + Case $GUI_EVENT_CLOSE + ExitLoop + EndSwitch +WEnd +Exit - If $sOutput = "" Then ; no Metadata - $sOutError = StringRegExpReplace($sOutError, ".*\\sox.exe", "") - MsgBox($MB_SYSTEMMODAL + $MB_ICONWARNING, @ScriptName, $sCurTrack & ":" & @CRLF & @CRLF & $sOutError) - Else - GUICtrlSetData($sLabelFile, _WordWrapTextForLabel($sCurTrack, 59)) - GUICtrlSetData($hLabelCounter, "Dateien werden gewandelt: " & $i & "/" & $aFileList[0]) - $aOutput = StringSplit($sOutput, @CRLF) - $aBitRate = StringRegExp($aOutput[15], "[\d.]{1,5}", 1) ; Bitrate steht im Metadaten-Array auf Platz 15 - $iBitRate = $aBitRate[0] - If StringInStr($iBitRate,".") Then ; Falls in z.B. 2.31M statt 192k angegeben - $iBitRate *= 1024 ; mbit to kbit +Func _runFFmpeg($command, $sWorkingDirectory) + Local $hPid = Run('"' & @ComSpec & '" /c ' & $command, $sWorkingDirectory, @SW_HIDE, $STDOUT_CHILD + $STDERR_CHILD) + Local $sStdErr, $sTimer + Local $iTicksDuration = 0, $iTicksTime = 0, $iTimer + While 1 + Sleep(500) + $sStdErr = StderrRead($hPid) + If @error Then ExitLoop + $g_sStdErrAll &= $sStdErr + If StringLen($sStdErr) > 0 Then + If Not $iTicksDuration Then $iTicksDuration = _GetDuration($sStdErr) + $iTicksTime = _GetTime($sStdErr) + If Not @error Then $sStdErr = "" + GUICtrlSetData($g_idProgress, $iTicksTime * 100 / $iTicksDuration) EndIf - ConsoleWrite("BitRate: " & $iBitRate & @CRLF) - $iFaktorFileSize = 2365.44 / $iBitRate ; 2365.44 = Bitrate für 24bit und 48kHz - ConsoleWrite("FaktorFileSize: " & $iFaktorFileSize & @CRLF) - - #cs Alternative für Fortschrittsbalken mit Auslesen StdErr von sox.exe - liest aber immer nur alle 6 Sekunden aus - $iPID = Run(@TempDir & "\sox.exe " & _quotePath($sCurTrack) & " -b 24 -r 48k " & _quotePath($sCurTrackMinusExt & $sCurTrackNewExt) & " -S", "", @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD) ; Metadaten auslesen - $hTimerStart = TimerInit() - While ProcessExists($iPID) - ;~ $sOutput &= StdoutRead($iPID) - $sOutError = StderrRead($iPID) - ;~ $sOutput = StderrRead($iPID) - If $sOutError <> "" Then - ;~ ConsoleWrite("New Block:" & @CRLF & $sOutError & @CRLF) - $aProzent = StringRegExp($sOutError, "(?i)In:([\d.]*)%", 3) - If Not @error Then - ;~ _ArrayDisplay($aProzent,"Zeile " & @ScriptLineNumber) - ;~ $sOutput = $aProzent[0] - $iProzent = $aProzent[UBound($aProzent) - 1] - ConsoleWrite($iProzent & @CRLF) - GUICtrlSetData($sLabelFile, $iProzent) - GUICtrlSetData($hProgress,$iProzent) - EndIf - ;~ GUICtrlSetData($sLabelFile, $sOutError) - EndIf - - If $sOutError <> "" Then ; no Metadata + $iTimer = TimerDiff($hTimerStart) + $sTimer = _Zeit($iTimer) + If GUICtrlRead($g_hLabelRunningTime) <> $sTimer Then + GUICtrlSetData($g_hLabelRunningTime, $sTimer) EndIf - ;~ Sleep(100) - WEnd - ConsoleWrite($sOutError & @CRLF) - ConsoleWrite(_Zeit(TimerDiff($hTimerStart), True) & @CRLF) -;~ ClipPut("OUT:" & @CRLF & $sOutput & @CRLF & @CRLF & "ERROR:" & @CRLF & $sOutError ) -;~ MsgBox($MB_SYSTEMMODAL + $MB_ICONWARNING, @ScriptName, $sOutError) - #ce - - $iPID = ShellExecute(@TempDir & "\sox.exe", _quotePath($sCurTrack) & " −b 24 -r 48k " & _quotePath($sCurTrackMinusExt & $sCurTrackNewExt),"","", @SW_HIDE) ; run converter - $iOldSize = FileGetSize($sCurTrack) - ConsoleWrite("OldSize: " & $iOldSize & @CRLF) - $iShouldSize = Round($iOldSize * $iFaktorFileSize) - ConsoleWrite("ShouldSize: " & $iShouldSize & @CRLF) - $sCurTrackName = StringTrimLeft($sCurTrack, StringInStr($sCurTrack, "\", 0, -1)) - While ProcessExists($iPID) - $iTempSize = FileGetSize($sCurTrackMinusExt & $sCurTrackNewExt) - $iProzent = Round(100 * $iTempSize / $iShouldSize) - If $iProzent <> $iProzentTemp Then - ConsoleWrite($iProzent & "% ") - $iProzentTemp = $iProzent - EndIf - GUICtrlSetData($hProgress,$iProzent) - WEnd - ConsoleWrite(@CRLF) ; neue Zeile - Sleep(100) - EndIf - ConsoleWrite(@CRLF) ; neue Zeile -Next -Exit + WEnd +EndFunc -Func _quotePath($sPath) ; versieht Pfade mit Anführungszeichen " - nötig für Run sowie die Parameter in ShellExecute - $sPath = '"' & $sPath & '"' - Return $sPath +Func _PlayReadySound() + Local $aSound = _SoundOpen(@WindowsDir & "\media\tada.wav") + _SoundPlay($aSound, 1) + _SoundClose($aSound) EndFunc -Func _Hide() ; Fenster verstecken oder anzeigen - If $bGUI = 1 Then - GUISetState(@SW_HIDE,$hGUI ) - TrayItemSetText($hEnableGUI, "Anzeigen") +Func _GetDuration($sStdErr) + If Not StringInStr($sStdErr, "Duration:") Then Return SetError(1, 0, 0) + Local $aRegExp = StringRegExp($sStdErr, "(?i)Duration.+?([0-9:]+)", 3) + If @error Or Not IsArray($aRegExp) Then Return SetError(2, 0, 0) + Local $sTime = $aRegExp[UBound($aRegExp) - 1] + Local $aTime = StringSplit($sTime, ":", 2) + If @error Or Not IsArray($aTime) Then Return SetError(3, 0, 0) + Return _TimeToTicks($aTime[0], $aTime[1], $aTime[2]) +EndFunc ;==>_GetDuration + +Func _GetTime($sStdErr) + If Not StringInStr($sStdErr, "time=") Then Return SetError(1, 0, 0) + Local $aRegExp = StringRegExp($sStdErr, "(?i)time.+?([0-9:]+)", 3) + If @error Or Not IsArray($aRegExp) Then Return SetError(2, 0, 0) + Local $sTime = $aRegExp[UBound($aRegExp) - 1] + Local $aTime = StringSplit($sTime, ":", 2) + If @error Or Not IsArray($aTime) Then Return SetError(3, 0, 0) + Return _TimeToTicks($aTime[0], $aTime[1], $aTime[2]) +EndFunc ;==>_GetTime + + +Func _FileName($sFullPath) + Local $iDelimiter = StringInStr($sFullPath, "\", 0, -1) + Local $sFilename, $sDisplayName + $sFilename = StringTrimLeft($sFullPath, $iDelimiter) + If StringLen($sFilename) > 45 Then + $sDisplayName &= StringLeft($sFilename, 20) & "[...]" & StringRight($sFilename, 20) Else - GUISetState(@SW_SHOW,$hGUI ) - TrayItemSetText($hEnableGUI, "Verstecken") + $sDisplayName = $sFilename EndIf - $bGUI = Not $bGUI + Return $sDisplayName EndFunc -Func _WordWrapTextForLabel($sText, $iCounter) - Local $sResult - Local $iTotalChar = StringLen($sText) - For $i = 1 To Ceiling($iTotalChar / $iCounter) - $sResult &= StringLeft($sText, $iCounter) & " " - $sText = StringTrimLeft($sText, $iCounter) - Next - $sResult = StringTrimRight($sResult, 1) ; cut last " " - Return $sResult -EndFunc - -Func _Zeit($iMs, $bComfortView = False) ; from ms to a format: "12h 36m 56s 13f" (with special space between - ChrW(8239)) +Func _Zeit($iMs, $bComfortView = True) ; from ms to a format: "12h 36m 56s 13f" (with special space between - ChrW(8239)) Local $sReturn - $iMs = Int($iMs) - Local $iFrames, $iMSec, $iSec, $iMin, $iHour, $sSign - If $iMs < 0 Then - $iMs = Abs($iMs) - $sSign = '-' - EndIf + $iMs = Int($iMs) + Local $iFrames, $iMSec, $iSec, $iMin, $iHour, $sSign + If $iMs < 0 Then + $iMs = Abs($iMs) + $sSign = '-' + EndIf $iMSec = StringRight($iMs, 3) $iFrames = $iMSec / 40 - $iSec = $iMs / 1000 - $iMin = $iSec / 60 - $iHour = $iMin / 60 - $iMin -= Int($iHour) * 60 - $iSec -= Int($iMin) * 60 + $iSec = $iMs / 1000 + $iMin = $iSec / 60 + $iHour = $iMin / 60 + $iMin -= Int($iHour) * 60 + $iSec -= Int($iMin) * 60 If $bComfortView Then ; no hours if not present and no frames If Not Int($iHour) = 0 Then $sReturn &= StringRight('0' & Int($iHour), 2) & 'h' & ChrW(8239) - $sReturn &= StringRight('0' & Int($iMin), 2) & 'm' & ChrW(8239) & StringRight('0' & Int($iSec), 2) & 's' + $sReturn &= StringRight('0' & Int($iMin), 2) & 'm' & ChrW(8239) + If Int($iHour) = 0 Then $sReturn &= StringRight('0' & Int($iSec), 2) & 's' ; zum DEBUGGING auskommentieren Else $sReturn = $sSign & StringRight('0' & Int($iHour), 2) & 'h' & ChrW(8239) & StringRight('0' & Int($iMin), 2) & 'm' & ChrW(8239) & StringRight('0' & Int($iSec), 2) & 's' & ChrW(8239) & StringRight('0' & Int($iFrames), 2) & 'f' EndIf Return $sReturn -EndFunc \ No newline at end of file +EndFunc ;==>_Zeit -- GitLab