3

I have some songs in wav format. I would like to convert them to flac (which is also lossless, but has compression).

The solution needs to recurse through subdirectories to find .wav or .WAV files (ideally case insensitive), convert them to .flac and output the .flac files to a different directory tree. The original wav files are in ~/Music and the output flac files could go into ~/Music_Flac.

I am using Arch Linux x86_64 and I have ffmpeg as follows:

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
  • Do you need the same subdirectory structure under ~/Music_Flac as under ~/Music? – nohillside Mar 4 '18 at 8:53
  • @patrix yes, the same subdirectory structure under ~/Music_Flac. – MountainX Mar 4 '18 at 9:23
  • linux.com/learn/… is quite old but give you a lot of different possibilities : FUSE based GUI based Batch based – user4089 Mar 4 '18 at 9:48
3

find + ffmpeg solution:

find ~/Music -type f -iname "*.wav" -exec sh -c \
'bn=${1##*/}; bn=${bn%.*}; ffmpeg -loglevel 16 -i "$1" "${0}${bn}.flac"' ~/Music_Flac/ {} \;
  • $0 - passed into shell command as a destination directory ~/Music_Flac/
  • $1 - passed into shell command as a filepath {}
  • bn=${1##*/} - file basename without directory path
  • bn=${bn%.*} - file basename with extension truncated
  • -loglevel 16 - set the logging level 16 used by ffmpeg
  • I like the option of using find + ffmpeg. Could you explain the parameters you used? Looks very interesting. Thanks – MountainX Mar 4 '18 at 9:27
  • @MountainX, what parameters you would like to be explained? – RomanPerekhrest Mar 4 '18 at 11:12
  • For a complete answer, ideally, all of the parameters could be explained (at least briefly). – MountainX Mar 30 '18 at 20:47
  • @MountainX, you have my explanation – RomanPerekhrest Mar 30 '18 at 21:18
1

Another option would be to use bash's globbing to find the wav files, then shell parameter expansion features to change the directory structure and filenames:

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

If the files are only ever *.wav and *.WAV, you could skip the shopt nocaseglob and instead use for input in Music/**/*.wav Music/**/*.WAV.

I don't know what options you want to use for ffmpeg, but I provided an echo example of the input and output file paths that you can build from.

On this sample directory tree:

$ 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

the sample command output is:

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

... along with the required mkdir commands along the way.

0

In addition to @RomanPerekhrest 's answer, which I selected as the correct answer to the question, there is a GUI solution which also works well:

GitHub - dfaust/soundkonverter: soundKonverter is in maintenance mode, PRs are welcome.

It is in the Arch repos too:

Arch Linux - soundkonverter 3.0.1-1 (x86_64)

  • 1
    Not sure why this was down voted, but SoundKonverter actually works very well. I've been very impressed with it. – MountainX Apr 1 '18 at 0:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.