将包含数千个(音频)文件的文件夹拆分为每个 74 分钟的子文件夹的脚本

将包含数千个(音频)文件的文件夹拆分为每个 74 分钟的子文件夹的脚本

我有一个文件夹,里面有大约 1600 多个 mp3 文件,我想把它们分成多个“专辑”即子文件夹中音频文件的总时长不超过74分钟(音频 CD 的大小,为了在我的 Windows Media Player 库中组织,并不打算将所有这些刻录到物理 CD 中)。

因此,我需要编写一个脚本(可以是 Bash - 我已安装 WSL,也可以是 Windows Batch - 怀疑它能否实现我想要的效果,或者 PowerShell),循环遍历所有 ~1600+ 个文件,并开始将它们移动到子文件夹,例如Volume 1。当此子文件夹接近超过 74 分钟的限制时,它应该创建一个新的子文件夹(例如Volume 2),然后继续移动到该文件夹​​,然后继续移动到下一个文件夹,依此Volume 3类推。

我在这里询问的原因是,虽然我对这个 bash 脚本的运行逻辑有一些想法,但我不知道如何获取音频文件的持续时间,更不用说在达到(或即将达到) 74 分钟的限制时控制切换文件夹的流程了。

答案1

A约 650 MB 的 CD可容纳MP3文件约十个小时就比赛时间而言。

你说你有 MP3 文件,并且这种格式会显著压缩音频,但保真度有所下降。如果你使用未压缩音频格式,如 WAV 或 PCM,那么每张 CD 的播放时间确实会限制在 74 分钟左右。使用无损,压缩格式,如 APE 或 FLAC,您可以在 CD 上获得更多。MP3 牺牲了一点绝对保真度来获得更高的压缩率。

刻录音频格式的 CD 毫无意义,因为您无法恢复因 MP3 压缩而丢失的信息。另一方面,几乎全部近期制造的 CD 播放器可以播放MP3文件,原样,在数据光盘上。只需创建一张 CD数据光盘,可容纳 650 MB 的 MP3 文件。完全没有必要知道性能长度,只是要存储的 MB 数,如果有很多小文件,则会留下一点额外的空间,因为每个文件的最后一个扇区都会浪费一点空间。

答案2

-- 这将是实际代码和伪代码的混合 --

在 Powershell 中,要获取 MP3 文件的长度,我们可以使用这个出色的显示扩展文件属性功能:

$dir_nam = "C:\Users\Username\Desktop\Folder"
$nam_len = Get-ExtensionAttribute -FullName $dir_nam -ExtensionAttribute Filename, Length  
## This will populate the $nam_len variable with the FullName, Filename & Length for each file in the directory.

除了 74 分钟的最大长度之外,您还需要设置最小长度(我将使用 70 分钟)。接下来,我们需要知道每个文件的平均长度,这样我们就可以知道有多少文件可以符合 70-74 分钟的时间限制。

foreach ($tim in ($nam_len | Select-Object -ExpandProperty Length)){
$secs = ([TimeSpan]::Parse($tim)).TotalSeconds # converts each value to seconds
$totl = $totl + $secs}  # Sum (length) of all the MP3s (in seconds)

$avg = ($totl/($nam_len.Count))/60 # (total seconds/number of MP3s)/60 seconds = average length in minutes
$num_mp3s = [math]::floor(72/$avg) # average number of MP3s in 72 minutes

现在处理这里的伪代码循环:

## Make this into a loop 
$batch = $nam_len | Sort-Object {Get-Random} | Select-Object -first $num_mp3s # Randomly select the avg number of MP3's
If ($batch).Length -gt 70 # Make sure the sum (length) is > 70 minutes
-and 
($batch).Length -lt 74){  # Make sure the sum (length) is < 74 minutes
    Create Directory X++ # Create a new directory
    Move $batch.FullName to Directory X++ 
    }
Else (Loop-Again)
Execute the Loop = (total number of MP3s/$num_mp3s) or until all files have been placed.

当您接近终点时,您可能必须减少完成所需的最少分钟数。

相关内容