通过Linux中的命令行在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

遵循上面给出的规格。注意003对应于封面,并且image / jpeg是mime类型。

所以最后,我的问题是,我如何对文件进行base64编码并生成此标头以将其嵌入到ogg文件中?

Answers:


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的解决方案:参数列表过长的问题。我创建了一个脚本,并将其命名为oggart。只需从命令行运行即可,如下所示:

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

这会使用METADATA_BLOCK_PICTURE字段标记您的ogg文件。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

脚本在这里很有趣。您可以在以下网址
Jason

我修复了帖子中的脚本格式。
加夫

1
如果你得到一个“语法错误:‘在Ubuntu(’意外”这可能是与被用来运行shell我改变了第一线#/斌/ bash和它的工作!
丹Gravell

1
该脚本不适用于我。正如我所看到的,它仅使用图像的base64,但在它之前需要有一个特殊的标头
Sergey

2

我不知道有什么可以仅通过指向图像来自动完成的。

但是,vorbiscomment可以嵌入任意标签,您只需要在base64中对图像进行编码,然后以正确的格式构建标签即可

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

您必须将这些步骤整理到某种脚本中才能有用。


这将是可行的,但可悲的是,如果图片超过64kb,则vorbiscomments返回“ / usr / bin / vorbiscomment:参数列表过长”。任何想法如何解决这个问题?
dmikalova 2010年

您的系统是什么,输出是getconf ARG_MAX什么?不幸的是,如果不重新编译内核,就无法解决这个限制。在64位2.6.32-24上,我有2 MB。
sml 2010年

我正在运行Arch Linux 64位2.6.34.1-1,我也有2mb。是否可以放入标记,例如vorbiscomment -a -t'METADATA_BLOCK_PICTURE = marker'file.ogg newfile.ogg,然后读取ogg文件并将标记替换为base64图像?
dmikalova

绝对。如果看到我链接的标签格式规范,则可以使用vorbiscomment插入一个临时(小)图像,然后直接写入文件以更新标签的最后两个部分-数据长度和数据本身。显然,您必须自己将某些东西一起砍掉。
sml 2010年

我正在尝试使用mutagen,这是一个用于音频标记的低级python库,我的初步想法似乎可以满足我的需求。我会在发现问题时报告。
dmikalova
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.