Linux / macOS - Way to encode mp3's from folder to taf file

Hi,
after i gave up to execute teddy with wine or mono i found a way to encode all mp3 files from a directory and encode it to a taf-file.

i created an alias:

mp3_taf() {
    local TMPFILE=$(mktemp -p /tmp)

    mkdir -p ${HOME}/tmp/teddycloud/data/content
    mkdir -p ${HOME}/tmp/teddycloud/data/library
    mkdir -p ${HOME}/tmp/teddycloud/certs/server
    mkdir -p ${HOME}/tmp/teddycloud/certs/client
    mkdir -p ${HOME}/tmp/teddycloud/config
    # LIST=`python -c 'import glob; print("|".join(sorted(glob.glob("*.mp3"))))'`
    # ffmpeg -i "concat:${LIST}" -acodec copy ${TMPFILE}
    # find . -maxdepth 1 -iname '*.mp3' -print0 | sort -z | xargs -0 mp3wrap ${TMPFILE}
    # cat *.mp3 ${TMPFILE}
    find . -name "*.mp3" -type f -exec cat {} >> ${TMPFILE} \; 
    docker run --rm \
        -v /tmp:/tmp:ro \
        -v "${PWD}:/app" \
        -v "${HOME}/tmp/teddycloud/data/content:/teddycloud/data/content" \
        -v "${HOME}/tmp/teddycloud/data/library:/teddycloud/data/library" \
        -v "${HOME}/tmp/teddycloud/data/firmware:/teddycloud/data/firmware" \
        -v "${HOME}/tmp/teddycloud/certs:/teddycloud/certs" \
        -v "${HOME}/tmp/teddycloud/config:/teddycloud/config" \
        --workdir /teddycloud \
        --entrypoint teddycloud \
        ghcr.io/toniebox-reverse-engineering/teddycloud:latest \
        ENCODE ${TMPFILE} /app/500304E0

        rm -f ${TMPFILE}
}

just execute the alias in the related directory with your mp3’s and upload taf file via teddycloud.

Unfortunately, the certificates are recreated every time the container is started, so I had to create the volumes to store them

This is confusing. Why would you need stable certificates for the encoding of the audio?

Oh, and https://github.com/bailli/opus2tonie/blob/main/opus2tonie.py works just fine afaict.

I also wanted to just create the Opus file and manage the folders and IDs on my microSD card by myself.
And the most comfortable way for me, using a MacBook with macOS, was a quick action I can fire directly on a folder in Finder. So I used Automator and the Python script linked here: https://github.com/bailli/opus2tonie

Since Python is not the language of my choice, the setup was a little fiddly.
At first you need to add a Python environment, install protobuf and ffmpeg, and maybe other missing libs too. It took me forever.

Then update your tonie_header_pb2.py with the new one given by SciLor in this issue: https://github.com/bailli/opus2tonie/issues/11

For the main Python script I created another optional argument ‘–save-in-source-folder’, add it after line 1027:

parser.add_argument('--save-in-source-folder', action='store_true', help='Saves the file directly in the given source folder with filename 500304E0')

And the handling of the new argument some lines underneath:

if args.save_in_source_folder:
    out_filename = os.path.join(args.input_filename, "500304E0")

If you start the script from the quick action menu (with the new argument) like in the screenshot below, it creates the opus file directly in the folder.

For setting up the quick action, start Automator and create a new workflow which runs a shell script. The input is a folder in Finder and hte content of the shell-script is (see screenshot below):

export PATH=/opt/homebrew/bin:$PATH

source /Users/YOURUSER/Toniebox/opus2tonie-main/venv/bin/activate

python3 /Users/YOURUSER/Toniebox/opus2tonie-main/opus2tonie.py --save-in-source-folder "$@" > /Users/YOURUSER/Toniebox/opus2tonie-main/log.txt 2>&1

And this is all the magic.
I guess the setup is probably not perfekt, but it works for me.
But if you encounter any problems, I might not help, sorry.

Cause he uses the teddycloud image for doing his conversation:
See his code here:

docker run --rm

ghcr.io/toniebox-reverse-engineering/teddycloud:latest
ENCODE ${TMPFILE} /app/500304E0

Hey @ingorichter - thanks four your guide. I just reproduced it on my Mac.

But what I don’t really get is why the filename should be fix 500304E0? Is this something outdated? Why shouldn’t I use the same filename as the input file but with .taf at the end?

I wanted to skip TeddyBench tool.
It converts the given sound file(s) (MP3 or whatever) to an Opus file , creates a new folder from the given NFC-tag name (in reverse) and copies the Opus file named as 500304E0 into that folder (onto SD card used in the Toniebox).
Also the original OPUS files are named like that.

I do not know if another file name works too for the Toniebox.

I see. I never used Teddybench and don’t really know the details there.

I’m using Teddycloud which accepts all kinds of filenames. It even has a built-in Audio Encoder in the Frontend. But unfortunately it takes ages to convert a file this way. That’s why I was looking for an alternative.

I just adapted the Python script and the Automator Action so that I can now either choose a directory or a single file in Finder. If I select a directory, all containing files will be merged into a single taf file and the name of this file will be the name of the selected directory. If I choose a single file, the result has the same file name but with taf file extension instead of mp3/m4a/etc.

My Automator/Shell-Script now looks like this:

export PATH=/opt/homebrew/bin:$PATH

source /Users/marco/.venv/bin/activate

if [ -f "$@" ]; then 
	python3 /Users/marco/dev/toniebox/opus2tonie/opus2tonie.py "$@" "${@%.*}.taf" > /Users/marco/dev/toniebox/opus2tonie/log.txt 2>&1
elif [ -d "$@" ]; then
	python3 /Users/marco/dev/toniebox/opus2tonie/opus2tonie.py --convert_dir_to_single_file "$@" > /Users/marco/dev/toniebox/opus2tonie/log.txt 2>&1
fi

And in opus2tonie.py I added this line right after the args parsing:

if args.convert_dir_to_single_file:
    base = os.path.splitext(args.input_filename)[0]
    out_filename = base + ".taf"

Conversion time comparison for an audiobook (73 minutes playtime):
Browser-Encoder (Raspberry Pi 4): 7m8s
Opus-2-Tonie Script (MacBook Pro M1): 41s

I think I’ll write instructions on how to set it up completely (homebrew, python, ffmpeg, google-api etc.)

I extended the Automator action to upload the converted taf file to the Teddycloud at the end. Furthermore it now also shows a native macOS notification if it succeeded or not:

if curl -F "file=@$OUTPUT_FILE" "http://$TEDDYCLOUD_IP/api/fileUpload?path=&special=library"; then
	osascript -e "display notification \"Die Datei $BASE_NAME befindet sich jetzt in deiner Teddycloud\" with title \"Upload erfolgreich\"" & 
else
	osascript -e 'display notification "Etwas ist schief gelaufen mit deinem Datei-Upload. Bitte überprüfe die Logs." with title "Teddycloud Fehler"'
fi

So now this is a single click solution and at the end the converted file is in the Teddycloud library, ready to be assigned to a Tonie (which could also be automated by the way :slight_smile: ).