Incruste la carátula del álbum en OGG a través de la línea de comandos en Linux

15

Quiero convertir mi música de flac a ogg, y actualmente oggenc lo hace perfectamente, excepto por la carátula del álbum. Metaflac puede generar carátulas de álbum, sin embargo, parece que no hay una herramienta de línea de comandos para incrustar carátulas de álbum en ogg. MP3Tag y EasyTag son capaces de hacerlo, y no hay una especificación para que aquí el que llama a la imagen que se codifica en base64. Sin embargo, hasta ahora no he podido tomar un archivo de imagen, convertirlo en base64 e incrustarlo en un archivo ogg.

Si tomo una imagen codificada en base64 de un archivo ogg que ya tiene la imagen incrustada, puedo incrustarla fácilmente en otra imagen usando vorbiscomment:

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

Mi problema es tomar algo como un jpeg y convertirlo a base64. Actualmente tengo:

base64 --wrap=0 ./image.jpg

Lo que me da el archivo de imagen convertido a base64, usando vorbiscomment y siguiendo las reglas de etiquetado, puedo incrustarlo en un archivo ogg de esta manera:

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

Sin embargo, esto me da un ogg cuya imagen no funciona correctamente. Al comparar las cadenas de base64, noté que todas las imágenes incrustadas correctamente tienen una línea de encabezado, pero todas las cadenas de base64 que genero carecen de este encabezado. Análisis adicional del encabezado:

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

Que sigue la especificación dada anteriormente. El aviso 003 corresponde a la portada e image / jpeg es el tipo mime.

Finalmente, mi pregunta es, ¿cómo puedo codificar un archivo base64 y generar este encabezado junto con él para incrustarlo en un archivo ogg?

dmikalova
fuente

Respuestas:

5

Acabo de escribir un script que exporta / importa imágenes de archivos OGG / Vorbis usando vorbiscomment. Es parte de una herramienta de conversión de biblioteca de música.

El script revelador está en la función 'mussync-tools-transfert_images' de esta herramienta:

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

Básicamente, he escrito un lector y un escritor para el formato metadata_block_picture.

El código es bastante complejo:

      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
fuente
6

Aquí está mi solución para el / usr / bin / vorbiscomment: La lista de argumentos es un problema demasiado largo. Creé un guión y lo llamé oggart. Simplemente ejecútelo desde la línea de comando así:

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

Esto etiqueta su archivo ogg con el campo METADATA_BLOCK_PICTURE. Easytag utiliza la antigua forma de hacerlo con el campo COVERART en lugar de METADATA_BLOCK_PICTURE. Si desea compatibilidad con Easytag, puede ejecutar el script de esta manera:

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

Aquí está el guión:

#!/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
fuente
El guión publicado es divertido aquí. Puede descargar oggart.tar.gz @ murga-linux.com/puppy/viewtopic.php?mode=attach&id=44270
Jason
Arreglé el formato del script en la publicación.
Gaff el
1
Si obtiene un "Error de sintaxis:" ("inesperado" en Ubuntu, probablemente sea algo que tenga que ver con el shell que se está ejecutando. Cambié la primera línea a #! / Bin / bash y funcionó.
Dan Gravell
1
Este script no me funciona. Como puedo ver, solo usa base64 de la imagen, pero debe haber un encabezado especial antes de él
Sergey
2

No conozco nada que lo haga automáticamente simplemente señalando la imagen.

Sin embargo, vorbiscomment puede incrustar etiquetas arbitrarias, solo necesita codificar la imagen en base64 y luego construir la etiqueta en el formato correcto .

p.ej vorbiscomment -a -t 'METADATA_BLOCK_PICTURE=...' file.ogg newfile.ogg

tendrás que introducir estos pasos en un script de algún tipo para que sea útil.

sml
fuente
Esto sería factible, pero lamentablemente si la imagen supera los 64 kb, entonces vorbiscomments devuelve "/ usr / bin / vorbiscomment: Lista de argumentos demasiado larga". ¿Alguna idea de como solucionar esto?
dmikalova
¿Cuál es su sistema y cuál es la salida de getconf ARG_MAX? Desafortunadamente, no hay forma de evitar este límite sin volver a compilar el núcleo. Aquí en 64 bits 2.6.32-24, tengo 2 MB.
sml
Estoy ejecutando Arch Linux 64-bit 2.6.34.1-1 y también tengo 2mb. ¿Sería posible poner un marcador, por ejemplo, vorbiscomment -a -t 'METADATA_BLOCK_PICTURE = marker' file.ogg newfile.ogg, luego hacer que algo lea el archivo ogg y reemplazar el marcador con la imagen base64?
dmikalova
Absolutamente. Si ve la especificación del formato de etiqueta que he vinculado, puede usar vorbiscomment para insertar una imagen temporal (pequeña) y luego escribir directamente en el archivo actualizando las dos últimas partes de la etiqueta: longitud de datos y los datos en sí. Obviamente, tendrás que hackear algo juntos, sin embargo.
sml
Estoy probando mutagen, una biblioteca de python de bajo nivel para el etiquetado de audio y mi aspecto preliminar parece que puede hacer lo que necesito. Informaré cuando resuelva las cosas.
dmikalova