Bulk converting wav files to 16-bit with ffmpeg in

2019-07-21 07:01发布

问题:

I have a folder consisting of many subfolders, each with other subfolders and therein wav files.

I want to convert all of the files like this:

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

BUT, I want the directory structures and names preserved. Either overwritten or in a parallel directory.

The above command words fine when the output file has a different name, however, with the same name I get an error:

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

I first tried bulk converting like this:

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

Unfortunately, this gives the same problem. How can I store them in a parallel directory? Say new///*.wav?

回答1:

This did the trick:

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


回答2:

Alternatively:

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

This uses pure-Bash constructs instead of the nasty find. If your file names (or directory names) contain spaces or special characters, these won't be expanded.

A brief explanation:

  • shopt -s globstar enables the double-star operator, so that **/*.wav will search for wav files in all subdirectories;
  • if there are no files with the wav extension, shopt -s nullglob makes the two globs expand to zero arguments (note: if this code is part of a larger script, remember to disable nullglob once you are out of the loop, to prevent unwanted behavior);
  • all variables are surrounded by double quotes, again to prevent expansion;
  • mv -f is used instead of the rm + mv trick.


标签: bash unix ffmpeg