我想将我的音乐从 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
它给了我转换为 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 对应于封面,image/jpeg 是 mime 类型。
所以最后,我的问题是,如何对文件进行 base64 编码并生成此标头以嵌入到 ogg 文件中?
答案1
以下是我对 /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
答案2
我刚刚编写了一个脚本,使用 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}"
答案3
我不知道有什么东西可以只通过指向图像就能自动完成此操作。
然而评论可以嵌入任意标签,你只需要使用 base64 对图片进行编码进而以正确的格式构建标签。
例如vorbiscomment -a -t 'METADATA_BLOCK_PICTURE=...' file.ogg newfile.ogg
您必须将这些步骤修改为某种脚本才能使其有用。
答案4
和许多人一样,我也需要一种方法将图像放入 ogg 文件中。@Biapy 说得对,唯一办法是构建 metadata_block_picture blob。
虽然 Biapy 的解决方案极具启发性,但它的复杂之处仅在于难以理解。此外,它是针对每个文件的,我想要一个可以在相册的所有文件中使用的 base64 blob。因此,在 Biapy 的工作基础上,我编写了一个仅输出 base64 blob 的脚本。我担心宽度/高度检测,但到目前为止它还没有让我失望。