Enhance Download TAFs as OGG #207
Until now only the whole OGG can be downloaded. OliKo and baili created both nice codes snippets to convert the TAF File directly to an mp3 with chapters. "i want to share my script, which automaticaly converts all TAFs from TeddyCloud library to fully tagged MP3 albums."
Features The script converts only new TAFs. → Already converted are skipped. Full ID3v2.3 tag information parsed from latest ‘tonies.json’. What it does?
Download latest ‘tonies.json’ for ID3v2.3 tag information. Process all TAFs from SOURCE directory. Download cover image, crop, square, resize and add boarder. Parse ‘tonies.json’ for full ID3v2.3 tag information Performer Album Track name (from tonies.json if present!) TrackNr./TrackTotal Disc/DiscTotal Genre Comment includes Model Cover (front) Convert to single or SPLIT mp3 file. Default is split mode. Check for already converted TAFs How to use it?
Create new file and copy code. Grant file execution permissions Adjust the follwoing variables to your setup: SOURCE → TeddyCloud library directory, e.g. “/teddycloud/library/by/audioID/” TARGET → directory of your choise, e.g. “/home/user/export/” OPUS2TONIE → path to Opus2Tonie 26 python script which is used to extract the AudioID from TAF TMP → local temp folter to process data. Will be deleted afterwards. Prerequisites
jq to parse JSON data on bash ffmpeg to convert TAF to mp3 and add cover imagemagic to process image for perfect fit Opus2Tonie 26 must be downloaded. It requires Python3 Opus2Tonie requires python3-protobuf to decoce protobuf. please install it via pip and/or apt Bash script
./_convert.sh
#!/bin/bash
VERSION=1.1
FORCE=0
SPLIT=1
TEST=0
OPUS2TONIE="/srv/Transfer/TAF_CONVERTER/opus2tonie-main/opus2tonie.py"
SOURCE="/teddycloud/library/by/audioID/"
TARGET="/srv/Transfer/TAF_CONVERTER/Target/"
TMP="./.tmp"
TONIES_JSON_URL="https://raw.githubusercontent.com/toniebox-reverse-engineering/tonies-json/release/tonies.json"
TONIES_JSON="tonies.json"
echo
echo -e "\e[1mAutomated TAF to MP3 converter v$VERSION\e[0m"
echo
usage()
{
echo "Usage: ${0##*/} [-h] [-t] [-f] [-s]"
echo
echo " -t Test Mode. Do not modify filesystem."
echo " -f FORCE. Remove already converted. Usefull to update ID3 tags."
echo " -s SINLGE. Create sinlge MP3 instead of split variant."
echo
exit 0
}
# Init
[ ! -d $TMP ] && mkdir $TMP
[ ! -d $SOURCE ] && exit 101
[ ! -d $TARGET ] && exit 102
while getopts "h?sft" opt; do
case "$opt" in
t )
TEST=1
;;
f )
FORCE=1
;;
s )
SPLIT=0
;;
h|\?|* )
usage
;;
esac
done
# Download latest tonies.json
pushd $TMP > /dev/null 2>&1
curl -s -o $TONIES_JSON $TONIES_JSON_URL
popd > /dev/null 2>&1
for TAF in $SOURCE*.taf; do
echo Processing file \"$TAF\"...
# Extraxt AUDIO_ID from filename
AUDIO_ID="$(basename $TAF .taf)"
# Get ID3 Tag info from tonies.json using AUDIO_ID
pushd $TMP > /dev/null 2>&1
ID3_COMPOSER="tonies®"
ID3_GENRE="Tonies"
ID3_PART_POSITION="1"
ID3_PART_TOTAL="1"
ID3_PERFORMER=$(cat $TONIES_JSON | jq -r ".[] | select(.audio_id[] | contains(\"$AUDIO_ID\")) | .series" | head -n1)
ID3_ALBUM=$(cat $TONIES_JSON | jq -r ".[] | select(.audio_id[] | contains(\"$AUDIO_ID\")) | .title" | head -n1)
ID3_TRACK_NAME=$(cat $TONIES_JSON | jq -r ".[] | select(.audio_id[] | contains(\"$AUDIO_ID\")) | .episodes" | head -n1)
ID3_COMMENT="Tonies Hörfigur "
ID3_COMMENT+=$(cat $TONIES_JSON | jq -r ".[] | select(.audio_id[] | contains(\"$AUDIO_ID\")) | .model" | head -n1)
ID3_COVER=$(cat $TONIES_JSON | jq -r ".[] | select(.audio_id[] | contains(\"$AUDIO_ID\")) | .pic" | head -n1)
ID3_TRACK_NAME_POSITION="1"
ID3_TRACK_NAME_TOTAL="1"
ALBUM_DIR=$(echo "$AUDIO_ID - $ID3_PERFORMER - $ID3_TRACK_NAME" | sed 's|/|, |g' | sed 's|?|?|g' | sed 's|:|꞉|g')
# Cleanup alreay existing MP3s in case of FORCE=1
(( $FORCE )) && rm -rf "${TARGET}/${ALBUM_DIR}"
# Check if TAF was already converted
if [ -f "${TARGET}${AUDIO_ID}.mp3" ] ; then
echo -e "\t- MP3 version found: \e[33mSkip\e[0m.\n"
continue
elif [ -f "${TARGET}/${ALBUM_DIR}/${AUDIO_ID}.mp3" ] ; then
echo -e "\t- MP3 version found (single): \e[33mSkip\e[0m.\n"
continue
elif [ -f "${TARGET}/${ALBUM_DIR}/${AUDIO_ID} - Track toniebox-reverse-engineering/teddycloud_web#1.mp3" ] ; then
echo -e "\t- MP3 version found (split): \e[33mSkip\e[0m.\n"
continue
fi
# Check if TAF exists in tonies.json
if [ -z "$ID3_PERFORMER" ] ; then
echo -e "\tUnknown tonie: \e[34mSkip\e[0m.\n"
continue
fi
echo -e "\t- AUDIO_ID: $AUDIO_ID"
echo -e "\t- PERFOMER: $ID3_PERFORMER"
echo -e "\t- ALBUM: $ID3_ALBUM"
echo -e "\t- TRACK: $ID3_TRACK_NAME"
if [ ! -z "$ID3_COVER" ] ; then
# Downloading cover artwork....
echo -en "\t- Loading Cover art: "
curl -s -o _cover.png $ID3_COVER
convert -gravity center _cover.png -background white -alpha remove -alpha off -fuzz 1% -trim +repage -bordercolor white -border 75 -resize 750x750 -extent 750x750 -define jpeg:extent=230kb cover.jpeg
rm _cover.png
echo -e "\e[32mOk\e[0m."
fi
if [ $SPLIT -eq "0" ] ; then
echo -en "\t- Convert TAF to single MP3: "
# Create album folder
TARGET2="${TARGET}${ALBUM_DIR}/"
if [ $TEST -eq "0" ] ; then
[ ! -d "$TARGET2" ] && mkdir "$TARGET2"
# Remove TAF Header from OGG container
dd if="${SOURCE}${AUDIO_ID}.taf" of="$AUDIO_ID".ogg bs=4096 skip=1 status=none
# Convert OGG to MP3
ffmpeg -hide_banner -loglevel panic -y -i "$AUDIO_ID.ogg" -metadata artist="$ID3_PERFORMER" -metadata album="$ID3_ALBUM" -metadata title="$ID3_TRACK_NAME" -metadata composer="$ID3_COMPOSER" -metadata genre="$ID3_GENRE" -metadata comment="$ID3_COMMENT" -metadata track="$ID3_TRACK_NAME_POSITION/$ID3_TRACK_NAME_TOTAL" -metadata disc="$ID3_PART_POSITION/$ID3_PART_TOTAL" "$AUDIO_ID.mp3"
# Add Cover image to MP3
ffmpeg -hide_banner -loglevel panic -y -i "$AUDIO_ID.mp3" -i cover.jpeg -c copy -map 0 -map 1 -id3v2_version 3 -metadata:s:v title="Album cover" -metadata:s:v comment="Cover (front)" "${TARGET2}${AUDIO_ID}.mp3"
fi
echo -e "\e[32mOk\e[0m."
else
echo -en "\t- Get tracknames from JSON: "
ID3_TRACK_NAMES=$(cat $TONIES_JSON | jq -r ".[] | select(.audio_id[] | contains(\"$AUDIO_ID\")) | .tracks" | sed 's|\[||g' | sed 's|\]||g' | tr -d '\n' | sed 's|, |;|g' | xargs)
IFS=';' read -a ID3_TRACK_NAMES_ARR <<< "$ID3_TRACK_NAMES"
echo -e "\e[32mOk\e[0m."
echo -en "\t- Convert TAF to split MP3: "
# Create album folder
TARGET2="${TARGET}${ALBUM_DIR}/"
if [ $TEST -eq "0" ] ; then
[ ! -d "$TARGET2" ] && mkdir "$TARGET2"
# Split TAF into single OGG tracks
rm *.opus > /dev/null 2>&1
$OPUS2TONIE --split "${SOURCE}${AUDIO_ID}.taf" . > /dev/null 2>&1
ID3_TRACK_NAME_TOTAL=$(ls *.opus | wc -l)
i=1
for TRACK in *.opus; do
[ -z "${ID3_TRACK_NAMES_ARR[$i-1]}" ] && ID3_TRACK_NAMES_ARR[$i-1]="Track $i"
# Convert OPUS to MP3
ffmpeg -hide_banner -loglevel panic -y -i "$TRACK" -metadata artist="$ID3_PERFORMER" -metadata album="$ID3_ALBUM" -metadata title="${ID3_TRACK_NAMES_ARR[$i-1]}" -metadata composer="$ID3_COMPOSER" -metadata genre="$ID3_GENRE" -metadata comment="$ID3_COMMENT" -metadata track="$i/$ID3_TRACK_NAME_TOTAL" -metadata disc="$ID3_PART_POSITION/$ID3_PART_TOTAL" "$AUDIO_ID - Track #$i.mp3"
# Add Cover image to MP3
ffmpeg -hide_banner -loglevel panic -y -i "$AUDIO_ID - Track #$i.mp3" -i cover.jpeg -c copy -map 0 -map 1 -id3v2_version 3 -metadata:s:v title="Album cover" -metadata:s:v comment="Cover (front)" "${TARGET2}${AUDIO_ID} - Track #$i.mp3"
let "i=i+1"
done
fi
echo -e "\e[32mOk\e[0m."
fi
popd > /dev/null 2>&1
echo
done
# Clean up
rm -rf $TMP
exit 0
Nothing to do for the web frontend.
The desired functionality should be part of the backend if possible.
@SciLor can you move the ticket to teddycloud directly?