"I'm sharing with you a script that uses ffmpeg to trim silence at the beginning and end of a WAV or FLAC file. It also has an option to change the output sample rate and resize the cover art.
There is no loss of quality. I tested it by trimming the same FLAC file 150 times. ffmpeg.exe must be located in the script directory.
Happy trimming
Code: Select all
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn ; Enable warnings to assist with detecting common errors.
; Script made by Ivan Radolović
;@Ahk2Exe-Bin C:\Program Files\AutoHotkey\Compiler\Unicode 32-bit.bin
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#Persistent
#NoTrayIcon
#SingleInstance off
global TrimBeginTreshold, TrimEndTreshold, NormalizeValue, ResizeScale, Samplerate
RegRead, TrimBeginTreshold, HKEY_CURRENT_USER, SOFTWARE\AnoApps\WavFlacTrim, TrimBeginTreshold
RegRead, TrimEndTreshold, HKEY_CURRENT_USER, SOFTWARE\AnoApps\WavFlacTrim, TrimEndTreshold
RegRead, ResizeScale, HKEY_CURRENT_USER, SOFTWARE\AnoApps\WavFlacTrim, ResizeScale
RegRead, Samplerate, HKEY_CURRENT_USER, SOFTWARE\AnoApps\WavFlacTrim, Samplerate
RegRead, FirstRun, HKEY_CURRENT_USER, SOFTWARE\AnoApps\WavFlacTrim, FirstRun
If ErrorLevel
{
TrimBeginTreshold := -70
TrimEndTreshold := -70
ResizeScale := "Keep"
Samplerate := "Keep"
RegWrite, REG_SZ, HKEY_CURRENT_USER, SOFTWARE\AnoApps\WavFlacTrim, FirstRun, 1
RegWrite, REG_SZ, HKEY_CURRENT_USER, SOFTWARE\AnoApps\WavFlacTrim, TrimBeginTreshold, %TrimBeginTreshold%
RegWrite, REG_SZ, HKEY_CURRENT_USER, SOFTWARE\AnoApps\WavFlacTrim, TrimEndTreshold, %TrimEndTreshold%
RegWrite, REG_SZ, HKEY_CURRENT_USER, SOFTWARE\AnoApps\WavFlacTrim, ResizeScale, %ResizeScale%
RegWrite, REG_SZ, HKEY_CURRENT_USER, SOFTWARE\AnoApps\WavFlacTrim, Samplerate, %Samplerate%
}
mapped_valueBegin := TrimBeginTreshold
mapped_valueEnd := TrimEndTreshold
IfNotExist, ffmpeg.exe
{
Msgbox, ffmpeg.exe do not exist in script dir. App exits
ExitApp
}
; Define GUI dimensions and drag-and-drop area
Gui, Main:+AlwaysOnTop
Gui, Main:+Resize
; Create edit box and make it read-only
Gui, Main:Add, Edit, ReadOnly vMyEditBox w50 h50
Gui, Main:Show, w480 h320, WavFlac Trim 1.0 powered by ffmpeg
; Create menu bar
Menu, MyMenu, Add, Start, MyMenu_Start
Menu, MyMenu, Add, About, MyMenu_About
Menu, MyMenu, Add, Options, MyMenu_Options
Menu, MyMenu, Add, Exit, MyMenu_Exit
Gui, Main:Menu, MyMenu
GuiControl, Main:Text, MyEditBox, Drop wav and flac files here
return
; Options menu
MyMenu_Options:
TrimBeginTresholdScrollbar := ((TrimBeginTreshold - (-99)) / (-30 - (-99))) * 100
TrimEndTresholdScrollbar := ((TrimEndTreshold - (-99)) / (-30 - (-99))) * 100
;NormalizeValueScrollbar := ((NormalizeValue - 0) / (-50 - 0)) * (100 - 0) + 0
CoverartItemList := "Keep|150:150|300:300|600:600|800:800|1200:1200"
SamplerateItemList := "Keep|32000|44100|48000|96000|192000"
Loop, parse, CoverartItemList, |,
if (A_LoopField = ResizeScale)
SelectCoverartItemNumber := A_Index
Loop, parse, SamplerateItemList, |,
if (A_LoopField = Samplerate)
SelectSamplerateItemNumber := A_Index
Gui, Main:+Disabled
Gui, Main:-AlwaysOnTop
Gui, Options:+AlwaysOnTop
Gui, Options:+Owner
Gui, Options:Add, GroupBox, x10 y30 w230 h80, Trim silence
Gui, Options:Add, Text, x20 y50 w80 h20, Begin Treshold:
Gui, Options:Add, Slider, x100 y50 w100 h20 vTrimBeginTresholdSlider gUpdateTrimBeginTreshold, %TrimBeginTresholdScrollbar%
Gui, Options:Add, Text, x205 y50 w30 h20 vTrimBeginTresholdDisplay, %TrimBeginTreshold%dB
Gui, Options:Add, Text, x20 y80 w80 h20, End Treshold:
Gui, Options:Add, Slider, x100 y80 w100 h20 vTrimEndTresholdSlider gUpdateTrimEndTreshold, %TrimEndTresholdScrollbar%
Gui, Options:Add, Text, x205 y80 w30 h20 vTrimEndTresholdDisplay, %TrimEndTreshold%dB
Gui, Options:Add, Text, x20 y128 w80 h20, Resize Coverart
Gui, Options:Add, DropDownList, x110 y128 w100 h200 Choose%SelectCoverartItemNumber% vDropDownListCoverartSelection, %CoverartItemList%
Gui, Options:Add, Text, x20 y154 w80 h20, Samplerate
Gui, Options:Add, DropDownList, x110 y152 w100 h200 Choose%SelectSamplerateItemNumber% vDropDownListSamplerateSelection, %SamplerateItemList%
Gui, Options:Add, Button, x40 y188 w80 h30 gApplyButton vDefaultButton, OK
Gui, Options:Add, Button, x140 y188 w80 h30 gCancelButton, Cancel
Gui, Options:Show, w260 h240, Options
return
; Update the text next to the Trim Begin Treshold slider
UpdateTrimBeginTreshold:
mapped_valueBegin := ((TrimBeginTresholdSlider - 0) / (100 - 0)) * (-30 - (-99)) + (-99)
mapped_valueBegin := Round(mapped_valueBegin)
GuiControlGet, TrimBeginTresholdDisplay, , %mapped_valueBegin%
GuiControl,, TrimBeginTresholdDisplay, %mapped_valueBegin%dB
return
; Update the text next to the Trim End Treshold slider
UpdateTrimEndTreshold:
mapped_valueEnd := ((TrimEndTresholdSlider - 0) / (100 - 0)) * (-30 - (-99)) + (-99)
mapped_valueEnd := Round(mapped_valueEnd)
GuiControlGet, TrimEndTresholdDisplay, , %mapped_valueEnd%
GuiControl,, TrimEndTresholdDisplay, %mapped_valueEnd%dB
return
; Update the text next to the Normalize Treshold slider
UpdateNormalizeValue:
mapped_norm_value := ((NormalizeValueSlider - 0) / (100 - 0)) * (-50 - 0) + 0
mapped_norm_value := Round(mapped_norm_value)
GuiControlGet, NormalizeValueDisplay, , %mapped_norm_value%
GuiControl,, NormalizeValueDisplay, %mapped_norm_value%dB
return
; Apply button
ApplyButton:
TrimBeginTreshold := mapped_valueBegin
TrimEndTreshold := mapped_valueEnd
;NormalizeValue := mapped_norm_value
Gui, Main:-Disabled
Gui, Main:+AlwaysOnTop
Gui, Options:Submit, NoHide
ResizeScale := DropDownListCoverartSelection
Samplerate := DropDownListSamplerateSelection
RegWrite, REG_SZ, HKEY_CURRENT_USER, SOFTWARE\AnoApps\WavFlacTrim, TrimBeginTreshold, %TrimBeginTreshold%
RegWrite, REG_SZ, HKEY_CURRENT_USER, SOFTWARE\AnoApps\WavFlacTrim, TrimEndTreshold, %TrimEndTreshold%
RegWrite, REG_SZ, HKEY_CURRENT_USER, SOFTWARE\AnoApps\WavFlacTrim, ResizeScale, %ResizeScale%
RegWrite, REG_SZ, HKEY_CURRENT_USER, SOFTWARE\AnoApps\WavFlacTrim, Samplerate, %Samplerate%
Gui, Options:Destroy
return
; Cancel button
CancelButton:
Gui, Main:+AlwaysOnTop
Gui, Main:-Disabled
Gui, Options:Cancel
Gui, Options:Destroy
return
; Close the Options GUI
OptionsGuiClose:
Gui, Main:+AlwaysOnTop
Gui, Main:-Disabled
Gui, Options:Destroy
return
MainGuiSize:
; Get the new dimensions of the GUI window
Gui, +LastFound
WinGetPos, X, Y, Width, Height, A
Width -= 18
Height -= 60
; Resize the edit box to fill the new dimensions of the GUI window
GuiControl, Move, MyEditBox, x0 y0 w%Width% h%Height%
return
; Define actions for menu items
MyMenu_Start:
Gui, -AlwaysOnTop
Gui, +Disabled
FileSelectFile, SelectedFiles, M3, , Open a file, Audio (*.flac; *.wav;)
Gui, +AlwaysOnTop
Gui, -Disabled
if (SelectedFiles = "")
return
ProcessFailed := "0"
ProcessSeccess := "0"
GuiControl, Text, MyEditBox, Trimming...
Loop, parse, SelectedFiles, `n
{
if (A_Index = 1)
{
OutDir := A_LoopField
Continue
}
else
{
Status := "Done."
ProcessedCount := A_Index
SelectedFile := OutDir . "\" . A_LoopField
SelectedFile := StrReplace(SelectedFile, "\\", "\")
SplitPath, SelectedFile, OutFileName, OutDir, OutExtension, OutNameNoExt
success := TrimFile(SelectedFile)
if (success) {
ProcessSeccess++
} else {
ProcessFailed++
Status := "Failed to trim."
}
FileGetAttrib, Attributes, %OutDir%\tmp%RndNumber%.%OutExtension%
if InStr(Attributes, "R") {
Attribute := " ----> File is ReadOnly "
Status := "Failed to trim."
ProcessFailed++
ProcessSeccess--
FileMove, %OutDir%\tmp%RndNumber%.%OutExtension%, %SelectedFile%
}
ListProcessedFiles := ListProcessedFiles
. Attribute
. OutFileName
. " - "
. Status
. "`n"
Attribute := ""
GuiControl, Text, MyEditBox, %ListProcessedFiles%
}
}
ListProcessedFiles := ListProcessedFiles
. "`nDone, "
. ProcessSeccess
. " file/s sucessfully trimmed., "
. ProcessFailed
. " failed."
GuiControl, Text, MyEditBox, %ListProcessedFiles%
ListProcessedFiles := ""
ProcessFailed := ""
ProcessSeccess := ""
IfExist, C:\Program Files (x86)\Mp3tag\mp3tag.exe
{
Gui, +Disabled
Msgbox, 262180, Suggestion: Mp3tag, Do you want to open trimmed files in Mp3tag?
Gui, -Disabled
IfMsgBox Yes
Run, C:\Program Files (x86)\Mp3tag\mp3tag.exe /fp:"%SelectedFile%"
}
return
MyMenu_About:
Gui, +Disabled
MsgBox, 262208, About, WavFlac Trim 1.0 is powered by ffmpeg.`n`n Script made by Ivan Radolović 2023 ©
Gui, -Disabled
return
MainGuiClose:
MyMenu_Exit:
ExitApp
return
MainGuiDropFiles:
ProcessFailed := "0"
ProcessSeccess := "0"
GuiControl, Text, MyEditBox, Trimming...
Loop, parse, A_GuiEvent, `n
{
Status := "Done."
ProcessedCount := A_Index
SelectedFile := A_LoopField
SplitPath, SelectedFile, OutFileName, OutDir, OutExtension, OutNameNoExt
success := TrimFile(SelectedFile)
if (success) {
ProcessSeccess++
} else {
ProcessFailed++
Status := "Failed to trim."
}
FileGetAttrib, Attributes, %OutDir%\tmp%RndNumber%.%OutExtension%
if InStr(Attributes, "R") {
Attribute := " ----> File is ReadOnly "
Status := "Failed to trim."
ProcessFailed++
ProcessSeccess--
FileMove, %OutDir%\tmp%RndNumber%.%OutExtension%, %SelectedFile%
}
ListProcessedFiles := ListProcessedFiles
. Attribute
. OutFileName
. " - "
. Status
. "`n"
Attribute := ""
GuiControl, Text, MyEditBox, %ListProcessedFiles%
}
ListProcessedFiles := ListProcessedFiles
. "`nDone, "
. ProcessSeccess
. " file/s sucessfully trimmed., "
. ProcessFailed
. " failed."
GuiControl, Text, MyEditBox, %ListProcessedFiles%
ListProcessedFiles := ""
ProcessFailed := ""
ProcessSeccess := ""
IfExist, C:\Program Files (x86)\Mp3tag\mp3tag.exe
{
Gui, +Disabled
Msgbox, 262180, Suggestion: Mp3tag, Do you want to open trimmed files in Mp3tag?
Gui, -Disabled
IfMsgBox Yes
Run, C:\Program Files (x86)\Mp3tag\mp3tag.exe /fp:"%SelectedFile%"
}
return
TrimFile(SelectedFile) {
Random, RndNumber, NewSeed
SplitPath, SelectedFile, OutFileName, OutDir, OutExtension, OutNameNoExt
if (OutExtension != "flac" and OutExtension != "wav") {
return 0
}
FileMove, %SelectedFile%, %OutDir%\tmp%RndNumber%.%OutExtension%
if ErrorLevel
return 0
if ResizeScale != Keep
resizeCoverArt := "-vf scale=" . ResizeScale
if Samplerate != Keep
Resample := "-ar " . Samplerate
AF_Param = silenceremove=start_periods=1:start_silence=0.1:start_threshold=%TrimBeginTreshold%dB:detection=rms,areverse,silenceremove=start_periods=1:start_silence=0.1:start_threshold=%TrimEndTreshold%dB:detection=rms,areverse
RunWait, ffmpeg.exe -i "%OutDir%\tmp%RndNumber%.%OutExtension%" %Resample% -af "%AF_Param%" -compression_level 10 %resizeCoverArt% "%SelectedFile%" , , Hide
if ErrorLevel {
FileMove, %OutDir%\tmp%RndNumber%.%OutExtension%, %SelectedFile%
return 0
} else {
FileDelete, %OutDir%\tmp%RndNumber%.%OutExtension%
return 1
}
}
[Mod action: Moved from main section, which is for v2 code]