0

I'm trying to turn this command into one that will convert a whole directory from flac to ogg:

ffmpeg -i musicfile.flac musicfile.ogg

I've read through the man page. But honestly it's a bit over my head. I don't want to use soundconverter(or any gui program). So I turn to you guys.

I use opensuse tumbleweed. And I use fish, not bash. Latest of everything.

Exactly what I would like, is to convert a flac folder into a separate ogg folder. Of say a quality of like q5. So say I put a hi.flac file into ~/flac/hi folder, I would like it to output into an ogg folder, keeping the files folder structure and name. ~/ogg/hi folder.

Is this possible? Or am I asking too much?

I've been using flac2all, and it does exactly what I just described, except it's been getting slower and slower. So I want to see if using the ffmpeg command is any faster. I searched and someone posted a small bash script, but it doesn't work for me. So again. I turn to you guys.

Thanks for reading.

4
  • 4
    "someone posted a small bash script, but it doesn't work for me" - please link the script. How did you use it? What exactly happened? What didn't happen? Help us understand how "it doesn't work for me" so we don't waste time providing the same solution Commented Dec 26, 2023 at 9:04
  • TBO I dislike this question. 10 minutes of ChatGPT or/and basic googling would enough to find out how to use Bash/shell scripting to 1) iterate through files 2) do operations on files 3) do them in parallel 4) work with file extensions if needed. I don't think SE is a website for "I'm lazy, please do this word for me". It's a website where people come to solve intractable/difficult issues. Maybe I'm wrong. Commented Dec 26, 2023 at 16:25
  • It's basically How can I convert a batch of flac files from 48000 24bit to 41000 16bit over on Super User Commented Dec 26, 2023 at 17:59
  • Chris thank you for that. I've seen that already, and it doesn't do what I want to. To wrap everything in a new directory that's named by the flac directory. Perhaps I'm asking too much. I appreciate your respone though Artem, if you would have read my post you would have known that I've searched this exhaustively. I'm just not good at writing scripts. So if coming here and asking for a script to be wrote for me, is annoying to you, then please block me. Problem Solved
    – h8uthemost
    Commented Dec 28, 2023 at 2:08

2 Answers 2

1

maybe something like this:

apt install parallel 

find /music -type d | xargs -i mkdir -p "/out_music/{}"
find /music -type f -name "*.flac" | parallel -j8 ffmpeg -i '{}' -ar 44100 -vn -codec:a libvorbis -qscale:a 7 -y '/out_music/{}.oga'

this will create files with names like .flac.oga though but personally, it has never caused me any problems.

2
  • 1
    I like it, thank you for posting this answer! May I recommend that you use find /music -type d -exec mkdir -p '/out_music/{}' ';' instead of find … | xargs…? It's that xargs is quite fiddly and will break if file names contain new lines, and we don't really need xargs here, as find can already -exec commands itself. Commented Dec 27, 2023 at 17:50
  • 1
    Not so much luck with the second find; if we really want to take advantage of parallel's parallelism, we need find to output things "safely". And we can do that: find /music -type f -name "*.flac" -print0 | parallel -0 -j8 ffmpeg … uses the zero byte as delimiter (which legitimately is that one character that can never be a valid part of a path!) Commented Dec 27, 2023 at 17:52
1

I like Paige's approach, though I'd have done it differently myself: You specified your shell was not bash, so I assume you won't mind a different shell to execute your shell; zsh. I bet fish can be used for this as well, but I have practically no experience with fish.

#!/usr/bin/zsh
targetfolder="$1"  # save argument to this shell script in
                   # variable $targetfolder


for infile in **/*.flac ; do
#   ^      ^  ^^     
#   |      |   |
#   \-------------------- we have a loop variable $infile…
#          \------------- which we set to a new value from the following list:
#              \--------- recursively (**) list all files ending in .flac (*.flac)

  mkdir -p "${targetfolder}/${infile:h}"
# ^      ^    ^                ^----^^
# |      |    |                |     |
# |      |    |                |     /
# |      |    |                |    |
# \------------------------------------ make a new directory
#        |    |                |    |
#        \----------------------------- making necessary parent directories on the way,
#                              |    |   ignoring all errors
#             |                |    |
#             \------------------------ expands to the argument passed to this script
#                              |    |
#                              \------- expands to the current found file name,
#                                   |   but modified:
#                                   |
#                                   \-- removes the trailing path component, i.e.
#                                       gets the directory containing the file
  ffmpeg -i "${infile}" "${targetfolder}/${infile%.flac}.ogg"
#                                                ^----^
#                                                  |
# remove the trailing ".flac" from the file name --/
done

or, in short, removing all comments:

#!/usr/bin/zsh
targetfolder="$1"

for infile in **/*.flac ; do
  mkdir -p "${targetfolder}/${infile:h}"
  ffmpeg -i "${infile}" "${targetfolder}/${infile%.flac}.ogg"
done

You use this script by saving it to some file, say massconvert.zsh; running chmod 755 /path/to/massconvert.zsh to make it executable, then run it in the folder containing your flac collection:

cd /home/utemost/flacs
/path/to/massconvert.zsh /home/utemost/oggs

That's it!

9
  • Nice! yeah I used to have one myself, although it's been years but admittedly its necessary because a lot of the filenames and such require normalization to expand correctly (I wish filesystems didn't allow newlines in filenames..) Moreover there's also problems with ffmpeg perhaps worth mentioning and if you want something like AAC-HE-V2 (PS+SBR) you'll wanna use fdkaac-cli, also stuff like downsampling (depending on your codec may need to be no higher than say 48,000 or may only support 16-bit and not 24/32; of lossy codecs aac-he-v2 was definitely my favorite but worth assaying them IMHO Commented Dec 27, 2023 at 19:11
  • I'm just upvoting for the work put in the comment(#)/diagram/help part :). It's very nice! Commented Dec 27, 2023 at 22:17
  • Thank you for your response, but I use fish and I'm not that great at writing code. So when I first tried the script I got error: (must start with '#!/path/to/fish'). Which was easy enough to fix. But when I ran it again I get error: (line 4): Missing end to balance this for loop for infile in ^~^.flac ; do Not sure about that one ^~^
    – h8uthemost
    Commented Dec 28, 2023 at 1:54
  • Well I temporarily changed my shell to zsh, and the script now tries to run. But I got a huge wall of text, before error(in red) pops up: {infile}: No such file or directory. I'll just continue doing it my old way. Unless somebody knows what I need to do to this command: find . -name "*flac" -exec oggenc -q 7 {} \; to output the .ogg files into it's own separate folder? Because along with flac2all, that's the only command or script I've been able to get working.
    – h8uthemost
    Commented Dec 28, 2023 at 2:20
  • @h8uthemost ah, typo in my script. I would have expected you to sleuth this out, but there's a $ missing in front of {infile}, let me fix my answer Commented Dec 28, 2023 at 9:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .