web-dev-qa-db-ja.com

LinuxのコマンドラインからOGGにアルバムアートを埋め込む

音楽をflacからoggに変換したいのですが、現在oggencはアルバムアートを除いて完全に変換しています。 Metaflacはアルバムアートを出力できますが、アルバムアートをoggに埋め込むためのコマンドラインツールはないようです。 MP3TagとEasyTagはそれを行うことができ、その仕様があります ここ これは画像をbase64でエンコードすることを要求します。しかし、これまでのところ、画像ファイルを取得してbase64に変換し、oggファイルに埋め込むことができませんでした。

すでに画像が埋め込まれているoggファイルからbase64でエンコードされた画像を取得する場合、vorbiscommentを使用して別の画像に簡単に埋め込むことができます。

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

私の問題は、jpegのようなものをbase64に変換することです。現在私は持っています:

base64 --wrap=0 ./image.jpg

これにより、vorbiscommentを使用し、タグ付けルールに従って、base64に変換された画像ファイルが得られます。これを次のように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は表紙に対応し、image/jpegはmimeタイプです。

最後に、私の質問は、ファイルをbase64でエンコードし、oggファイルに埋め込むためにこのヘッダーを一緒に生成するにはどうすればよいですか?

15
dmikalova

vorbiscommentを使用してOGG/Vorbisファイルから画像をエクスポート/インポートするスクリプトを作成しました。これは、音楽ライブラリ変換ツールの一部です。

啓示的なスクリプトは、このツールの「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}"
5
Biapy

/ usr/bin/vorbiscommentの解決策は次のとおりです。引数リストが長すぎる問題。スクリプトを作成し、oggartという名前を付けました。次のようにコマンドラインから実行するだけです。

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

これにより、oggファイルにMETADATA_BLOCK_PICTUREフィールドのタグが付けられます。 Easytagは、METADATA_BLOCK_PICTUREの代わりにCOVERARTフィールドでこれを行う古い方法を使用します。 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
6
Jason

画像をポイントするだけで自動的に行われることは何も知りません。

ただし、 vorbiscomment は任意のタグを埋め込むことができます。必要なのは、 base64で画像をエンコード してから 正しい形式でタグを作成する です。

例:vorbiscomment -a -t 'METADATA_BLOCK_PICTURE=...' file.ogg newfile.ogg

これらの手順を何らかのスクリプトにハックして、役立つようにする必要があります。

2
sml