Suche z.B. Shell-Script um mehrere Bilder (jpeg/png) in eine mp3-Datei (ID3v2.4) einzubinden.

Niel$

New Member
Hallo Leute,

ich habe mehrere mp3-Dateien (Podcast) die wiederum in verschiedenen Unterverzeichnissen liegen. In jedem Unterverzeichnis liegen ca. 10 bis 30 Dateien (mp3) und mehrere Bilder (jpeg/png). Die Bilder haben die Namen ihrer Verwendung (TYPE) z.B. front_cover.jpeg / icon.png.

Mein Ziel ist es, mit Hilfe eines Schell-Scripts und dem Programm eyeD3 die jeweiligen Bilder (z.B. im Verzeichnis A) in alle mp3-Dateien (z.B. im Verzeichnis A) zu schreiben.

Mit dem Programm eye3d kann man Bilder in die nachstehenden Typen einbetten:

OTHER, ICON, OTHER_ICON, FRONT_COVER, BACK_COVER, LEAFLET, MEDIA, LEAD_ARTIST,
ARTIST, CONDUCTOR, BAND, COMPOSER, LYRICIST, RECORDING_LOCATION, DURING_RECORDING,
DURING_PERFORMANCE, VIDEO, BRIGHT_COLORED_FISH, ILLUSTRATION, BAND_LOGO, PUBLISHER_LOGO.

Der Terminal-Befehl zum einbetten von Bildern in eine mp3 Datei lautet für eye3d:

Code:
eyeD3 --add-image front_cover.jpeg:FRONT_COVER
Code:
eyeD3 --add-image icon.png:ICON

Code:
eyeD3 --add-image /Users/1234/Dokumente/Podcast/Podcast 001/Cover.jpeg:FRONT_COVER: /Users/1234/Dokumente/Podcast/*.mp3

Da ich viele Unterverzeichnisse habe währe es für mich ziemlich aufwändig die Bilder in die zahlreichen mp3-Dateien einzubetten.

Es währe schön, wenn mir jemand so ein Schell-Script programmieren könnte.

PS.

Schön währe es, wenn ich z.B. folgenden Befehl in mein Terminal eingeben könnte:

Picture2mp3 /Users/1234/Dokumente/Podcast/

und alle Unterverzeichnisse unterhalb vom Verzeichnis /Podcast/ werden abgearbeitet.

Eine Fertigmeldung nach dem Einbettungsprozes währe auch nicht schlecht.

Danke schon mal für eure Hilfe.
 
Last edited:
Bash am Morgen vertreibt Kummer und Sorgen. Ungetestet sollte das hier die Funktion erfüllen.
Das Skript iteriert über alle Podcast-Ordner und geht die im jeweiligen Hauptordner liegenden Bild-Dateien in alle Mp3-Dateien des Ordners + Unterordner einfügen. Die Bilddateien müssen den Namen der jeweiligen Funktion tragen, zB front_cover.jpg.
Achtung: der Code benutzt Bash-style Expansion, es muss also eine Bash-Shell verwendet werden.

Code:
#Wir gehen davon aus dass wir im Hauptorder der Struktur sind
cd /path/to/mainfolder

#Iteriert ueber alle Podcast Ordner
for dir in ./*/; do
    #Iteriert ueber alle MP3 Dateien im Podcast Hauptordner + Unterordner
    for mp3 in $(find "$dir" -name "*.mp3"); do
        #Iteriert über alle Bilddateien im Podcast Hauptordner
        for image in $dir/*.jpg; do
            #Extrahiert "bild" aus "bild.jpg"
            image_name="${image%.*}"
            #Fuegt den Bildnamen grossgeschrieben ein
            eyeD3 --add-image "$image:${image_name^^}:" $mp3
        done;
    done;
done
 
hallo df4,

danke für deine Hilfe.

1. Ich habe eine Datei "test.sh" erstellt und in den Ordner "/Users/1234/Dokumente/Podcast/" kopiert.
2. In die Datei "test.sh" habe ich folgendes eingefügt und gespeichert.

Code:
#!/bin/bash
#Iteriert ueber alle Podcast Ordner
for dir in ./*/; do
    #Iteriert ueber alle MP3 Dateien im Podcast Hauptordner + Unterordner
    for mp3 in $(find "$dir" -name "*.mp3"); do 
        #Iteriert über alle Bilddateien im Podcast Hauptordner
        for image in "$dir/*.jpeg"; do
            #Extrahiert "bild" aus "bild.jpeg"
            image_name="${image%.*}"
            #Fuegt das Bild ein
            eyeD3 --add-image $image:${image_name^^}: $mp3
        done;
    done;
done

3. ich bin mit dem Befehl "cd /Users/1234/Dokumente/Podcast/" in das Verzeichnis "Podcast" gewechselt. Hier liegt die Datei test.sh. Ausserdem befindet sich dort ein Ordner der Wiederum mehrere mp3 Dateien und eine jpeg Datei enthält.
4. ich habe das script mit dem Befehl "bash test.sh" aufgerufen.

5. Alls Ergebnis bekomme ich folgende Meldung:

test.sh: line 11: $image:${image_name^^}:: bad substitution


eyeD3 --add-image /Podcast_A/front_cover.jpeg:FRONT_COVER /Podcast_A/*.mp3

Die Dateien front_cover.jpeg und Episode_01.mp3 und Episode_02.mp3 etc. befinden sich im Verzeichnis "Podcast_A". Es gibt noch weitere Verzeichnisse mit entsprechenden Daten. Die heißen dann Podcast_B, Podcast_C usw.
 
Last edited:
Wenn diese Fehlermeldung kommt ist es trotz des Namens keine echte Bash-Shell. Was der Befehl für uppercase in deiner Shell ist musst du dann leider selber raussuchen oder eine echte Bash-Shell nehmen wie sie von Cygwin oder MobaXterm mitgebracht wird.

Drei konkrete Fehler habe ich aber rausgebügelt, hier neue Version:
- Nicht alle Variablen waren korrekt in Anführungszeichen was zumal mit Windows-Pfaden Probleme machen kann
- Der glob hatte nicht den leeren Fall abgefangen
- $image_name hatte den Pfad noch dranhängen, der ist jetzt über basename raus.
Code:
#!/bin/bash
#Iteriert ueber alle Podcast Ordner
for dir in ./*/; do
     [ -e "$dir" ] || continue
    #Iteriert ueber alle MP3 Dateien im Podcast Hauptordner + Unterordner
    for mp3 in $(find "$dir" -name "*.mp3"); do
        echo "=> Processing $mp3"
        #Iteriert über alle Bilddateien im Podcast Hauptordner
        for image in "${dir}"*.jpeg; do
                [ -e "$image" ] || continue
                #Extrahiert "bild" aus "bild.jpeg"
                image_full=$(basename "$image")
                image_name="${image_full%.*}"
                echo "Adding $image_name"
                #Fuegt das Bild ein
                eyeD3 --add-image $image:${image_name^^}: $mp3
        done;
    done;
done

Getestet mit folgender Dateistruktur:
Code:
./podcast_a
./podcast_a/front_cover.jpeg
./podcast_a/sub1
./podcast_a/sub1/e1.mp3
./podcast_a/sub1/e2.mp3
./podcast_a/sub2
./podcast_a/sub2/e0.mp3
./podcast_b
./podcast_b/back_cover.jpeg
./podcast_b/sub_b1
./podcast_b/sub_b1/e1.mp3
./podcast_b/sub_b1/e2.mp3
./podcast_b/sub_b1/e3.mp3
./podcast_b/sub_b1/e4.mp3
./test.sh
 
Ich habe jetzt auf meinem Mac die zsh-Shell verwendet, da diese doch etwas moderner ist.

Mein Verzeichnisbaum sieht wie folgt aus:

Code:
./Podcast 2000/Podcast_001/Cover.jpeg
./Podcast 2000/Podcast_001/Episose_001.mp3
./Podcast 2000/Podcast_001/Episose_002.mp3
./Podcast 2000/Podcast_001/Episose_002.mp3
./Podcast 2000/Podcast_002/Cover.jpeg
./Podcast 2000/Podcast_002/Episose_001.mp3
./Podcast 2000/Podcast_002/Episose_002.mp3
./Podcast 2000/Podcast_002/Episose_002.mp3
./test.sh

Code:
MacBook-Pro:Podcast user$ zsh test.sh
=> Processing ./Podcast
=> Processing 2000//Podcast_002/Episose_001.mp3
=> Processing ./Podcast
=> Processing 2000//Podcast_002/Episose_002.mp3
=> Processing ./Podcast
=> Processing 2000//Podcast_002/Episose_003.mp3
=> Processing ./Podcast
=> Processing 2000//Podcast_001/Episose_001.mp3
=> Processing ./Podcast
=> Processing 2000//Podcast_001/Episose_002.mp3
=> Processing ./Podcast
=> Processing 2000//Podcast_001/Episose_003.mp3
MacBook-Pro:Podcast nerd$

Leider wurden die Cover nicht eingebunden.

Wenn ich folgendes eingebe, funktioniert das einbinden des Covers:

Code:
eyeD3 --add-image /Users/user/Downloads/Files/Podcast\ 2000/Podcast_001/Cover.jpeg:FRONT_COVER: /Users/user/Downloads/Files/Podcast\ 2000/Podcast_001/*.mp3

Die Dateien

./Podcast 2000/Podcast_001/Episose_001.mp3
./Podcast 2000/Podcast_001/Episose_002.mp3
./Podcast 2000/Podcast_001/Episose_002.mp3
habe so ein Cover erhalten.

Unter Windows müsste die Eingabezeile wohl wie folgt lauten:

Code:
eyeD3 --add-image C:\\Downloads\Files\Podcast 2000\Podcast_001\Cover.jpeg:FRONT_COVER: C:\\Downloads\Files\Podcast 2000\Podcast_001\*.mp3
 
Last edited:
Ich hatte mal gestern aus Spaß angefangen eyed3 in Python zu verwenden, denn es handelt sich um ein Python-Package.
Ich musste dann leider feststellen, dass die "library" ungefragt Text via stderr und stdout ausgibt, falls irgendwas schief läuft.
Das eine läuft übers logging und das andere mit der print Funktion.

Es ist also einfach das Tool mit der Shell aufzurufen, als in Python drum herum zu programmieren, was die Entwickler versaut haben.
Über die Shell ist es einfacher, aber der Nachteil ist, dass jedes mal ein neuer Python-Interpreter gestartet wird, für jede Datei.
Bei wenig Dateien wird das nicht ins Gewicht fallen, aber wenn man 10.000 Dateien verarbeitet, kann sich die Laufzeit aufaddierten.

Vielleicht melde ich mich nochmal dazu.
 
Back
Top