Incorporar arte do álbum no OGG através da linha de comando no linux

15

Quero converter minha música de flac para ogg, e atualmente oggenc faz isso perfeitamente, exceto na arte do álbum. O Metaflac pode produzir a arte do álbum, no entanto, parece não haver uma ferramenta de linha de comando para incorporar a arte do álbum no ogg. Mp3Tag e EasyTag são capazes de fazê-lo, e não há uma especificação para ele aqui que apela para a imagem a ser base64 codificado. No entanto, até agora não obtive êxito em obter um arquivo de imagem, convertê-lo em base64 e incorporá-lo em um arquivo ogg.

Se eu pegar uma imagem codificada em base64 de um arquivo ogg que já tenha a imagem incorporada, eu posso incorporá-la facilmente em outra imagem usando o vorbiscomment:

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

Meu problema é pegar algo como um jpeg e convertê-lo em base64. Atualmente tenho:

base64 --wrap=0 ./image.jpg

O que me dá o arquivo de imagem convertido em base64, usando o vorbiscomment e seguindo as regras de marcação, posso incorporar isso em um arquivo ogg da seguinte forma:

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

No entanto, isso me dá um ogg cuja imagem não funciona corretamente. Notei que, ao comparar as seqüências base64, todas as imagens incorporadas corretamente têm uma linha de cabeçalho, mas todas as seqüências base64 que eu gero não possuem esse cabeçalho. Análise mais aprofundada do cabeçalho:

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 segue a especificação dada acima. O aviso 003 corresponde à capa e image / jpeg é do tipo mime.

Então, finalmente, minha pergunta é: como posso base64 codificar um arquivo e gerar esse cabeçalho junto com ele para incorporar em um arquivo ogg?

dmikalova
fonte

Respostas:

5

Acabei de escrever um script que exporta / importa imagens de arquivos OGG / Vorbis usando o vorbiscomment. Faz parte de uma ferramenta de conversão de biblioteca de música.

O script revelent está na função 'mussync-tools-transfert_images' desta ferramenta:

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

Basicamente, escrevi um leitor e um escritor para o formato metadata_block_picture.

O código é bastante complexo:

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

Aqui está minha solução para o / usr / bin / vorbiscomment: Problema muito longo na lista de argumentos. Eu criei um script e o chamei de oggart. Basta executá-lo na linha de comando da seguinte maneira:

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

Isso marca seu arquivo ogg com o campo METADATA_BLOCK_PICTURE. A Easytag usa a maneira antiga de fazer isso com o campo COVERART em vez de METADATA_BLOCK_PICTURE. Se você deseja compatibilidade com o Easytag, pode executar o script assim:

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

Aqui está o 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
fonte
O script postou engraçado aqui. Você pode fazer o download do arquivo oggart.tar.gz @ murga-linux.com/puppy/viewtopic.php?mode=attach&id=44270 #
Jason
Corrigi a formatação do script na postagem.
Gaff
1
Se você receber um "Erro de sintaxe:" ("inesperado" no Ubuntu, é provavelmente algo a ver com o shell que está sendo usado para executar. Alterei a primeira linha para #! / Bin / bash e funcionou.
Dan Gravell
1
esse script não está funcionando para mim. Como eu posso ver que utiliza apenas base64 da imagem, mas é preciso haver um cabeçalho especial antes
Sergey
2

Não estou ciente de nada que faça isso automaticamente, apenas apontando para a imagem.

No entanto, o vorbiscomment pode incorporar tags arbitrárias, basta codificar a imagem em base64 e, em seguida, construir a tag no formato correto .

por exemplo vorbiscomment -a -t 'METADATA_BLOCK_PICTURE=...' file.ogg newfile.ogg

você precisará hackear essas etapas em algum tipo de script para que seja útil.

sml
fonte
Isso seria possível, mas, infelizmente, se a imagem tiver mais de 64kb, o vorbiscomments retornará "/ usr / bin / vorbiscomment: lista de argumentos muito longa". Alguma idéia de como contornar isso?
dmikalova
qual é o seu sistema e qual é a saída getconf ARG_MAX? Infelizmente, não há como contornar esse limite sem recompilar o kernel. Aqui no 2.6.32-24 de 64 bits, tenho 2 MB.
sml 29/07
Estou executando o arch linux de 64 bits 2.6.34.1-1 e também tenho 2mb. Seria possível inserir um marcador, por exemplo, vorbiscomment -a 't' METADATA_BLOCK_PICTURE = marcador 'file.ogg newfile.ogg, e depois ler algo no arquivo ogg e substituir o marcador pela imagem base64?
dmikalova
Absolutamente. Se você vir a especificação de formato de tag que vinculei, poderá usar o vorbiscomment para inserir uma imagem (pequena) temporária e, em seguida, gravar diretamente no arquivo que atualiza as duas últimas partes da tag - comprimento dos dados e os próprios dados. Obviamente, você terá que cortar algo juntos, no entanto.
sml 30/07/10
Estou testando o mutagen, uma biblioteca python de baixo nível para marcação de áudio e minha aparência preliminar parece que pode fazer o que eu preciso. Vou relatar quando descobrir as coisas.
dmikalova