Sematkan album art di OGG melalui command line di linux

15

Saya ingin mengubah musik saya dari flac ke ogg, dan saat ini oggenc melakukannya dengan sempurna kecuali untuk sampul album. Metaflac dapat menampilkan seni album, namun sepertinya tidak ada alat baris perintah untuk menanamkan seni album ke ogg. MP3Tag dan EasyTag dapat melakukannya, dan ada spesifikasi untuk itu di sini yang menyerukan agar gambar dienkode base64. Namun sejauh ini saya belum berhasil mengambil file gambar, mengubahnya menjadi base64 dan menanamkannya ke dalam file ogg.

Jika saya mengambil gambar yang disandikan base64 dari file ogg yang sudah memiliki gambar yang disematkan, saya dapat dengan mudah menanamkannya ke gambar lain menggunakan vorbiscomment:

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

Masalah saya adalah mengambil sesuatu seperti jpeg dan mengubahnya menjadi base64. Saat ini saya punya:

base64 --wrap=0 ./image.jpg

Yang memberi saya file gambar dikonversi ke base64, menggunakan vorbiscomment dan mengikuti aturan penandaan, saya bisa menanamkan itu ke dalam file ogg seperti:

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

Namun ini memberi saya sebuah ogg yang gambarnya tidak berfungsi dengan baik. Saya perhatikan ketika membandingkan string base64 bahwa semua gambar yang disematkan dengan benar memiliki baris header tetapi semua string base64 yang saya hasilkan kurang memiliki header ini. Analisis lebih lanjut dari tajuk:

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

Yang mengikuti spec yang diberikan di atas. Perhatikan 003 sesuai dengan sampul depan dan gambar / jpeg adalah tipe mime.

Jadi akhirnya, pertanyaan saya adalah, bagaimana saya bisa base64 menyandikan file dan menghasilkan header ini bersama dengan itu untuk menanamkan ke dalam file ogg?

dmikalova
sumber

Jawaban:

5

Saya baru saja menulis sebuah skrip yang mengekspor / mengimpor gambar dari file OGG / Vorbis menggunakan vorbiscomment. Ini adalah bagian dari alat konversi perpustakaan musik.

Script revelent ada dalam fungsi 'mussync-tools-transfert_images' dari alat ini:

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

Pada dasarnya, saya telah menulis pembaca dan penulis untuk format metadata_block_picture.

Kode ini cukup rumit:

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

Inilah solusi saya untuk / usr / bin / vorbiscomment: Daftar argumen masalah terlalu lama. Saya membuat skrip dan menamakannya oggart. Jalankan saja dari baris perintah seperti ini:

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

Ini menandai file ogg Anda dengan bidang METADATA_BLOCK_PICTURE. Easytag menggunakan cara lama melakukan ini dengan bidang COVERART alih-alih METADATA_BLOCK_PICTURE. Jika Anda ingin kompatibilitas Easytag maka Anda dapat menjalankan skrip seperti ini:

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

Ini skripnya:

#!/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
sumber
Script diposting lucu di sini. Anda dapat mengunduh oggart.tar.gz @ murga-linux.com/puppy/viewtopic.php?mode=attach&id=44270
Jason
Saya memperbaiki pemformatan skrip dalam posting.
Gaff
1
Jika Anda mendapatkan "Kesalahan sintaks:" ("tidak terduga" di Ubuntu, mungkin itu ada hubungannya dengan shell yang digunakan untuk menjalankan. Saya mengubah baris pertama menjadi #! / Bin / bash dan berhasil.
Dan Gravell
1
skrip ini tidak berfungsi untuk saya. Seperti yang saya lihat itu hanya menggunakan base64 dari gambar tetapi perlu ada header khusus sebelum itu
Sergey
2

Saya tidak mengetahui apa pun yang melakukannya secara otomatis dengan hanya menunjuk ke gambar.

Namun vorbiscomment dapat menyematkan tag arbitrer, Anda hanya perlu menyandikan gambar di base64 dan kemudian membuat tag dalam format yang benar .

misalnya vorbiscomment -a -t 'METADATA_BLOCK_PICTURE=...' file.ogg newfile.ogg

Anda harus meretas langkah-langkah ini menjadi semacam skrip agar bermanfaat.

sml
sumber
Ini bisa dilakukan, tetapi sayangnya jika gambar lebih dari 64kb maka vorbiscomments mengembalikan "/ usr / bin / vorbiscomment: Daftar argumen terlalu panjang". Ada yang tahu bagaimana menyiasatinya?
dmikalova
apa sistem Anda, dan apa outputnya getconf ARG_MAX? Sayangnya tidak ada cara untuk melewati batas ini tanpa mengkompilasi ulang kernel. Di sini, pada 64-bit 2.6.32-24, saya memiliki 2 MB.
sml
Saya menjalankan arch linux 64-bit 2.6.34.1-1 dan saya punya 2mb juga. Apakah mungkin untuk meletakkan marker misalnya vorbiscomment -a -t 'METADATA_BLOCK_PICTURE = file marker.ogg newfile.ogg, lalu minta sesuatu membaca file ogg dan mengganti marker dengan gambar base64?
dmikalova
Benar. Jika Anda melihat spesifikasi format tag yang ditautkan, Anda bisa menggunakan vorbiscomment untuk menyisipkan gambar sementara (kecil), dan kemudian langsung menulis ke file memperbarui dua bagian terakhir dari tag - panjang data, dan data itu sendiri. Namun, jelas Anda harus meretas sesuatu bersama.
sml
Saya mencoba mutagen, pustaka python tingkat rendah untuk penandaan audio dan sepertinya saya bisa melakukan apa yang saya butuhkan. Saya akan melaporkan kembali ketika saya memikirkan hal-hal di dalamnya.
dmikalova