一次修剪多个 mp3 文件

qad*_*nza 7 mp3

所以,我在一个文件夹中有数百个 .mp3 文件。几乎每个人都有一段时间的沉默,然后你才能听到声音。并且周期的大小不同。

文件的结尾也是如此。

是否有任何应用程序(如果可能的话,免费)可以让我一次修剪所有文件,以便每个文件在歌曲结束之前和结束时都有相同的静音时间(例如五秒)。

或者,也许是一个 mp3 播放器,它可以按照描述的方式调整每首歌曲的静音。

另外,如果我必须一个一个地剪切所有文件,哪个应用程序最适合此任务(即速度足够快)?

nix*_*xda 10

我知道四种方法:mp3DirectCutMp3splt-GTKMp3spltffmpeg


mp3DirectCut(GUI 版本,快速出结果的最佳选择)

  • 启动后,转到文件»批处理
  • 添加您的 mp3 文件夹,选择自动裁剪并按开始

    在此处输入图片说明

提示

  • 选择一个不同的文件夹作为输出来测试一些结果文件。验证后,重新运行它并选择Overwrite originals。您应该在几秒钟内完成,因为程序不会重新编码您的 mp3 文件
  • 您可能想要启用设置 » 保持覆盖源文件的日期

Mp3splt-gtk(GUI 版本,适用于所有主要操作系统平台)

  • 下载$启动程序,点击Batch & Automatic split
  • 选择使用静音检测修剪并按批量拆分

    在此处输入图片说明


mp3splt(命令行版本,适用于所有主要操作系统平台)

下载mp3splt,打开您的PowerShell ISE,更改两个路径并运行以下代码:

$files = Get-ChildItem "C:\my\musicfolder" -Recurse -Include *.mp3,*.ogg,*.flac
$exe = "C:\path\to\mp3splt.exe"

ForEach ($file in $files) {    
    If ($file.BaseName -notmatch "_trimmed$" ) {        

        $newFile = $file.DirectoryName + "\" + $file.BaseName + "_trimmed" + $file.Extension
        If (Test-Path $newFile) {Remove-Item $newFile }

        & $exe -r -p "th=-48,min=2" `"$file`" | Out-Null

        Remove $file.Fullname
        Rename $($file.DirectoryName + "\" + $file.BaseName + "_trimmed" + $file.Extension) $file.Fullname
    }
}
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

提示

  • -r -p th=-48, min=2是在文件开始/结束时删除静音的选项。th以 dB 为单位定义阈值电平。下面的一切都被视为沉默。min=2以秒为单位设置最小静音。只有超过 2 秒的静音才会被截断
  • 您可以通过-P在 mp3splt 命令的末尾添加一个大写来假装测试运行。它输出错误或说一切顺利。如果使用,请注释掉RemoveRename因为没有创建新文件来处理它们
  • 对于测试,您还可以使用-d FOLDERPATH选择单个输出文件夹并-o@f使用原始文件名作为输出(否则_trimmed将被附加)

    解释所有可用选项的文档


FFmpeg(命令行版本,适用于所有主要操作系统平台)

-af silenceremove不应该使用FFmpeg 的音频过滤器,因为它总是重新编码您的文件,而且您不能保持与输入文件相同的音频质量-acodec copy不能在这里使用。即使您处理具有不同质量的多个文件,您也只能选择一种固定比特率。

但是,还有另一个 ffmpeg 选项:-af silencedetect. 该理论已经在 StackOverflow 上进行了解释。我将它用于 Windows 和 PowerShell。

下载ffmpeg,打开您的PowerShell ISE,更改两个路径并运行以下代码:

$files = Get-ChildItem "C:\path\to\musicfolder" -Recurse -Include *.mp3,*.ogg,*.flac
$ffmpeg = "C:\path\to\ffmpeg.exe"

ForEach ($file in $files) {
    If ($file.BaseName -notmatch "_trimmed$" ) {

        # Detect silence with ffmpeg and "silencedetect". Save the complete output to variable $log
        $log = & $ffmpeg -hide_banner -i `"$file`" -af "silencedetect=duration=1:noise=-50dB" -f null - 2>&1

        $totalLength = [string]$log | where {$_ -match '(?<= Duration:.*)[\d:\.]+' } | % {$matches[0]}        
        $totalLength = ([TimeSpan]::Parse($totalLength)).TotalSeconds

        # Use regex to search all numbers after string "silence_end". Save them as string array in the format XXX.XXX
        # Check if any 'silence_end' was found. If yes, save the first silence ending time as mp3 start time        
        [string[]]$silenceEnd = $log | where {$_ -match '(?<=silence_end: )[-\d\.]+' } | % {$matches[0]}            
        If ($silenceEnd.count -gt 0 -And [double]$silenceEnd[0] -lt $totalLength/2) {
            [double]$trackStart = $silenceEnd[0]
        } else {
            [double]$trackStart = 0
        }

        # Do the same again but for silence starting times. Save the last one as mp3 end time
        [string[]]$silenceStart = $log | where {$_ -match '(?<=silence_start: )[-\d\.]+' } | % {$matches[0]}                
        If ($silenceStart.count -gt 0 -And $silenceStart[$silenceStart.count-1] -gt $totalLength/2) {
            [double]$trackEnd = $silenceStart[$silenceStart.count-1]
        } else {        
            [double]$trackEnd = $totalLength
        } 

        # calculate duration since ffmpeg's -t option wants a duration and not a timestamp
        $duration = $trackEnd - $trackStart

        # Put together the new file name. If file already exists from  previous run, delete it
        $newFile = $file.DirectoryName + "\" + $file.BaseName + "_trimmed" + $file.Extension
        If (Test-Path $newFile) {Remove-Item $newFile }                        

        # Run ffmpeg with our calculated start and duration times to remove silence at start and end
        write-host "$ffmpeg -i `"$file`" -ss $trackStart -t $duration -acodec copy `"$newFile`"  2>&1"
        & $ffmpeg -i `"$file`" -ss $trackStart -t $duration -acodec copy `"$newFile`"  2>&1

        # Delete the original mp3 file and rename the new mp3 file to the original name
        Remove-Item $file.Fullname   
        Rename-Item $newFile $file.Fullname
    }
}
Run Code Online (Sandbox Code Playgroud)