Intégrer une pochette d'album dans OGG via la ligne de commande sous Linux

15

Je veux convertir ma musique de flac en ogg, et actuellement oggenc le fait parfaitement, sauf pour les pochettes d'album. Metaflac peut produire des pochettes d'album, mais il ne semble pas y avoir d'outil de ligne de commande pour intégrer des pochettes d'album dans ogg. MP3Tag et EasyTag sont capables de le faire, et il y a une spécification ici qui demande que l'image soit encodée en base64. Cependant, jusqu'à présent, je n'ai pas réussi à prendre un fichier image, à le convertir en base64 et à l'intégrer dans un fichier ogg.

Si je prends une image encodée en base64 à partir d'un fichier ogg qui a déjà l'image intégrée, je peux facilement l'intégrer dans une autre image en utilisant le vorbiscomment:

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

Mon problème prend quelque chose comme un jpeg et le convertit en base64. Actuellement, j'ai:

base64 --wrap=0 ./image.jpg

Ce qui me donne le fichier image converti en base64, en utilisant le vorbiscomment et en suivant les règles de marquage, je peux l'intégrer dans un fichier ogg comme ceci:

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

Cependant cela me donne un ogg dont l'image ne fonctionne pas correctement. J'ai remarqué en comparant les chaînes base64 que toutes les images correctement incorporées ont une ligne d'en-tête mais toutes les chaînes base64 que je génère manquent de cet en-tête. Analyse plus approfondie de l'en-tête:

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

Qui suit la spécification donnée ci-dessus. L'avis 003 correspond à la couverture et l'image / jpeg est le type mime.

Donc, finalement, ma question est, comment puis-je coder en base64 un fichier et générer cet en-tête avec lui pour l'incorporer dans un fichier ogg?

dmikalova
la source

Réponses:

5

je viens d'écrire un script qui exporte / importe des images à partir de fichiers OGG / Vorbis en utilisant vorbiscomment. Il fait partie d'un outil de conversion de bibliothèque musicale.

Le nouveau script se trouve dans la fonction 'mussync-tools-transfert_images' de cet outil:

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

Fondamentalement, j'ai écrit un lecteur et un écrivain pour le format metadata_block_picture.

Le code est assez complexe:

      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}"
Biapy
la source
6

Voici ma solution pour le / usr / bin / vorbiscomment: Liste d'arguments problème trop long. J'ai créé un script et je l'ai nommé oggart. Il suffit de l'exécuter à partir de la ligne de commande comme ceci:

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

Cela marque votre fichier ogg avec le champ METADATA_BLOCK_PICTURE. Easytag utilise l'ancienne façon de procéder avec le champ COVERART au lieu de METADATA_BLOCK_PICTURE. Si vous souhaitez la compatibilité Easytag, vous pouvez exécuter le script comme ceci:

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

Voici le script:

#!/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
Jason
la source
Le script est drôle ici. Vous pouvez télécharger oggart.tar.gz @ murga-linux.com/puppy/viewtopic.php?mode=attach&id=44270
Jason
J'ai corrigé la mise en forme du script dans le message.
Gaff
1
Si vous obtenez une "erreur de syntaxe:" ("inattendu" dans Ubuntu, c'est probablement quelque chose à voir avec le shell utilisé pour fonctionner. J'ai changé la première ligne en #! / Bin / bash et cela a fonctionné.
Dan Gravell
1
ce script ne fonctionne pas pour moi. Comme je peux le voir, il utilise uniquement la base64 de l'image, mais il doit y avoir un en-tête spécial avant
Sergey
2

Je ne suis au courant de rien qui le fasse automatiquement en pointant simplement l'image.

Cependant, le vorbiscomment peut incorporer des balises arbitraires, il vous suffit de coder l'image en base64 , puis de construire la balise au format correct .

par exemple vorbiscomment -a -t 'METADATA_BLOCK_PICTURE=...' file.ogg newfile.ogg

vous devrez pirater ces étapes dans un script quelconque pour qu'il soit utile.

sml
la source
Ce serait faisable, mais malheureusement si l'image dépasse 64 Ko, vorbiscomments renvoie "/ usr / bin / vorbiscomment: la liste des arguments est trop longue". Une idée de comment contourner cela?
dmikalova
quel est votre système, et quelle est la sortie de getconf ARG_MAX? Malheureusement, il n'y a aucun moyen de contourner cette limite sans recompiler le noyau. Ici, en 64 bits 2.6.32-24, j'ai 2 Mo.
sml
J'utilise arch linux 64-bit 2.6.34.1-1 et j'ai également 2 Mo. Serait-il possible de mettre un marqueur, par exemple vorbiscomment -a -t 'METADATA_BLOCK_PICTURE = marker' file.ogg newfile.ogg, puis de lire le fichier ogg et de remplacer le marqueur par l'image base64?
dmikalova
Absolument. Si vous voyez la spécification de format de balise que j'ai liée, vous pouvez utiliser vorbiscomment pour insérer une (petite) image temporaire, puis écrire directement dans le fichier en mettant à jour les deux dernières parties de la balise - la longueur des données et les données elles-mêmes. De toute évidence, vous devrez cependant pirater quelque chose ensemble.
sml
J'essaie mutagen, une bibliothèque python de bas niveau pour le balisage audio et mon apparence préliminaire semble pouvoir faire ce dont j'ai besoin. Je ferai rapport quand j'aurai compris les choses.
dmikalova