使用 ffmpeg 从 unix 命令批量将 wav 文件批量转换为 16 位

Bulk converting wav files to 16-bit with ffmpeg in batch from unix command

我有一个包含许多子文件夹的文件夹,每个子文件夹都有其他子文件夹,其中包含 wav 文件。

我想像这样转换所有文件:

ffmpeg -i BmBmGG-BmBmBmBm.wav -acodec pcm_s16le -ar 44100 BmBmGG-BmBmBmBm.wav

但是,我想保留目录结构和名称。覆盖或在并行目录中。

当输出文件具有不同的名称时,上面的命令字很好,但是,使用相同的名称我得到一个错误:

Multiple frames in a packet from stream 0
[pcm_s24le @ 0x1538ac0] Invalid PCM packet, data has size 4 but at least a size of 6 was expected
Error while decoding stream #0:0: Invalid data found when processing input

我第一次尝试像这样批量转换:

ffmpeg -i */*/*.wav -acodec pcm_s16le -ar 44100 */*/*.wav

不幸的是,这给出了同样的问题。如何将它们存储在并行目录中?说new///*.wav?

这成功了:

for f in $(find ./ -name '*.wav'); do 
ffmpeg -i $f -acodec pcm_s16le -ar 44100 ${f%.wav}z.wav; 
rm $f;
mv ${f%.wav}z.wav $f;
done

或者:

shopt -s globstar nullglob
for f in *.wav **/*.wav
do
  ffmpeg -i "$f" -acodec pcm_s16le -ar 44100 "${f%.wav}.new.wav"
  mv -f "${f%.wav}.new.wav" "$f"
done

这使用纯粹的Bash 构造而不是讨厌的find。如果您的文件名(或目录名)包含空格或特殊字符,这些将不会被展开。

简要说明:

  • shopt -s globstar启用双星运算符,这样**/*.wav会在所有子目录中搜索wav文件;
  • 如果没有扩展名为 wav 的文件,shopt -s nullglob 使两个 glob 扩展为零参数(注意:如果此代码是较大脚本的一部分,请记住禁用 nullglob 一旦你脱离了循环,以防止不必要的行为);
  • 所有变量都用双引号括起来,再次防止扩展;
  • mv -f 用于代替 rm + mv 技巧。