Betten Sie Albumcover über die Befehlszeile in Linux in OGG ein


12

Ich möchte meine Musik von flac nach ogg konvertieren, und derzeit macht oggenc das perfekt, außer für Albumcover. Metaflac kann Albumcover ausgeben, es scheint jedoch kein Befehlszeilen-Tool zu geben, um Albumcover in ogg einzubetten. MP3Tag und EasyTag sind dazu in der Lage, und es gibt eine Spezifikation dafür Hier Das heißt, das Bild muss base64-codiert sein. Bisher ist es mir jedoch nicht gelungen, eine Bilddatei aufzunehmen, in base64 zu konvertieren und in eine ogg-Datei einzubetten.

Wenn ich ein base64-kodiertes Bild aus einer ogg-Datei nehme, in die das Bild bereits eingebettet ist, kann ich es mit vorbiscomment problemlos in ein anderes Bild einbetten:

vorbiscomment -l withimage.ogg > textfile
vorbiscomment -c textfile noimage.ogg

Mein Problem ist, etwas wie ein JPEG zu nehmen und es in base64 umzuwandeln. Derzeit habe ich:

base64 --wrap=0 ./image.jpg

Womit ich die Bilddatei mit vorbiscomment in base64 konvertiert habe und den Tagging-Regeln folge, kann ich das wie folgt in eine ogg-Datei einbetten:

echo "METADATA_BLOCK_PICTURE=$(base64 --wrap=0 ./image.jpg)" > ./folder.txt
vorbiscomment -c textfile noimage.ogg

Dies gibt mir jedoch ein OGG, dessen Bild nicht richtig funktioniert. Beim Vergleich der base64-Zeichenfolgen ist mir aufgefallen, dass alle richtig eingebetteten Bilder eine Kopfzeile haben, aber allen von mir generierten base64-Zeichenfolgen fehlt diese Kopfzeile. Weitere Analyse des Headers:

od -c header.txt
0000000  \0  \0  \0 003  \0  \0  \0  \n   i   m   a   g   e   /   j   p
0000020   e   g  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0  \0
0000040  \0  \0  \0  \0  \0  \0  \0  \0 035 332
0000052

Was folgt die oben angegebene Spezifikation. Hinweis 003 entspricht der Titelseite und Image / JPEG ist der MIME-Typ.

Meine Frage ist nun, wie kann ich eine Datei mit base64 codieren und diesen Header zusammen mit ihm zum Einbetten in eine ogg-Datei generieren?

Antworten:


3

Ich habe gerade ein Skript geschrieben, das mit vorbiscomment Bilder aus OGG / Vorbis-Dateien exportiert / importiert. Es ist Teil eines Konvertierungstools für Musikbibliotheken.

Das revelent-Skript befindet sich in der Funktion 'mussync-tools-transfert_images' dieses Tools:

https://github.com/biapy/howto.biapy.com/blob/master/various/mussync-tools

Grundsätzlich habe ich einen Reader und einen Writer für das metadata_block_picture-Format geschrieben.

Der Code ist ziemlich komplex:

      OUTPUT_FILE="/path/to/my-ogg-file.ogg"
      IMAGE_PATH="/path/to/my-cover-art.jpg"
      IMAGE_MIME_TYPE="image/jpeg"
      # Export existing comments to file.
      local COMMENTS_PATH="$(command mktemp -t "tmp.XXXXXXXXXX")"
      command vorbiscomment --list --raw "${OUTPUT_FILE}" > "${COMMENTS_PATH}"

      # Remove existing images.
      command sed -i -e '/^metadata_block_picture/d' "${COMMENTS_PATH}"

      # Insert cover image from file.

      # metadata_block_picture format.
      # See: https://xiph.org/flac/format.html#metadata_block_picture

      local IMAGE_WITH_HEADER="$(command mktemp -t "tmp.XXXXXXXXXX")"
      local DESCRIPTION=""

      # Reset cache file.
      echo -n "" > "${IMAGE_WITH_HEADER}"

      # Picture type <32>.
      command printf "0: %.8x" 3 | command xxd -r -g0 \
              >> "${IMAGE_WITH_HEADER}"
      # Mime type length <32>.
      command printf "0: %.8x" $(echo -n "${IMAGE_MIME_TYPE}" | command wc -c) \
                | command xxd -r -g0 \
              >> "${IMAGE_WITH_HEADER}"
      # Mime type (n * 8)
      echo -n "${IMAGE_MIME_TYPE}" >> "${IMAGE_WITH_HEADER}"
      # Description length <32>.
      command printf "0: %.8x" $(echo -n "${DESCRIPTION}" | command wc -c) \
                | command xxd -r -g0 \
              >> "${IMAGE_WITH_HEADER}"
      # Description (n * 8)
      echo -n "${DESCRIPTION}" >> "${IMAGE_WITH_HEADER}"
      # Picture with <32>.
      command printf "0: %.8x" 0 | command xxd -r -g0 \
              >> "${IMAGE_WITH_HEADER}"
      # Picture height <32>.
      command printf "0: %.8x" 0 | command xxd -r -g0 \
              >> "${IMAGE_WITH_HEADER}"
      # Picture color depth <32>.
      command printf "0: %.8x" 0 | command xxd -r -g0 \
              >> "${IMAGE_WITH_HEADER}"
      # Picture color count <32>.
      command printf "0: %.8x" 0 | command xxd -r -g0 \
              >> "${IMAGE_WITH_HEADER}"
      # Image file size <32>.
      command printf "0: %.8x" $(command wc -c "${IMAGE_PATH}" \
                | command cut --delimiter=' ' --fields=1) \
                | command xxd -r -g0 \
              >> "${IMAGE_WITH_HEADER}"
      # Image file.
      command cat "${IMAGE_PATH}" >> "${IMAGE_WITH_HEADER}"

      echo "metadata_block_picture=$(command base64 --wrap=0 < "${IMAGE_WITH_HEADER}")" >> "${COMMENTS_PATH}"

      # Update vorbis file comments.
      command vorbiscomment --write --raw --commentfile "${COMMENTS_PATH}" "${OUTPUT_FILE}"

      # Delete cache file.
      command rm "${IMAGE_WITH_HEADER}"
      # Delete comments file.
      command rm "${COMMENTS_PATH}"

5

Hier ist meine Lösung für das / usr / bin / vorbiscomment: Argumentliste zu langes Problem. Ich habe ein Skript erstellt und es oggart genannt. Führen Sie es einfach von der Kommandozeile aus:

oggart /path/to/music_file.ogg /path/to/image_file

Dies markiert Ihre ogg-Datei mit dem METADATA_BLOCK_PICTURE-Feld. Easytag verwendet hierfür die alte Methode mit dem Feld COVERART anstelle von METADATA_BLOCK_PICTURE. Wenn Sie Easytag-Kompatibilität wünschen, können Sie das Skript folgendermaßen ausführen:

oggart /path/to/music_file.ogg /path/to/image_file -e

Hier ist das Skript:

#!/bin/sh

FILE1="`basename \"$1\"`"
EXT1=${FILE1##*.}
EXTTYPE1=`echo $EXT1 | tr '[:upper:]' '[:lower:]'`

FILE2="`basename \"$2\"`"
EXT2=${FILE2##*.}
EXTTYPE2=`echo $EXT2 | tr '[:upper:]' '[:lower:]'`

OGG=""
if [ "$EXTTYPE1" = ogg ]; then
OGG="$1"
elif [ "$EXTTYPE2" = ogg ]; then
OGG="$2"
fi
if [ "$OGG" = "" ]; then
echo no ogg file selected
exit 0
fi

PIC=""
array=(jpeg jpg png)
for item in ${array[*]}
do
if [ "$item" = "$EXTTYPE1" ]; then
PIC="$1"
elif [ "$item" = "$EXTTYPE2" ]; then
PIC="$2"
fi
done
if [ "$PIC" = "" ]; then
echo no jpg or png file selected
exit 0
fi

if [ "$3" = -e ]; then
EASYTAG=Y
else
EASYTAG=N
fi

DESC=`basename "$PIC"`
APIC=`base64 --wrap=0 "$PIC"`
if [ "`which exiv2`" != "" ]; then
MIME=`exiv2 "$PIC" | grep 'MIME type ' | sed 's/: /|/' | cut -f 2 -d '|' | tail -n 1`
fi
if [ "$MIME" = "" ]; then
MIME="image/jpeg"
fi

vorbiscomment -l "$OGG" | grep -v '^COVERART=' | grep -v '^COVERARTDESCRIPTION=' | grep -v '^COVERARTMIME=' | grep -v 'METADATA_BLOCK_PICTURE=' > "$OGG".tags

if [ "$EASYTAG" = N ]; then
echo METADATA_BLOCK_PICTURE="$APIC" > "$OGG".tags2
else
echo COVERART="$APIC" > "$OGG".tags2
fi
vorbiscomment -w -R -c "$OGG".tags2 "$OGG"
vorbiscomment -a -R -t COVERARTDESCRIPTION="$DESC" "$OGG"
vorbiscomment -a -R -t COVERARTMIME="$MIME" "$OGG"
vorbiscomment -a -R -c "$OGG".tags "$OGG"

rm -f "$OGG".tags
rm -f "$OGG".tags2

Das Drehbuch gepostet witzig hier. Sie können oggart.tar.gz @ herunterladen. murga-linux.com/puppy/viewtopic.php?mode=attach&id=44270
Jason

Ich habe die Formatierung des Skripts im Beitrag korrigiert.
3498DB

1
Wenn unter Ubuntu ein "Syntaxfehler:" ("unerwartet") angezeigt wird, hängt dies wahrscheinlich mit der zum Ausführen verwendeten Shell zusammen. Ich habe die erste Zeile in "#! / Bin / bash" geändert und es hat funktioniert.
Dan Gravell

1
Dieses Skript funktioniert nicht für mich. Wie ich sehen kann, verwendet es nur base64 des Bildes, aber es muss einen speziellen Header davor geben
Sergey

2

Mir ist nichts bewusst, was dies automatisch durch einfaches Zeigen auf das Bild bewirkt.

jedoch Vorbemerkung Sie können beliebige Tags einbetten codiere das Bild in base64 und dann Konstruieren Sie das Tag im richtigen Format .

z.B vorbiscomment -a -t 'METADATA_BLOCK_PICTURE=...' file.ogg newfile.ogg

Sie müssen diese Schritte in ein Skript hacken, damit es nützlich ist.


Dies wäre machbar, aber leider gibt vorbiscomments "/ usr / bin / vorbiscomment: Argumentliste zu lang" zurück, wenn das Bild größer als 64 KB ist. Hast du eine Idee, wie du das umgehen kannst?
dmikalova

Was ist Ihr System und was ist die Ausgabe von getconf ARG_MAX? Leider führt kein Weg an dieser Grenze vorbei, ohne den Kernel neu zu kompilieren. Hier auf 64-Bit 2.6.32-24 habe ich 2 MB.
sml

Ich verwende Arch Linux 64-Bit 2.6.34.1-1 und ich habe auch 2 MB. Wäre es möglich, einen Marker, z.B. vorbiscomment -a -t 'METADATA_BLOCK_PICTURE = marker' file.ogg newfile.ogg, dann muss etwas die ogg-Datei lesen und den marker durch das base64-Image ersetzen?
dmikalova

Absolut. Wenn Sie die von mir verknüpfte Tag-Formatspezifikation sehen, können Sie vorbiscomment verwenden, um ein temporäres (kleines) Bild einzufügen und dann direkt in die Datei zu schreiben, wobei die letzten beiden Teile des Tags aktualisiert werden - die Datenlänge und die Daten selbst. Offensichtlich müssen Sie jedoch selbst etwas zusammen hacken.
sml

Ich probiere Mutagen aus, eine Low-Level-Python-Bibliothek für Audio-Tagging, und mein vorläufiges Aussehen scheint zu tun, was ich brauche. Ich melde mich wieder, wenn ich es herausgefunden habe.
dmikalova
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.