리눅스에서 커맨드 라인을 통해 OGG에 앨범 아트를 포함


15

내 음악을 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

위의 사양을 따릅니다. Notice 003은 앞 표지에 해당하며 image / jpeg는 MIME 유형입니다.

마지막으로, 내 질문은 어떻게 파일을 base64로 인코딩하고 ogg 파일에 포함시키기 위해이 헤더와 함께 헤더를 생성 할 수 있습니까?

답변:


5

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

6

/ usr / bin / vorbiscomment : Argument list too long problem에 대한 해결책은 다음과 같습니다. 스크립트를 작성하고 이름을 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

이 스크립트는 여기에 재미있었습니다. oggart.tar.gz @ murga-linux.com/puppy/viewtopic.php?mode=attach&id=44270
Jason

게시물에서 스크립트 형식을 수정했습니다.
Gaff

1
우분투에서 "구문 오류 :"( "예기치 않은")가 발생하면 아마도 셸을 실행하는 데 사용 된 것일 수 있습니다. 첫 번째 줄을 #! / bin / bash로 변경하고 작동했습니다.
Dan Gravell

1
이 스크립트는 나를 위해 작동하지 않습니다. 내가 볼 수 있듯이 이미지의 base64만을 사용하지만 그 전에 특별한 헤더가 필요합니다
Sergey

2

이미지를 가리키면 자동으로 수행되는 작업을 알지 못합니다.

그러나 vorbiscomment 는 임의의 태그를 포함 할 수 있으므로 base64로 이미지인코딩 한 다음 올바른 형식으로 태그구성하면됩니다 .

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

이 단계를 유용한 스크립트로 해킹해야합니다.


이것은 가능하지만 슬프게도 그림이 64kb를 초과하면 vorbiscomments는 "/ usr / bin / vorbiscomment : Argument list too long"을 반환합니다. 이 문제를 해결하는 방법에 대한 아이디어가 있습니까?
dmikalova

당신의 시스템은 무엇이며, 결과는 getconf ARG_MAX무엇입니까? 불행히도 커널을 다시 컴파일하지 않으면이 한계를 극복 할 방법이 없습니다. 여기 64 비트 2.6.32-24에는 2MB가 있습니다.
sml

아치 리눅스 64 비트 2.6.34.1-1을 실행 중이며 2MB도 있습니다. vorbiscomment -a -t 'METADATA_BLOCK_PICTURE = marker'file.ogg newfile.ogg와 같은 마커를 넣을 수 있습니까? 그런 다음 ogg 파일을 읽고 마커를 base64 이미지로 바꾸십시오.
dmikalova

물론. 내가 링크 한 태그 형식 사양이 표시되면 vorbiscomment를 사용하여 임시 (작은) 이미지를 삽입 한 다음 태그의 마지막 두 부분 (데이터 길이 및 데이터 자체)을 업데이트하는 파일에 직접 쓸 수 있습니다. 그러나, 당신은 스스로 무언가를 해킹해야합니다.
sml

오디오 태깅을위한 저수준 파이썬 라이브러리 인 mutagen을 시도하고 있으며 예비 모습은 필요한 것을 할 수있는 것처럼 보입니다. 내가 알아낼 때 다시보고하겠습니다.
dmikalova
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.