Osadzanie okładek albumów w OGG za pomocą wiersza poleceń w systemie Linux

15

Chcę przekonwertować moją muzykę z flac na ogg, a obecnie oggenc robi to doskonale, z wyjątkiem okładek albumów. Metaflac może wyświetlać okładki albumów, jednak wydaje się, że nie ma narzędzia wiersza poleceń do osadzania okładek albumów w OGG. MP3tag i EasyTAG są w stanie to zrobić, i nie ma na to specyfikacja tutaj który domaga obraz ma być zakodowane base64. Jednak jak dotąd nie udało mi się pobrać pliku obrazu, przekonwertować go na base64 i osadzić w pliku ogg.

Jeśli pobiorę obraz zakodowany w standardzie base64 z pliku ogg, który ma już osadzony obraz, mogę łatwo osadzić go w innym obrazie za pomocą vorbiscomment:

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

Moim problemem jest pobranie czegoś w rodzaju pliku JPEG i przekonwertowanie go na base64. Obecnie mam:

base64 --wrap=0 ./image.jpg

Co daje mi plik obrazu przekonwertowany na base64, przy użyciu vorbiscomment i zgodnie z regułami tagowania, mogę osadzić go w pliku ogg w następujący sposób:

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

Jednak daje mi to ogg, którego obraz nie działa poprawnie. Zauważyłem podczas porównywania ciągów base64, że wszystkie poprawnie osadzone obrazy mają linię nagłówka, ale wszystkie ciągi base64, które generuję, nie mają tego nagłówka. Dalsza analiza nagłówka:

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

Który jest zgodny ze specyfikacją podaną powyżej. Uwaga 003 odpowiada przedniej okładce, a image / jpeg to typ MIME.

Wreszcie moje pytanie brzmi: w jaki sposób mogę zakodować plik base64 i wygenerować ten nagłówek wraz z nim do osadzenia w pliku ogg?

dmikalova
źródło

Odpowiedzi:

5

Właśnie napisałem skrypt, który eksportuje / importuje obrazy z plików OGG / Vorbis za pomocą vorbiscomment. Jest to część narzędzia do konwersji biblioteki muzycznej.

Rewelacyjny skrypt znajduje się w funkcji „mussync-tools-transfert_images” tego narzędzia:

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

Zasadniczo napisałem czytnik i pisarz dla formatu metadata_block_picture.

Kod jest dość złożony:

      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}"
Biapy
źródło
6

Oto moje rozwiązanie problemu / usr / bin / vorbiscomment: zbyt długa lista argumentów. Stworzyłem skrypt i nazwał go oggart. Po prostu uruchom go z wiersza poleceń w następujący sposób:

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

To oznacza twój plik ogg polem METADATA_BLOCK_PICTURE. Easytag używa starego sposobu robienia tego z polem COVERART zamiast METADATA_BLOCK_PICTURE. Jeśli chcesz mieć kompatybilność z Easytag, możesz uruchomić skrypt w następujący sposób:

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

Oto skrypt:

#!/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
źródło
Skrypt opublikowany tutaj zabawnie. Możesz pobrać oggart.tar.gz @ murga-linux.com/puppy/viewtopic.php?mode=attach&id=44270
Jason
Naprawiłem formatowanie skryptu w poście.
Gaff
1
Jeśli pojawi się komunikat „Błąd składni:” („nieoczekiwany” w Ubuntu, prawdopodobnie jest to związane z uruchomioną powłoką. Zmieniłem pierwszą linię na #! / Bin / bash i zadziałało.
Dan Gravell
1
ten skrypt nie działa dla mnie. Jak widzę, wykorzystuje on tylko base64 obrazu, ale musi być przed nim specjalny nagłówek
Sergey
2

Nie jestem świadomy niczego, co robi to automatycznie, po prostu wskazując na obraz.

Jednak vorbiscomment może osadzać dowolne znaczniki, wystarczy zakodować obraz w base64, a następnie skonstruować znacznik we właściwym formacie .

na przykład vorbiscomment -a -t 'METADATA_BLOCK_PICTURE=...' file.ogg newfile.ogg

będziesz musiał zhakować te kroki do jakiegoś skryptu, aby był on użyteczny.

sml
źródło
Byłoby to wykonalne, ale niestety, jeśli obraz ma ponad 64 KB, vorbiscomments zwraca „/ usr / bin / vorbiscomment: Lista argumentów za długa”. Masz pomysł, jak to obejść?
dmikalova
jaki jest twój system i jaka jest wydajność getconf ARG_MAX? Niestety nie można obejść tego ograniczenia bez ponownej kompilacji jądra. Tutaj na 64-bitowej wersji 2.6.32-24 mam 2 MB.
sml
Korzystam z arch linux 64-bit 2.6.34.1-1 i mam również 2 MB. Czy można wstawić znacznik, np. Vorbiscomment -a -t 'METADATA_BLOCK_PICTURE = marker' file.ogg newfile.ogg, a następnie odczytać plik ogg i zastąpić znacznik obrazem base64?
dmikalova
Absolutnie. Jeśli zobaczysz specyfikację formatu tagu, którą połączyłem, możesz użyć vorbiscomment, aby wstawić tymczasowy (mały) obraz, a następnie bezpośrednio zapisać w pliku aktualizując dwie ostatnie części tagu - długość danych i same dane. Oczywiście musisz jednak samodzielnie zhakować coś.
sml
Próbuję mutagenu, niskopoziomowej biblioteki Pythona do znakowania audio, a mój wstępny wygląd wydaje się, że może zrobić to, czego potrzebuję. Zamelduję się, kiedy się zorientuję.
dmikalova