Вставити зображення альбому в OGG за допомогою командного рядка в Linux


15

Я хочу перетворити свою музику з flac в ogg, і в даний час oggenc робить це ідеально, крім альбому. Metaflac може виводити зображення альбому, однак, здається, немає інструменту командного рядка, який би вбудовував зображення альбому в ogg. Mp3Tag і EasyTag в змозі зробити це, і є специфікація для цього тут , який вимагає зображення , яке буде в кодуванні base64. Однак поки що мені не вдалося взяти файл зображення, перетворити його на base64 і вставити його у файл ogg.

Якщо я беру кодоване зображення base64 з файлу ogg, у якому вже вбудоване зображення, я можу легко вставити його в інше зображення, використовуючи vorbiscomment:

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

Моя проблема - взяти щось на зразок jpeg і перетворити його на base64. На даний момент у мене:

base64 --wrap=0 ./image.jpg

Що дає мені файл зображення, перетворений на base64, за допомогою vorbiscomment та дотримуючись правил тегування, я можу вставити це у файл ogg так:

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

Однак це дає мені ogg, зображення якого не працює належним чином. Я помітив, порівнюючи рядки base64, що на всіх правильно вбудованих зображеннях розміщено заголовок, але у всіх створених генерованих рядках base64 бракує цього заголовка. Подальший аналіз заголовка:

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

З чого випливає специфікація, наведена вище. Повідомлення 003 відповідає передній обкладинці, а зображення / jpeg - типу mime.

Отже, нарешті, моє питання полягає в тому, як я можу base64 кодувати файл і генерувати цей заголовок разом із ним для вбудовування у файл ogg?

Відповіді:


5

Я щойно написав сценарій, який експортує / імпортує зображення з файлів OGG / Vorbis за допомогою vorbiscomment. Це частина інструменту перетворення музичної бібліотеки.

Поважний сценарій знаходиться у функції 'mussync-tools-transfert_images' цього інструменту:

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

В основному, я написав читача і автора для формату metadata_block_picture.

Код досить складний:

      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}"

6

Ось моє рішення для / usr / bin / vorbiscomment: Аргумент занадто довгий проблема. Я створив сценарій і назвав його oggart. Просто запустіть його з командного рядка так:

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

Це позначає ваш файл ogg із полем METADATA_BLOCK_PICTURE. Easytag використовує старий спосіб робити це з полем COVERART замість METADATA_BLOCK_PICTURE. Якщо ви хочете сумісність Easytag, ви можете запустити сценарій так:

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

Ось сценарій:

#!/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

Сценарій розміщений тут смішно. Ви можете завантажити oggart.tar.gz @ murga-linux.com/puppy/viewtopic.php?mode=attach&id=44270
Jason

Я виправив форматування сценарію в публікації.
Гафф

1
Якщо у вас з'явилася "Syntax error:" ("несподівана" в Ubuntu, можливо, це стосується оболонки, яка використовується для запуску. Я змінив перший рядок на #! / Bin / bash, і він спрацював.
Dan Gravell,

1
цей сценарій не працює для мене. Як я бачу, він використовує лише base64 зображення, але перед ним повинен бути спеціальний заголовок
Сергій

2

Я не знаю нічого, що робить це автоматично, просто вказуючи на зображення.

Однак vorbiscomment може вставляти довільні теги, потрібно просто кодувати зображення в base64 і потім сконструювати тег у правильному форматі .

напр vorbiscomment -a -t 'METADATA_BLOCK_PICTURE=...' file.ogg newfile.ogg

вам доведеться зламати ці кроки в якийсь сценарій, щоб він був корисним.


Це може бути здійснено, але, на жаль, якщо картина перевищує 64 кб, тоді виртуальні коментарі повертаються "/ usr / bin / vorbiscomment: список аргументів занадто довгий". Будь-яка ідея, як обійти це?
dmikalova

що це за ваша система, і який результат getconf ARG_MAX? На жаль, немає можливості обійти це обмеження без повторної компіляції ядра. Тут на 64-розрядному 2.6.32-24 у мене є 2 МБ.
sml

Я запускаю аркуш Linux 64-розрядний 2.6.34.1-1 і в мене також є 2mb. Чи можна було б поставити маркер, наприклад, vorbiscomment -a -t 'METADATA_BLOCK_PICTURE = маркер' file.ogg newfile.ogg, а потім щось прочитати файл ogg та замінити маркер зображенням base64?
dmikalova

Абсолютно. Якщо ви бачите специфікацію, з якою я пов’язаний формат тегів, ви можете використовувати vorbiscomment, щоб вставити тимчасове (невелике) зображення, а потім безпосередньо записати у файл оновлення двох останніх частин тегу - довжина даних та самі дані. Очевидно, вам доведеться щось зламати разом.
sml

Я випробовую мутаген, бібліотеку пітонів низького рівня для тегування звуку, і мої попередні погляди здаються, що він може робити все, що мені потрібно. Я звітну, коли розберуся в ньому.
dmikalova
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.