Skip to main content

Topic: Linux Audio Conversion Script Terminal Based (Read 1143 times) previous topic - next topic

0 Members and 2 Guests are viewing this topic.
  • wozbit
  • [*]
Linux Audio Conversion Script Terminal Based
At the moment i'm using a mish mash of messy audio conversion scripts (found on github) to convert audio into different formats. I have a master FLAC collection and convert into different formats for different devices, ie. mp3, opus, ogg, aac  etc. My requirements are to keep the exact same directory structure, id tags, etc as the master collection and output them into required format. Does anybody know of a single script / tool what can do this what is terminal based and works on linux?
  • Last Edit: 30 October, 2017, 12:27:30 PM by wozbit

  • smok3
  • [*][*][*][*][*]
  • Moderator
Re: Linux Audio Conversion Script Terminal Based
Reply #1
wozbit: If you have a good idea how would you construct it (Especially the part that looks and reacts to dir/subdir changes) and it's bash I may give it a try.
PANIC: CPU 1: Cache Error (unrecoverable - dcache data) Eframe = 0x90000000208cf3b8
NOTICE - cpu 0 didn't dump TLB, may be hung

  • wozbit
  • [*]
Re: Linux Audio Conversion Script Terminal Based
Reply #2
The closest i've found is https://sourceforge.net/projects/audenc/  but i cannot get it to work..

Would be nice if the script could detect changed files and only convert what is new etc I'm suprised there is hardly anything out there what is up to the job. A good idea for a new github project!


  • Deathcrow
  • [*]
Re: Linux Audio Conversion Script Terminal Based
Reply #3
This is the uncool non-nerdy answer, but foobar2000 works pretty well in wine and can do this. A while ago I wanted to do something similar (especially with preservering the directory structure) and fb2k was just easiest. Though it should be doable as a python/bash script with ffmpeg too. Just needs more effort.

  • smok3
  • [*][*][*][*][*]
  • Moderator
Re: Linux Audio Conversion Script Terminal Based
Reply #4
A try at a simple unidirectional model for two dirs (With some help from freenode #bash). It basically loops over every found flac and checks if ogg is there in the 2nd folder, if not makes one. Also if ogg mtime is older, makes a new ogg. Just a model, didn't bother with actual encoding code so far.
http://paste.debian.net/plain/993464

To test:
Code: [Select]
mkdir -p ~/tmp/test/one
cd ~/tmp/test/one
touch a.flac b.flac c.flac
# run 'test' script
./test
basext = a.flac, base = a, dir = .
/home/b/tmp/test/two/./a.ogg ... making one
encoding ...
basext = b.flac, base = b, dir = .
/home/b/tmp/test/two/./b.ogg ... making one
encoding ...
basext = c.flac, base = c, dir = .
/home/b/tmp/test/two/./c.ogg ... making one
encoding .

touch one/a.flac

./test
basext = a.flac, base = a, dir = .
/home/b/tmp/test/two/./a.ogg ... is older, making new one
encoding ...
basext = b.flac, base = b, dir = .
/home/b/tmp/test/two/./b.ogg ... already there
basext = c.flac, base = c, dir = .
/home/b/tmp/test/two/./c.ogg ... already there

tree
.
├── one
│   ├── a.flac
│   ├── b.flac
│   └── c.flac
├── test
└── two
    ├── a.ogg
    ├── b.ogg
    └── c.ogg



Probably needs some additional sanity checking, but after that should be easily expandable to multiple destinations/encoders. p.s. Actually I'd probably do multiple scripts, each for one encoder.

edit: and bash parallel version of the same
http://paste.debian.net/plain/993697
  • Last Edit: 01 November, 2017, 05:38:54 AM by smok3
PANIC: CPU 1: Cache Error (unrecoverable - dcache data) Eframe = 0x90000000208cf3b8
NOTICE - cpu 0 didn't dump TLB, may be hung

  • finphil
  • [*]
Re: Linux Audio Conversion Script Terminal Based
Reply #5
To my knowledge, the closest tool to the OP's request is this:

https://sourceforge.net/projects/pacpl/

Not using it myself  but worthy of investigation?

Re: Linux Audio Conversion Script Terminal Based
Reply #6
To my knowledge, the closest tool to the OP's request is this:

https://sourceforge.net/projects/pacpl/

Not using it myself  but worthy of investigation?
It does exactly what is needed. I used it to convert my audio files to MP3 for portable listening.  Input from one tree, output to another of same structure.

pacpl manual page
The most important audio cables are the ones in the brain

  • lothario15
  • [*][*]
Re: Linux Audio Conversion Script Terminal Based
Reply #7
I've just re-encoded a large FLAC library to 128kbps Opus with this one-liner:
Code: [Select]
find * -type f -name \*.flac -exec dirname {} \; | sort -u | while read d; do echo "$d" && mkdir -p "$HOME/Music_portable/${d}" && ls "$d"/*.flac | parallel 'opusenc --quiet --bitrate 128 {} "$HOME"/Music_portable/"${d}"/{.}.opus'; done
It uses the 'find' command to recursively locate directories containing FLAC files and creates a mirror of the directory tree.  It echoes the directory name to give the user an idea of progress.  It then uses GNU parallel (https://www.gnu.org/software/parallel/) to utilise multiple processor cores when transcoding.

Edit the output directory and the encoder preference then simply navigate your terminal to the parent directory of your FLAC library.  Paste the command and hit enter.  You could edit the command to output to four different formats in four different destinations, if your processor is up to it.

And it needn't take much to throw this into a script where 'find' checks for modification times and/or newly-created FLAC files.  Since the default behaviour for some encoders is to overwrite without prompting, the script could be added as a cron or anacron job so that it would periodically update your lossy library with zero user intervention.

  • smok3
  • [*][*][*][*][*]
  • Moderator
Re: Linux Audio Conversion Script Terminal Based
Reply #8
lothario15: thats pretty cool, thanks for sharing. (I can see two points that could make trouble, sort and ls).
PANIC: CPU 1: Cache Error (unrecoverable - dcache data) Eframe = 0x90000000208cf3b8
NOTICE - cpu 0 didn't dump TLB, may be hung

Re: Linux Audio Conversion Script Terminal Based
Reply #9
I've just re-encoded a large FLAC library to 128kbps Opus with this one-liner:
Code: [Select]
find * -type f -name \*.flac -exec dirname {} \; | sort -u | while read d; do echo "$d" && mkdir -p "$HOME/Music_portable/${d}" && ls "$d"/*.flac | parallel 'opusenc --quiet --bitrate 128 {} "$HOME"/Music_portable/"${d}"/{.}.opus'; done
That's a helluva line of code.

Gonna keep it on Google Keep for whenever it comes in handy.

Thank you!
Listen to the music, not the media.

  • wozbit
  • [*]
Re: Linux Audio Conversion Script Terminal Based
Reply #10
wow, nice one-liner. Have to figure out a way for it to detect changed files.

  • wozbit
  • [*]
Re: Linux Audio Conversion Script Terminal Based
Reply #11
I found this script on github, modified it slightly, also created version for fdk-aac.

Tested with fdkaac 0.6.3 and opusenc opus-tools 0.1.9 (using libopus 1.1.5)

* Keeps directory structure
* Copies metadata
* Detects changed files
* Uses parallel

flac2opus.sh

Code: [Select]
#!/bin/bash

export BITRATE=64

function usage
{
        echo
        echo "Usage:"
        echo "    $0 FLAC_DIR LOSSY_DIR"
}

function encode
{
        if [ ! -f "$LOSSY_DIR"/"$(echo "$1" | sed 's/.flac/.opus/')" ]; then
                ARTIST=`metaflac "$FLAC_DIR"/"$1" --show-tag=ARTIST | sed s/.*=//`
                TITLE=`metaflac "$FLAC_DIR"/"$1" --show-tag=TITLE | sed s/.*=//g`
                ALBUM=`metaflac "$FLAC_DIR"/"$1" --show-tag=ALBUM | sed s/.*=//g`
                TRACKNUMBER=`metaflac "$FLAC_DIR"/"$1" --show-tag=TRACKNUMBER | sed s/.*=//g`
                DISCNUMBER=`metaflac "$FLAC_DIR"/"$1" --show-tag=DISCNUMBER | sed s/.*=//g`

                echo "encoding $1"
                flac -s -c -d "$FLAC_DIR"/"$1" | opusenc --quiet --bitrate "$BITRATE" --artist "$ARTIST" --album "$ALBUM" \
                        --title "$TITLE" --comment "TRACKNUMBER=$TRACKNUMBER" --comment "DISCNUMBER=$DISCNUMBER" \
                        - "$LOSSY_DIR"/"$(echo "$1" | sed 's/\.flac$/\.opus/')"
        fi
}
export -f encode

#If user didn't provide 2 arguments, quit.
if [ "$#" -ne 2 ]; then
        usage
        exit
fi

export FLAC_DIR="$1"
export LOSSY_DIR="$2"

#If first argument isn't a directory, quit.
if [ ! -d "$FLAC_DIR" ]; then
        usage
        exit
fi

#if LOSSY_DIR doesn't exist, create it
if [ ! -d "$LOSSY_DIR" ]; then
        mkdir "$LOSSY_DIR"
fi

#recreate the folder structure in lossy
echo "Creating the folder structure."
diff --new-line-format="" --unchanged-line-format="" \
  <(find "$FLAC_DIR" -mindepth 1 -maxdepth 3 -type d -printf '%P\n' | sort) \
  <(find "$LOSSY_DIR" -mindepth 1 -maxdepth 3 -type d -printf '%P\n' | sort) |while read fname; do
        mkdir -v -p "$LOSSY_DIR/$fname"
done

echo "Encoding missing songs."
diff --new-line-format="" --unchanged-line-format="" \
  <(find "$FLAC_DIR" -mindepth 1 -name \*.flac -printf '%P\n' | sort) \
  <(find "$LOSSY_DIR" -mindepth 1 -name \*.opus -printf '%P\n' | sed 's/\.opus$/\.flac/g' | sort) \
  | parallel --no-notice encode


flac2aac.sh

Code: [Select]
#!/bin/bash

export FDKAAC_PROFILE=5
export FDKAAC_BITRATE_MODE=2

function usage
{
        echo
        echo "Usage:"
        echo "    $0 FLAC_DIR LOSSY_DIR"
}

function encode
{
        if [ ! -f "$LOSSY_DIR"/"$(echo "$1" | sed 's/.flac/.m4a/')" ]; then
                ARTIST=`metaflac "$FLAC_DIR"/"$1" --show-tag=ARTIST | sed s/.*=//`
                TITLE=`metaflac "$FLAC_DIR"/"$1" --show-tag=TITLE | sed s/.*=//g`
                ALBUM=`metaflac "$FLAC_DIR"/"$1" --show-tag=ALBUM | sed s/.*=//g`
                TRACKNUMBER=`metaflac "$FLAC_DIR"/"$1" --show-tag=TRACKNUMBER | sed s/.*=//g`
                DISCNUMBER=`metaflac "$FLAC_DIR"/"$1" --show-tag=DISCNUMBER | sed s/.*=//g`

                echo "encoding $1"
                flac -s -c -d "$FLAC_DIR"/"$1" | fdkaac -S -p "$FDKAAC_PROFILE" -m "$FDKAAC_BITRATE_MODE" --artist "$ARTIST" --album "$ALBUM" \
                        --title "$TITLE" --comment "TRACKNUMBER=$TRACKNUMBER" --comment "DISCNUMBER=$DISCNUMBER" \
                        - -o "$LOSSY_DIR"/"$(echo "$1" | sed 's/\.flac$/\.m4a/')"
        fi
}
export -f encode

#If user didn't provide 2 arguments, quit.
if [ "$#" -ne 2 ]; then
        usage
        exit
fi

export FLAC_DIR="$1"
export LOSSY_DIR="$2"

#If first argument isn't a directory, quit.
if [ ! -d "$FLAC_DIR" ]; then
        usage
        exit
fi

#if LOSSY_DIR doesn't exist, create it
if [ ! -d "$LOSSY_DIR" ]; then
        mkdir "$LOSSY_DIR"
fi

#recreate the folder structure in lossy
echo "Creating the folder structure."
diff --new-line-format="" --unchanged-line-format="" \
  <(find "$FLAC_DIR" -mindepth 1 -maxdepth 3 -type d -printf '%P\n' | sort) \
  <(find "$LOSSY_DIR" -mindepth 1 -maxdepth 3 -type d -printf '%P\n' | sort) |while read fname; do
        mkdir -v -p "$LOSSY_DIR/$fname"
done

echo "Encoding missing songs."
diff --new-line-format="" --unchanged-line-format="" \
  <(find "$FLAC_DIR" -mindepth 1 -name \*.flac -printf '%P\n' | sort) \
  <(find "$LOSSY_DIR" -mindepth 1 -name \*.m4a -printf '%P\n' | sed 's/\.m4a$/\.flac/g' | sort) \
  | parallel --no-notice encode


  • lothario15
  • [*][*]
Re: Linux Audio Conversion Script Terminal Based
Reply #12
No problem.  Hope it's useful.  You need to install parallel from the repositories beforehand since it has a citation notice that needs to be agreed first by typing:
Code: [Select]
parallel --bibtex
After doing that once, you're good to go.

The command worked flawlessly with my FLAC library.  I added the sort and echo commands to give me an indication of progress.  Since find doesn't necessarily sort alphanumerically, the sort -u orders every unique directory.  I started encoding in the evening with 2pac; by the morning I saw that it had reached Radiohead so didn't have too long to go until it finished.


Smok3, I know it's generally bad practice to use the output of ls but parallel doesn't seem to mind how it's fed.  That said, I'm no expert and I'm always looking to improve my terminal-fu so let me know what problems you foresee using sort and ls in this command.  Thanks.

Wozbit, here's a start on using find to detect file modification timestamps:
https://stackoverflow.com/questions/5566310/how-to-recursively-find-and-list-the-latest-modified-files-in-a-directory-with-s

  • smok3
  • [*][*][*][*][*]
  • Moderator
Re: Linux Audio Conversion Script Terminal Based
Reply #13
@lothario15, Nothing specific, but I wonder if there is an equally nice onliner without ls.
@wozbit, you sure it will detect changed flacs or just new flacs?
  • Last Edit: 01 November, 2017, 11:56:42 AM by smok3
PANIC: CPU 1: Cache Error (unrecoverable - dcache data) Eframe = 0x90000000208cf3b8
NOTICE - cpu 0 didn't dump TLB, may be hung

  • wozbit
  • [*]
Re: Linux Audio Conversion Script Terminal Based
Reply #14
i will see if i can use a diff option so it detects modified files
  • Last Edit: 01 November, 2017, 01:07:26 PM by wozbit

  • smok3
  • [*][*][*][*][*]
  • Moderator
Re: Linux Audio Conversion Script Terminal Based
Reply #15
Tought one with the script you posted.
PANIC: CPU 1: Cache Error (unrecoverable - dcache data) Eframe = 0x90000000208cf3b8
NOTICE - cpu 0 didn't dump TLB, may be hung

  • finphil
  • [*]
Re: Linux Audio Conversion Script Terminal Based
Reply #16
Wozbit, was the script you found on github this one?

https://github.com/SimonPersson/flac2opus

I've been using this successfully for a while. I just checked - it does detect and encode new files. Also it re-encodes where the filename or tags are different from the existing opus file.

  • yourlord
  • [*][*][*][*]
Re: Linux Audio Conversion Script Terminal Based
Reply #17
Or look into Caudec which was developed by one of our members.

  • wozbit
  • [*]
Re: Linux Audio Conversion Script Terminal Based
Reply #18
Wozbit, was the script you found on github this one?

https://github.com/SimonPersson/flac2opus

I've been using this successfully for a while. I just checked - it does detect and encode new files. Also it re-encodes where the filename or tags are different from the existing opus file.

Yes thats the script!

  • abajaj11
  • [*]
Re: Linux Audio Conversion Script Terminal Based
Reply #19
At the moment i'm using a mish mash of messy audio conversion scripts (found on github) to convert audio into different formats. I have a master FLAC collection and convert into different formats for different devices, ie. mp3, opus, ogg, aac  etc. My requirements are to keep the exact same directory structure, id tags, etc as the master collection and output them into required format. Does anybody know of a single script / tool what can do this what is terminal based and works on linux?
I wrote this for use on my linux mint box. Works great. Converts my entire flac tree to mp3. I have a similar one for wav, though anyone should be able to modify this one to do wav.
_______________
#!/bin/bash
    #####################################
    if [ -z $1 ];then echo Give target directory such as . ; exit 0;fi
    find "$1" -depth -name '*' | while read file ; do
    directory=$(dirname "$file")
    oldfilename=$(basename "$file")
    newfilename=$(basename "${file%.[Ff][Ll][Aa][Cc]}")
    if [ "$oldfilename" != "$newfilename" ]; then
    ffmpeg -i "$directory/$oldfilename" -ab 320k "$directory/$newfilename.mp3" </dev/null
    rm "$directory/$oldfilename"
    fi
    done
   
    #replace all flac occurences with mp3 within filenames
    find . -depth -name '*flac*' -execdir bash -c 'for f; do mv -i "$f" "${f//flac/mp3}"; done' bash {} +
    # replace flac with mp3 WITHIN all .m3u files
    find . -name "*.m3u" -exec sed -i 's/flac/mp3/g' {} +
____________________________________________
:)