Hey y'all! I made a bash sync script for the Tangara!
What it assumes:
* you are running linux
* You have a single source folder containing all your music files
* You want that single library folder structure to be mirrored on your tangara
* You have ffmpeg installed and accessible on your PATH
* you have read access to your music library
* You too struggled to get https://github.com/complexlogic/EasyAudioSync running on your system
What it does:
* Converts incompatible aac/alac files
* Handles embedded and folder-local cover files
* lets you choose your target audio settings
* Lets you choose if you want to compress lossless audio to save space
* lets you choose which categories of lossy files you want converted
What it doesn't do:
* Anything other than music. Playlists don't work either.
* Delete things.
* It doesn't update your tangara if you remove an album from your library
* It does its best to never overwrite any existing files (But no promises! Backups are YOUR job!)
Running the script:
Step 1:
Check for ffmpeg in your path:
[*]
Step 2:
Copy your music library to a folder the script has read permission in!
Step 3:
Make a new folder somewhere the script has write permissions in.
Step 4:
Paste this code into an empty shell script file.
Step 5:
Edit the first two variables to match the locations of your duplicate music library and your new writable folder.
Step 6:
Run the script and watch it go!
Step 7:
Rsync the destination folder contents to your tangara sd card.
Step 8:
Rerun the script whenever you have new music to add!
I consider this to be version 1.0. Its feature complete (for now) but bug testing is only mildly been done!
What it assumes:
* you are running linux
* You have a single source folder containing all your music files
* You want that single library folder structure to be mirrored on your tangara
* You have ffmpeg installed and accessible on your PATH
* you have read access to your music library
* You too struggled to get https://github.com/complexlogic/EasyAudioSync running on your system
What it does:
* Converts incompatible aac/alac files
* Handles embedded and folder-local cover files
* lets you choose your target audio settings
* Lets you choose if you want to compress lossless audio to save space
* lets you choose which categories of lossy files you want converted
What it doesn't do:
* Anything other than music. Playlists don't work either.
* Delete things.
* It doesn't update your tangara if you remove an album from your library
* It does its best to never overwrite any existing files (But no promises! Backups are YOUR job!)
Running the script:
Step 1:
Check for ffmpeg in your path:
Code:
ffmpeg -version
Step 2:
Copy your music library to a folder the script has read permission in!
Step 3:
Make a new folder somewhere the script has write permissions in.
Step 4:
Paste this code into an empty shell script file.
Code:
#!/bin/bash
#First two variables are the only ones you are required to adjust
#recommend using a copy of your library and sending to another folder (and not the tangara card)
#then just do rsync --progress source dest
#IF YOU LOSE DATA IT'S YOUR OWN FAULT FOR NOT BACKING THINGS UP
#that said, this is deigned to allow for reruns to sync any new music files it finds without overwriting
#any existing data at target directory
#source and destination folders
library="/home/dageek247/Music Copy"
tangara="/home/dageek247/tangaraMusic"
#Options are copy or convert
#copy keeps lossless files as is
#convert converts all lossless files to target settings to save space
reincodelossless=copy
#choose to reincode lossy audio; turn on for uniformity.
#aac and alac will be reencoded regardless of this setting.
reincodelossy=false
#choose what to do with unknown audio formats
#unkown audio is all audio files that ffmpeg can read, but is not listed at
#https://cooltech.zone/tangara/docs/music-library/#supported-audio-formats
reincodeunknowncodecs=true
#this script can handle album art for the tangara
#it grabs whatever cover art it can find and then downsizes it to fit the tangara screen
#capable of using embedded cover art, no problem.
grabalbumart=true
#format to convert to whenever conversion is required
#this will be run on any aac and alac audio
targetcodec=libopus
targetextension=ogg
#use kbps for this option
targetquality=256k
#main script loop, iterate through every file in source library and run commands depnding on prior settings
#IFS command keeps the find command as one string instead of splitting strings delimitted by spaces
IFS=$'\n'
#run file operations in temp directory
mkdir temp
cd temp
#loop through all the files in the source library
for file in $(find $library); do
filename=$(basename -a $file)
cutfilename=${filename%.*}
filestruct="${file#$library}"
cutfilestruct=${filestruct%.*}
cutfolderstruct=${filestruct%/*}
#echo "Current Working File: $filestruct"
#ensure folder structure matches source library
if [ -d $file ] ; then #if file is folder
if [ -d "$tangara$filestruct" ] ; then #if folder exists in target library
:
else #if folder does not exist in target library
#create folder in target directory
mkdir -p "$tangara$filestruct"
fi
elif [ -f $file ] ; then
#file is file
#only do very slow ffprobe task if the possible target files don't exist
if [ -f $tangara$cutfilestruct.$targetextension ] ; then
echo "$cutfilestruct.$targetextension already exists on target directory! Skipping."
continue
elif [ -f $tangara$filestruct ] ; then
echo "$filestruct already exists on target directory! Skipping."
continue
else
ffproberesults=$(ffprobe $file 2>&1)
#copy the current working file to the current directory
cp -f $library$filestruct $filename
fi
#check codec of file
filecodec=na
filecodectype=na
#obtain current working file codec
if [[ $(echo $ffproberesults | grep -w "Audio: aac") ]] ; then
filecodec=aac
filecodectype=lossy
elif [[ $(echo $ffproberesults | grep -w "Audio: alac") ]] ; then
filecodec=alac
filecodectype=lossy
elif [[ $(echo $ffproberesults | grep -w "Audio: flac") ]] ; then
filecodec=flac
filecodectype=lossless
elif [[ $(echo $ffproberesults | grep -w "Audio: wav") ]] ; then
filecodec=wav
filecodectype=lossless
elif [[ $(echo $ffproberesults | grep -w "Audio: mp3") ]] ; then
filecodec=mp3
filecodectype=lossy
elif [[ $(echo $ffproberesults | grep -w "Audio: vorbus") ]] ; then
filecodec=vorbus
filecodectype=lossy
elif [[ $(echo $ffproberesults | grep -w "Audio: opus") ]] ; then
filecodec=opus
filecodectype=lossy
elif [[ $(echo $ffproberesults | grep -w "Audio: ") ]] ; then
filecodec=unk
filecodectype=lossy
fi
#handle cover.jpg
#check if we want to send a cover.jpg to the target library
if [ $grabalbumart = true ] ; then
if [ -f $tangara$cutfolderstruct/cover.jpg ] ; then
#do nothing because we already have a cover.jpg at the target location
:
else
#Check if this file is a cover.jpg equivalent and sync it to the tangara.
if [[ $cutfilename == "cover" || $cutfilename == "folder" ]] ; then
#attempt to compress it to fit the tangara screen size while keeping source ratio
ffmpeg -y -hide_banner -loglevel error -i $filename -qscale:v 2 -vf "scale='if(gt(iw,ih),160,-1)':'if(gt(iw,ih),-1,128)" cover.jpg
mv -u cover.jpg $tangara$cutfolderstruct/cover.jpg
#ensure file is some sort of music file before running this
elif [[ $filecodectype == "lossless" || $filecodectype == "lossy" ]] ; then
#check for embedded art prior to converting
if [[ $(echo $ffproberesults | grep -w "Video: ") ]] ; then
ffmpeg -y -hide_banner -loglevel error -i $filename -qscale:v 2 -vf "scale='if(gt(iw,ih),160,-1)':'if(gt(iw,ih),-1,128)" cover.jpg
mv -u cover.jpg $tangara$cutfolderstruct/cover.jpg
fi
fi
fi
fi
#choose what to do with the file
if [[ $filecodectype == "lossless" ]] ; then
#First check to see if an encoded or copy version already exists on target library
if [ -f $tangara$cutfilestruct.$targetextension ] ; then
echo "$cutfilestruct.$targetextension already exists on target directory! Skipping."
elif [ -f $tangara$filestruct ] ; then
echo "$filestruct already exists on target directory! Skipping."
else
if [[ $reincodelossless == "limit" ]] ; then
echo "we can't do the limit option just yet"
elif [[ $reincodelossless == "copy" ]] ; then
#safely copy the file to the tangara device without overwriting existing files
echo "Copying lossless audio file $filename over to $tangara$filestruct"
mv -u $filename $tangara$filestruct
elif [[ $reincodelossless == "convert" ]] ; then
echo "Converting $filename to $cutfilestruct.$targetextension"
ffmpeg -n -hide_banner -loglevel error -i $filename -map 0:a -c:a $targetcodec -b:a $targetquality $cutfilename.$targetextension
echo "Copying $cutfilestruct.$targetextension over to $tangara$cutfilestruct"
mv -u $cutfilename.$targetextension $tangara$cutfilestruct.$targetextension
fi
fi
elif [[ $filecodectype == "lossy" ]] ; then
#start with unspported codecs which will always be converted
if [[ $filecodec == "aac" || $filecodec == "alac" ]] ; then
if [ -f $tangara$cutfilestruct.$targetextension ] ; then
echo "$tangara$cutfilestruct.$targetextension already exists. Skipping."
else
echo "Converting $filename to $cutfilestruct.$targetextension"
ffmpeg -n -hide_banner -loglevel error -i $filename -map 0:a -c:a $targetcodec -b:a $targetquality $cutfilename.$targetextension
echo "Copying $cutfilestruct.$targetextension over to $tangara$cutfilestruct"
mv -u $cutfilename.$targetextension $tangara$cutfilestruct.$targetextension
fi
#move to supported lossy codecs
elif [[ $filecodec == "mp3" || $filecodec == "opus" || $filecodec == "vorbis" ]] ; then
#echo "$filename is a lossy file. Convert Target result is $tangara$filestruct"
if [ $reincodelossy = false ] ; then
#verify if a copied file version exists
if [ -f $tangara$filestruct ] ; then
echo "$filestruct already exists. Skipping."
else
#safely copy the lossy file over to the tangara device.
echo "Copying lossy audio file $filename over to $tangara$filestruct"
mv -u $filename $tangara$filestruct
fi
elif [ $reincodelossy = true ] ; then
#verify if a converted file version exists
if [ -f $tangara$cutfilestruct.$targetextension ] ; then
echo "$cutfilestruct.$targetextension already exists. Skipping."
else
echo "Converting $filename to $cutfilestruct.$targetextension"
ffmpeg -n -hide_banner -loglevel error -i $filename -map 0:a -c:a $targetcodec -b:a $targetquality $cutfilename.$targetextension
echo "Copying $cutfilestruct.$targetextension over to $tangara$cutfilestruct"
mv -u $cutfilename.$targetextension $tangara$cutfilestruct.$targetextension
fi
fi
#handle unknown but still audio codecs
elif [[ $filecodec == "unk" ]] ; then
if [ reincodeunknowncodecs = true ] ; then
#verify if a converted file version exists
if [ -f $tangara$cutfilestruct.$targetextension ] ; then
echo "$cutfilestruct.$targetextension already exists. Skipping."
else
echo "Converting $filename to $cutfilestruct.$targetextension"
ffmpeg -n -hide_banner -loglevel error -i $filename -map 0:a -c:a $targetcodec -b:a $targetquality $cutfilename.$targetextension
echo "Copying $cutfilestruct.$targetextension over to $tangara$cutfilestruct"
mv -u $cutfilename.$targetextension $tangara$cutfilestruct.$targetextension
fi
else
#safely copy the unknown audio file over to the tangara device.
mv -u $filename $tangara$filestruct
fi
fi
fi
fi
done
#temp directory cleanup
cd ..
rm -rf temp
Step 5:
Edit the first two variables to match the locations of your duplicate music library and your new writable folder.
Step 6:
Run the script and watch it go!
Step 7:
Rsync the destination folder contents to your tangara sd card.
Code:
rsync --progress "/home/dageek247/tangaraMusic" "/media/SDCard01/Music"
Step 8:
Rerun the script whenever you have new music to add!
I consider this to be version 1.0. Its feature complete (for now) but bug testing is only mildly been done!