x
Blog Digitalgesellschaft Verwaltungsbetrieb Textarchiv Textarchiv Walter Kirk (✝) Impressum
Audiobook erstellen (.m4b) - II: Automatik
Automatisierte ErstellungAnpassungenmeta.txtDateinamenErstellung der ListenErstellung der .m4bBash-ScriptErgebnisErgänzte meta.txtDarstellung in CozyKapitelnamen nachträglich ändernZusammenfassung
Wer eine vollständig automatisierte Erstellung von .m4b bevorzugt, sollte sich das Bash-Script chapters.sh von Jeff Channel ansehen, das auf .m4b umgestellt und auf die eigenen Verhältnisse angepasst werden kann. Download unter: FFMETADATA Chapter generator.
Das Ergebnis ist gut, wenn man die Verhältnisse bei .mp4 berücksichtigt. Für die Erstellung von .m4b sind folgende Anpassungen sinnvoll.
Die Anpassungen setzen die im Blogpost Audiobook erstellen (.m4b) aufgeführten Bedingungen voraus.
Die bereit gestellten Audiobook/Podcast enthalten nicht immer die korrekten Metadaten. Deshalb ist die meta.txt manuell im Teil oberhalb der Angaben für [Chapter] zu ergänzen. Beispiel:
xxxxxxxxxx
;FFMETADATA1
major_brand=M4A
minor_version=512
compatible_brands=M4A isomiso2
title=Der Schatz im Silbersee
subtitle=
artist=Karl May
author=Karl May
director=
composer=
lyricist=
narrator=
album_artist=Martin Seifert
album=Der Schatz im Silbersee
date=2020-09-10
url=
umid=
date_recorded=
recording_location=
producer=
producer/email=
copyright=Mitteldeutscher Rundfunk
comment=ungekürzte Lesung, compiled 2024-10-31
description=Auf der Suche nach Reichtümern ziehen der Bandit Cornel Brinkley und seine Tramps zum Silbersee. Old Firehand, Winnetou und Old Shatterhand haben das gleiche Ziel. Wer wird zuerst ankommen?
synopsis=
genre=Audiobook
encoder=Lavf60.3.100
Das Script fügt die Kapitelmarker automatisiert in die meta.txt ein.
Das Script setzt voraus, dass die Dateinamen als Kapitelnamen genutzt werden. Deshalb ist hier darauf zu achten, dass die Dateinamen entsprechend der Gliederung korrekt ausgewählt sind, z.B. Folge 1.mp3 oder Folge 1: Text.mp3.
Damit die natürliche Reihenfolge der Dateien erfolgt, und zwar von 1-9 und nicht 01-09, wird die Erstellung der Listen entsprechend eingestellt:
xxxxxxxxxx
printf "%s\n" *.m4b | sort -V > "${file_list}"
printf "file '%s'\n" *.m4b | sort -V > "${input_list}"
Mit der Sortierung unter Angabe sort -V wird dies erreicht.
Da die Videospur nicht vorhanden ist, wird die Ausführung von FFmpeg entsprechend angepasst.
xxxxxxxxxx
ffmpeg -f concat -safe 0 -i "${input_list}" -i "${meta_file}" -map_metadata 1 -vn -codec copy "${final_m4b}" -v quiet
Der Schalter -vn bewirkt, dass die Videospur nicht berücksichtigt wird, sodass keine neue Transcodierung stattfindet.
xxxxxxxxxx
#!/bin/bash
# Original chapters.sh by copyrigt Jeff Channel
# https://gist.github.com/bdurrow/b51470869dd72b2333407dbfcb947801
# Adapted Version
# copyright Wolfgang Kirk
set -euo pipefail
IFS=$'\n\t'
## Script to merge all m4b in current directory
## And update chapter marks to retain the folder/filename
## Script for merging .m4b
# 1. Schritt Transcodieren nach m4b
# for f in *.mp3; do ffmpeg -i "$f" -vn -ac 2 -ar 48000 -b:a 320k -c:a aac "${f%.mp3}.m4b" ; done
# 2. Schritt
temp_dir=$(mktemp -d)
function finish {
rc=$?
if [[ $rc != 0 ]]; then
echo
echo "FAILED!"
fi
echo -n "Cleaning up "
rm -rf "${temp_dir}"
echo "..........[ DONE ]"
exit $rc
}
trap finish EXIT
current_dir=$(pwd)
bname=$(basename ${current_dir})
final_m4b=${bname}.m4b
input_list=input-list.txt
file_list=filelist.txt
meta_file=meta.txt
# 3. Schritt Prüfung auf Gesamtdatei
#Hopefully this will work for either BSD or GNU sed
extended_match="-r"
echo "" | sed ${extended_match} 's|foo|bar|' 2>/dev/null || extended_match="-E"
if [ -e "${final_m4b}" ]; then
echo "${final_m4b} already exists, please remove it."
exit 1
fi
# 4 Schritt Listen erstellen.
echo -n "Generating file lists "
printf "%s\n" *.m4b | sort -V > "${file_list}"
printf "file '%s'\n" *.m4b | sort -V > "${input_list}"
echo "..........[ DONE ]"
# 5. Schritt Chaptermarks erstellen
## chapter marks
#Do this first so we fail early
#TODO: Test (‘=’, ‘;’, ‘#’, ‘\’) are escaped
ts=0
echo -n "Generating chapter marks "
# ffmpeg -i "$(head -1 "${file_list}")" -f ffmetadata "${meta_file}" -v quiet
cat "${file_list}" | while read file
do
ds=$(ffprobe -v quiet -of csv=p=0 -show_entries format=duration "${file}")
# echo "$ds"
escaped_title=$(echo ${file} | sed ${extended_match} -e 's|([=;#\])|\\\1|g' -e 's|.[Mm][Pp]4$||' )
# escaped_title=$(echo ${bname} | sed ${extended_match} -e 's|([=;#\])|\\\1|g' -e 's|.[Mm][Pp]4$||' )
echo "[CHAPTER]" >> "${meta_file}"
echo "TIMEBASE=1/1" >> "${meta_file}"
echo "START=${ts}" >> "${meta_file}"
ts=$(awk "BEGIN {print ${ts}+${ds}; exit}")
echo "END=${ts}" >> "${meta_file}"
# echo "TITLE=${escaped_title}" >> "${meta_file}"
echo "TITLE=${file%.*}" >> "${meta_file}"
done
echo "..........[ DONE ]"
# 6. Schritt
echo -n "Merging the files "
ffmpeg -f concat -safe 0 -i "${input_list}" -i "${meta_file}" -map_metadata 1 -vn -codec copy "${final_m4b}" -v quiet
echo "..........[ DONE ]"
echo "Job Completed."
# 7. Schritt Art-Cover einfügen
for f in ./*.m4b; do AtomicParsley "$f" --artwork cover.jpg --overWrite ; done
# 8. Schritt Ordner bereinigen
mv "$(basename "$(pwd)")".m4b ./gesamt/ &&
mv *.jpg .txt ./sonstiges/ && mv *.m4b ./m4b/ && mv *.mp3 ./mp3/ && mv *.mpga* ./mp3/
Ein Temp-Ordner wird bei dieser Ausführung nicht genutzt, weil die .txt aufbewahrt werden sollen.
Bei umfangreichen .m4b zeigt das Script seine Stärken. Im Bild unten wird ein Beispiel aufgezeigt, das insgesamt 38 Kapitel umfasst und ohne Schwierigkeiten erstellt wurde.
xxxxxxxxxx
;FFMETADATA1
major_brand=M4A
minor_version=512
compatible_brands=M4A isomiso2
title=Der Schatz im Silbersee
subtitle=
artist=Karl May
author=Karl May
director=
composer=
lyricist=
narrator=
album_artist=Martin Seifert
album=Der Schatz im Silbersee
date=2020-09-10
url=
umid=
date_recorded=
recording_location=
producer=
producer/email=
copyright=Mitteldeutscher Rundfunk
comment=ungekürzte Lesung, compiled 2024-10-31
description=Auf der Suche nach Reichtümern ziehen der Bandit Cornel Brinkley und seine Tramps zum Silbersee. Old Firehand, Winnetou und Old Shatterhand haben das gleiche Ziel. Wer wird zuerst ankommen?
synopsis=
genre=Audiobook
encoder=Lavf60.3.100
[CHAPTER]
TIMEBASE=1/1
START=0
END=1583.59
TITLE=Folge 1
[CHAPTER]
TIMEBASE=1/1
START=1583.59
END=3316.13
TITLE=Folge 2
[CHAPTER]
TIMEBASE=1/1
START=3316.13
END=5106.41
TITLE=Folge 3
usw.
Das .m4b als Ergebnis in Cozy angezeigt:
Änderungen der Kapitelnamen lassen sich in eine vorhandene .m4b einfügen. Dazu ist die meta.txt zu ergänzen/ändern:
xxxxxxxxxx
[CHAPTER]
TIMEBASE=1/1
START=0
END=1583.59
# TITLE=Folge 1 # alt
TITLE=Folge 1: Beispiel
Die geänderte meta.txt wird in die .m4b übertragen. Danach muss die vorhandene cover.jpg neu eingefügt werden. Beide Vorgänge können mit einem Bash-Script vereinfacht erledigt werden. Hierzu müssen die Dateien .m4b, meta.txt und cover.jpg in einem Verzeichnis gespeichert sein.
xxxxxxxxxx
bin/bash
# 1. Schritt: Neue Metadaten einfügen
ffmpeg -i *.m4b -i meta.txt -map_metadata 1 -map_chapters 1 -vn -codec copy "test.m4b"
# 2. Schritt Art-Cover einfügen
for f in *.m4b; do AtomicParsley "$f" --artwork cover.jpg --overWrite ; done
Im obigen Beispiel ist das Audiobook mit 38 Folgen in Cozy dargestellt. Nun lasen sich die einzelnen Folgen auch unter die vom Autor vorgegebenen Kapitel zusammen fassen, also 1=Folge 1-8, etc.. So ergibt sich eine komplett andere Darstellung.
Die Ausführung mit dem (angepassten) Bash-Script ist insbesondere bei umfangreichen Audiobook eine vorteilhafte Lösung. Eine nachträgliche Änderung der Meta-Daten kann ebenfalls mit einem Bash-Script vereinfacht erfolgen.
Wolfgang Kirk
Veröffentlicht: 2024-11-01, 09:30 Uhr aktualisiert: 2024-12-05, 07:15 Uhr