Trim Silence from Audio Sample Files in Bulk or Batch Mode


I found it surprisingly difficult to find a quick and easy way to trim silence in bulk or batch mode from a large number of audio files. While there’s some GUI software that facilitates trimming, a superb option for manipulating video and sound files is called FFmpeg. It’s free, open source and cross platform.

However, FFmpeg is so powerful and versatile, it can be a bit intimidating to figure out.

So here’s the script I recently created for myself to trim silence at the beginning and end in each of all WAV files in a folder. Each file is only a few seconds long (to be used in a sampler instrument).

I’m posting it here in the hope that it will save someone else a little time.

The script requires FFmpeg and runs in Powershell. I wrote the script for a Windows system, but since PowerShell and FFmpeg are multi-platform, it hopefully works with minor modifications on MacOS and popular Linux systems.

# ### Set the source and target folders  ####################

$sourceDir = "h:\Temp"
$targetDir = $sourceDir + "_trimmed"

# ### Set the desired FFmpeg directives  ################################################################

$ffmpegDirectives = "-af silenceremove=start_periods=1:start_threshold=-40dB:stop_periods=1:stop_duration=1:stop_threshold=-60dB: -c:a pcm_s32le  -y"

# ### Set the location of the FFmpeg program  ################################################################

$ffmpegPath = "C:\Other Programs\ffmpeg\bin\ffmpeg.exe"

# ### No changes needed below this line ################################################################

Write-Host "--------------------------------------------------------------------"
Write-Host "Trim Silence from files "
$now = Get-Date -Format "HH:mm:ss"
Write-Host @("script started at " + $now )

# Set-Location $sourceDir
New-Item -Path $targetDir -Force -ItemType directory | Out-Null

$wavFileList = Get-ChildItem -Path $sourceDir -Name -Include "*.wav" 

$fileCount = 0
foreach ( $wavFile in $wavFileList ) {

    $fileCount++

    $sourcePath = Join-Path $sourceDir $wavFile
    $targetPath = Join-Path $targetDir $wavFile

#    Write-Host @($sourcePath + " >>> " + $targetPath)

    $ffmpegParameters = " -loglevel error  -i """ + $sourcePath + """ " + $ffmpegDirectives + "  """ + $targetPath + """"

#    Write-Host $ffmpegParameters
    Start-Process -FilePath $ffmpegPath -ArgumentList $ffmpegParameters -NoNewWindow
}

# ########################################################################
Write-Host @("Files processed: " + $fileCount)
$now = Get-Date -Format "HH:mm:ss"
Write-Host @("script completed at " + $now )
Write-Host "-------------------------------------------------------------`n"