How to best transcode an entire library of music?

I have a pretty decent music library of mostly tracks I’ve pulled from youtube or from scattered places around the net. So Y have a fair mix of files. Problem is I’m not going to use my phone for music anymore, if ever again. So, for an ipod, I have to convert to AAC, ALAC, WAV, or MP3.

Someone is going to say VLC, and while thats cute and all, I select multiple files, can’t select an output point worth dick, and I have to sit there for 3 hours going through 5000 songs and videos hitting the overwrite button, rather than the DEVS PUTTING IN AN OVERWRITE ALL BUTTON, WOW, LIKE THATS NOT FUCKING SENSIBLE…

Ahem.

So I need a better tool than shitty VLC. Someone’ll say ffmpeg, I’d like the folder structure copied too though, and IDK of a tool that can do that.

Any help is appreciated.

2 Likes

I am also interested on that for Linux :pleading_face:. Remember Winamp in windows, it was so easy. Hope something like that exists on then linux side.

Rhythmbox is the one I use for ripping my CD (Yes I still use CDs :smirk:) but lacks the trans-coding feature. I want to make an mp3 usb, but have the same issues as you.

1 Like

You can just use ffmpeg CLI to do that. Personally, every time I want to do something like that, I google how to do it in the CLI as I find music conversion software often is kind of an obnoxious bloatware. Not saying all of them are but some Ive had installed surely are and didnt even necessarily do what I wanted them to do.

Its fairly easy if you know exactly what you want to do to figure out a one time use command(s) that does exactly that.

1 Like

Found this.

Still unsure how to get it to copy the directory structure but I’m sure I could make that happen just with bash scripting

1 Like
for{
for i in *.mkv;
  do name=`echo "$i" | cut -d'.' -f1`
  echo "$name"
  ffmpeg -i "$i" "${name}.mp3"
done

for i in *.mp4;
  do name=`echo "$i" | cut -d'.' -f1`
  echo "$name"
  ffmpeg -i "$i" "${name}.mp3"
done

for i in *.webm;
  do name=`echo "$i" | cut -d'.' -f1`
  echo "$name"
  ffmpeg -i "$i" "${name}.mp3"
done}
done

Ended up with this. Worked, till the last file, and failed on the extra done. IDK shit about bash I just tried to make it check through all of the listed formats, which is what I assume it did.

At the moment I am zeroing out my ipod’s music partition as rhythmbox doesn’t know how to do math and tells me my ipod will run out of its 64GB of space on only 10GB of music.

Yeah whatever.

This is only a highlight of the problems in linux in general but its not like anyone’ll fix it unless I do it myself.

For the record, if you manage your library with beets, it has a built in transcoding feature which will keep everything organized and tagged properly, and let’s you properly specify all kinds of processing options, including output directory.

5 Likes

I wonder hows the apple eco system as far as transferring music goes these days? Back when I had an ipod I was basically hard locked into using itunes and the file formats it accepted to get songs onto it.

I think it’s even worse now that it’s ipod touch and iphone. Back in the day, you could set it up to show up as a USB disk and just throw MP3s on it. Dunno that it’s the same these days.

They don’t want you to store it.
They want you to stream it.
With Apple Music.

2 Likes

Well they basically dumped itunes. Spotify is better anyways for most people nowadays. And the better alternatives are all out there, just most people scoff at you if you don’t have a phone.

Unfortunately, I think most people are a bit dense putting everything on their phone. Its kinda like having your office in your bedroom. Your work and relax are in the same space.

No. Separate that shit. I want my music, not fucking aunt becky calling me 40 times a day or whatever dumb shit.

1 Like

Spotify is not an alternative to itunes though. Its an alternative to other streaming services. I also have all my music on my phone. I also have my own music collection. If you dont want to deal with it its perfectly valid to have a spotify subscription instead. I just dont wanna get into the situation where song x is not on spotify and I would need another streaming service to listen to it. Its like when game of thrones came out. Who on earth was using HBOs streaming service? Also what do I do when spotify goes away someday? I can use another one, but there goes all my playlists too.

I dont personally benefit much from the “i can listen to music without an internet connection” argument. But sometimes I do. It also eats less battery to play local songs.

But for me the bigger motivation to maintain my own music collection is just the long term preservation of the songs I listen to and the basically 100% guarantee that every song that gets released that I want I will have a way to get to without jumping ship to another service.

I argue about this with my sister all the time. She just doesn’t care. Youtube will be there when spotify dies, is her opinion. Its just spotify is slightly more convenient, even if its 12 bucks a month.

Michigan.

I do constantly. I get all my music that I want to listen to and put it in one place, then don’t have to pay for data? Hell yeah! The unfortunate part of streaming services, for me at least, is I mostly use them to listen to music I don’t even want to bother stealing, let alone buying. So, funnily enough, its mostly hip hop. I love scarlxrd, I’m not buying his albums in flac. A that’d ruin the sound, B he has too many fucking albums.

Same for most hip hop artists I listen to. I always get the whole discography of an artist I like, and hopefully in flac. I can transcode it to what device I need to from there.

I have all the gorillaz albums, sunny day real estate, paramore, and a bunch more. They all have 6-10 albums. Any playlist I add suicideboys to on spotify and just holy fuck its every other song.

I find DeaDBeeF to be suitable for this situation. It’s the closest you are ever going to get to foobar2000.

2 Likes

If you have a Windows machine with lots of power to do this fast I suggest you to use BatchEncoder. I used it to transcode from WAV to MP3 VBR hours and hours of lecture recordings and working with one thread per track really works wonderfully and very fast.

P.S. it’s also dumb easy to use. Drop in the tracks, choose a destination folder, a format and just click start.

This is going to need some work, but this is what I use to convert my music to atrac to burn to my MiniDisc players. Yeah, old school. It relies on your music having the proper name right now.

I never finished plumbing the parts that write the tags to the output since the MD cannot store those anyway. Eventually, I will finish the script that will convert to one format or another and can write to MD based on some flags. Hopefully there is noting in here to dox me.

just work on your bash-fu and you can make this do what it wants. I have some better scripts that actually read a file for flags that I use to convert videos and/or make audio out of the videos but I am at work right now and am not allowed to VPN to my home because gov’t.

#!/bin/bash
#send_to_MiniDisc.sh

netmdcli_NetMD="/home/$USER/Software/code/linux-minidisc/master_-_netmd_fix_fork_vuori_-_01112019/netmdcli/"
netmdcli_HiMD="/home/$USER/Software/code/linux-minidisc/master_-_himd_fix_fork_glaubitz_-_01112019/netmdcli/"
netmdcliOptions="netmdcli -v send"
tempDir="/home/$USER/Music/temp/rip2MD/"
sourceDir="/home/$USER/Music/temp/"
atracEncoder='/home/$USER/Software/code/linux-minidisc/atracdenc_-_master_-_01122019/test/src/atracdenc'
atracVersion="atrac3"
atracOptions="-e"
fileName=""
noExtension=""
fileExtension=""
NetMDVersion="NetMD"
sleepTime=5

SongArtist=""
SongAlbum=""
SongTitle=""
CurrentGroup=""

SongList=""
SourceFormatType=""
CurrentFormatType=""

#FFProbe
FFProbeGetFormatType="ffprobe -v quiet -show_entries stream=codec_name -select_streams a -print_format default=noprint_wrappers=1:nokey=1"

#FFMPEGOptions
FFMPEGInputOptions="-y -hide_banner -v error"
FFMPEGOutputOptions="-filter aresample=44100 -acodec pcm_s16le"


#########Function Definitions################
function getArtist {}
function getAlbum {}
function getTitle {}
function getSongList {}
function getFormatType
{
   "$FFProbeGetFormatType"
}
function setGroup {}
function setFormatType {}
function createSongList {}


#######End Function Definitions##############

#Ask for the source directory.
printf "\nWhich music folder to work from?\n"
read tempString

if [ -d "$tempString" ];then
     sourceDir="$tempString"
else 
     printf "\nNo folder exists at \"$tempString\".\nExiting program.\n\n"
     exit
fi


#Determine if an argument was passed on the command line.
if [ -n "$*" ];then
     #Set file extension and atrac version appropriately.
     for arg in [email protected];do

          if [ "$arg" = "--atrac1" ];then
               atracVersion="atrac1"
               fileExtension="aea"
               atracOptions="$atracOptions $atracVersion"

         elif [ "$arg" = "--atrac3" ];then
               atracVersion="atrac3"
               fileExtension="oma"
               atracOptions="$atracOptions $atracVersion"

	 elif [ "$arg" = "--HiMD" ];then
               NetMDVersion="HiMD"
         fi
     done
fi #End command line argument check

#If no valid command line argument was passed...
if [ -z "$fileExtension" ];then
     #then default to look at the atracVersion variable. Set file extension and atrac version appropriately.
     if [ "$atracVersion" = "atrac1" ];then
          fileExtension="aea"
          atracOptions="$atracOptions $atracVersion"
     elif [ "$atracVersion" = "atrac3" ];then
          fileExtension="oma"
          atracOptions="$atracOptions $atracVersion"
     #If nothig is configured then output mini help.
     else
          echo "\tInvalid configuration.\n\tProper commands are --atrac1 or --atrac3."
          return 1
     fi #End default configuration check
fi #End invalid command line argument check

echo "\tProceeding to rip as $atracVersion, library $NetMDVersion!"


##Setup working directory.
if [ ! -d "$tempDir" ];then
     mkdir -p "$tempDir"
fi


#Pull the artist and the ablum from the file


##Follow the atrac1 sequence
if [ "$atracVersion" = "atrac1" ];then  
     for file in "$sourceDir"/*."mp3" "$sourceDir"/*."ogg" "$sourceDir"/*."m4a" "$sourceDir"/*."wav" "$sourceDir"/*."opus";do

          #Determine if file exists.
          if [ -f "$file" ];then

               #Get the file name minus the absolute path of $file
               fileName="$(echo "$(basename "$file")"| cut -f 1 -d '.')"
	           formatExtension="$(echo "$(basename "$file")"| cut -f 2 -d '.')"

#               echo "\tConverting $file to $tempDir$fileName.$fileExtension ..."
#               $atracEncoder $atracOptions -i "$file" -o "$tempDir$fileName.$atracVersion.$fileExtension" #Can only convert 44.1khz PCM 16bit WAV Files.

               #Perform format conversion to PCM WAV
               echo "\tConverting $file into a WAV file..."
               ffmpeg $FFMPEGInputOptions -i "$file" $FFMPEGOutputOptions "$tempDir$fileName.wav" #FFMPEG seems to have trouble placing atrac1 in WAV. Just convert to PCM for now.

               echo "\tUploading "$fileName".wav to MiniDisc recorder..."
               #Since we are sending PCM WAV, let player convert. Transfer is about 2x (343 kB/s). Works with both forks.
               if [ "$NetMDVersion" = "NetMD" ];then
                    $netmdcli_NetMD$netmdcliOptions "$tempDir$fileName.wav" "$fileName"
                    sleep $sleepTime
               elif [ "$NetMDVersion" = "HiMD" ];then
                    $netmdcli_HiMD$netmdcliOptions "$tempDir$fileName.wav" "$fileName"
                    sleep $sleepTime
               fi
          fi
     done
##Follow atrac3 (MDLP:LP2) sequence
elif [ "$atracVersion" = "atrac3" ];then
     for file in "$sourceDir"/*."mp3" "$sourceDir"/*."ogg" "$sourceDir"/*."m4a" "$sourceDir"/*."wav" "$sourceDir"/*."opus";do

          #Determine if file exists.
          if [ -f "$file" ];then

               #Get the file name minus the absolute path of $file
               fileName="$(echo "$(basename "$file")"| cut -f 1 -d '.')"
	           formatExtension="$(echo "$(basename "$file")"| cut -f 1 -d '.')"

               #Perform format conversion to PCM WAV
               echo "\tConverting $file into a WAV file..."
               ffmpeg $FFMPEGInputOptions -i "$file" $FFMPEGOutputOptions "$tempDir$fileName.wav" #FFMPEG seems to have trouble placing atrac1 in WAV. Just convert to PCM for now.

               #Now encode to LP2 using the atrac encoder
               echo "\tConverting $tempDir$fileName.wav to $tempDir$fileName.$fileExtension ..."
               $atracEncoder $atracOptions -i "$tempDir$fileName.wav" -o "$tempDir$fileName.$fileExtension"
               echo "\tPlacing $tempDir$fileName.$fileExtension into a WAV container..."
               ffmpeg $FFMPEGInputOptions -i "$tempDir$fileName.$fileExtension" -c:a copy "$tempDir$fileName.$fileExtension.wav"

               echo "\tUploading "$tempDir$fileName.$fileExtension.wav" to MiniDisc recorder..."
               #Transfer speed is about 18.25x (295 kB/s). Again this is MDLP2. LP4 is not yet working.
               if [ "$NetMDVersion" = "NetMD" ];then
                    $netmdcli_NetMD$netmdcliOptions "$tempDir$fileName.$fileExtension.wav" "$fileName"
                    sleep $sleepTime
               elif [ "$NetMDVersion" = "HiMD" ];then #This only produces noise when uploading oma/atrac3 files in a WAV container, if it works at all. Use the NetMD fork. 
                    $netmdcli_HiMD$netmdcliOptions "$tempDir$fileName.$fileExtension.wav" "$fileName"
                    sleep $sleepTime
               fi
          fi
     done
fi


#remove the rip2MD directory.
rm -R $tempDir

#Show disc contents
if [ "$NetMDVersion" = "NetMD" ];then
     $netmdcli_NetMDnetmdcli
     sleep 2
elif [ "$NetMDVersion" = "HiMD" ];then
     $netmdcli_HiMDnetmdcli
     sleep 2
fi
1 Like

So is ewerything behind $ a custom variable?

In Windows I use FFmpeg in a for batch loop in cmd.exe.
for /r C:\Users\admin\Desktop\filestotranscode\ %a in (*.wav) do ffmpeg -i -vn -sn -c:a libopus -vbr on -b:a 160k -compression_level 10 -map_metadata 0 -threads 0 “%a” “%~pa%~na.opus”
Creates a 160k opus file.
Just need to change the *.wav for each extension you have.

I assume bash should be able to do something similar.

Mostly.

$arg is a built in bash variable for command line arguments.

$USER is a global *nix variable for the user running the bash script.

$* is bash string manipulation shorthand. Everything else is custom.

I have been getting killed at work and working extra long hours. I will try to upload my other script that looks at Tags directly. Again these are all works in progress to be the respective one script to rule them all, but right now they do what they need to do so I have been lazy to finish them and clean them up.

1 Like

It can. But depending on the version of bash you are using and your bash-fu, it is not as accessible to some.

Maybe I should use bash to ween off the lisp a little and learn how to actually program user applications.

Although question because of above comment.

What about fish