我有一些 wav 格式的歌曲。我想将它们转换为 flac (也是无损的,但有压缩)。
该解决方案需要递归通过子目录来查找 .wav 或 .WAV 文件(最好不区分大小写),将它们转换为 .flac 并将 .flac 文件输出到不同的目录树。原始的 wav 文件位于 ~/Music 中,输出的 flac 文件可以放入 ~/Music_Flac 中。
我使用的是 Arch Linux x86_64,并且我有 ffmpeg,如下所示:
ffmpeg version 3.4.2 Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 7.3.0 (GCC)
configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-avisynth --enable-avresample --enable-fontconfig --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libass --enable-libbluray --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libiec61883 --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-shared --enable-version3 --enable-omx
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libavresample 3. 7. 0 / 3. 7. 0
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
答案1
如果你想代替wav
我发现最简单的方法flac
是使用flac
二进制文件:
find . -name '*.wav' -exec flac --best {} --delete-input-file \;
以下是该命令不同部分的细分:
find .
:该命令搜索当前目录及其所有子目录(以 表示.
)中的文件。-name '*.wav'
:该标志指定我们正在寻找具有.wav
扩展名的文件。是*
匹配任何字符或字符组的通配符,因此该标志将匹配任何以.wav
.-exec
:此标志告诉find
命令对匹配搜索条件的文件执行命令。flac --best {} --delete-input-file
:这是对匹配文件执行的命令。是{}
一个占位符,表示命令正在处理的文件find
。该flac
命令使用标志指定的最高压缩级别将文件转换为 FLAC 格式--best
。该--delete-input-file
标志告诉命令在成功转换为 FLAC 格式后flac
删除原始文件。.wav
\;
:这是命令结束信号所必需的,flac
以便-exec
选项正常运行。
答案2
find
+ffmpeg
解决方案:
find ~/Music -type f -iname "*.wav" -exec sh -c \
'bn=${1##*/}; bn=${bn%.*}; ffmpeg -loglevel 16 -i "$1" "${0}${bn}.flac"' ~/Music_Flac/ {} \;
$0
- 作为目标目录传递到 shell 命令中~/Music_Flac/
$1
- 作为文件路径传递到 shell 命令中{}
bn=${1##*/}
- 不带目录路径的文件基名bn=${bn%.*}
- 扩展名被截断的文件基名-loglevel 16
16
- 设置使用的日志记录级别ffmpeg
答案3
另一种选择是使用 bash 的 globbing 来查找 wav 文件,然后使用 shell 参数扩展功能来更改目录结构和文件名:
shopt -s globstar nocaseglob
for input in Music/**/*.wav
do
indir=$(dirname "$input")
outdir=${indir/#Music/Music_Flac}
[ ! -d "$outdir" ] && mkdir -p "$outdir"
infile=$(basename "$input")
outfile=${infile%.???}.flac
echo ffmpeg -i "$input" "${outdir}/${outfile}"
done
如果文件只有*.wav
和*.WAV
,您可以跳过shopt nocaseglob
并改用for input in Music/**/*.wav Music/**/*.WAV
。
我不知道您想对 ffmpeg 使用哪些选项,但我提供了echo
您可以构建的输入和输出文件路径的示例。
在此示例目录树上:
$ tree Music
Music
├── a.wav
├── b.WAV
├── c d.wav
└── subdir1
├── a.wav
├── b.WAV
├── c d.wav
└── subdir2
├── a.wav
├── b.WAV
└── c d.wav
示例命令输出为:
ffmpeg -i Music/a.wav Music_Flac/a.flac
ffmpeg -i Music/b.WAV Music_Flac/b.flac
ffmpeg -i Music/c d.wav Music_Flac/c d.flac
ffmpeg -i Music/subdir1/a.wav Music_Flac/subdir1/a.flac
ffmpeg -i Music/subdir1/b.WAV Music_Flac/subdir1/b.flac
ffmpeg -i Music/subdir1/c d.wav Music_Flac/subdir1/c d.flac
ffmpeg -i Music/subdir1/subdir2/a.wav Music_Flac/subdir1/subdir2/a.flac
ffmpeg -i Music/subdir1/subdir2/b.WAV Music_Flac/subdir1/subdir2/b.flac
ffmpeg -i Music/subdir1/subdir2/c d.wav Music_Flac/subdir1/subdir2/c d.flac
...以及mkdir
一路上所需的命令。
答案4
除了我选择的 @RomanPerekhrest 的答案作为问题的正确答案之外,还有一个效果很好的 GUI 解决方案:
soundkonverter,soundKonverter 处于维护模式,欢迎 PR,下载soundkonverter的源码_GitHub_酷徒
它也在 Arch 仓库中: