0

My system is Windows and I use Cygwin to run bash and shell file. Check a script, see the link below, which according to its author creates the metadata of an image to be attached to the ogg file, it happens that the script is generating incomplete data.

I did some tests with the first script posted by @Gaff here:Embed album art in OGG through command line in linux that do not generate the metadata correctly, see the tests below:

Metadata block picture results according to defined option in the $EASYTAG variable of the script.

Note:

When we run the script without the -e parameter at the end, the $EASYTAG variable will have the value of N and when we run the script with the -e parameter at the end, the $EASYTAG variable will have the Y value.

Script execution command without -e at the end :

sh oggart.sh "audio.ogg" "cover.jpg"

Output ffprobe in audio file with option $EASYTAG variable = N, generated by the script:

[ogg @ 0000023748f0f300] Invalid picture type: -2555936.
[ogg @ 0000023748f0f300] Could not read mimetype from an attached picture.
Input #0, ogg, from 'audio.ogg':
  Duration: 00:03:26.60, start: 0.000000, bitrate: 402 kb/s
  Stream #0:0: Audio: vorbis, 44100 Hz, stereo, fltp, 320 kb/s
    Metadata:
      encoder         : Lavc59.12.100 libvorbis
      album           : CMG Clássicos Pop Rock Nacionais
      artist          : Lobão
      date            : 1988
      genre           : Clássico Pop Rock Nacional
      TKEY            : E m
      title           : Cuidado!

Script execution command with -e at the end :

sh oggart.sh "audio.ogg" "cover.jpg" -e

Output ffprobe in audio file with option $EASYTAG variable = Y, generated by the script:

Input #0, ogg, from 'audio.ogg':
  Duration: 00:03:26.60, start: 0.000000, bitrate: 402 kb/s
  Stream #0:0: Audio: vorbis, 44100 Hz, stereo, fltp, 320 kb/s
    Metadata:
      encoder         : Lavc59.12.100 libvorbis
      album           : CMG Clássicos Pop Rock Nacionais
      artist          : Lobão
      date            : 1988
      genre           : Clássico Pop Rock Nacional
      TKEY            : E m
      title           : Cuidado!
      COVERART        : /9j/4AAQSkZJRgABAQEASABIAAD/4ROiRXhpZgAASUkqAAgAAAACADIBAgAUAAAAJ
                        gAAAGmHBAABAAAAOgAAAEAAAAAyMDE5OjEwOjE4IDEzOjU4OjU5AAAAAAAAAAMAAw
                        EEAAEAAAAGAAAAAQIEAAEAAABqAAAAAgIEAAEAAAAwEwAAAAAAAP/Y/+AAEEpGSUY
                        AAQEAAAEAAQAA/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcUGBg

In $EASYTAG = N show:

[ogg @ 0000023748f0f300] Invalid picture type: -2555936.
[ogg @ 0000023748f0f300] Could not read mimetype from an attached picture.

In $EASYTAG = Y, does not show an error message, but includes the COVERART in a Metadata field with incomplete data:

COVERART        : /9j/4AAQSkZJRgABAQEASABIAAD/4ROiRXhpZgAASUkqAAgAAAACADIBAgAUAAAAJ
                  gAAAGmHBAABAAAAOgAAAEAAAAAyMDE5OjEwOjE4IDEzOjU4OjU5AAAAAAAAAAMAAw
                  EEAAEAAAAGAAAAAQIEAAEAAABqAAAAAgIEAAEAAAAwEwAAAAAAAP/Y/+AAEEpGSUY
                  AAQEAAAEAAQAA/9sAQwAGBAUGBQQGBgUGBwcGCAoQCgoJCQoUDg8MEBcUGBg

Note: The COVERAT field shows only the first 255 characters of the generated metadata block picture... this may be happening precisely because of the lack information in the data block related to the identification of the file, that is in its header, where the program identifies the record and inserts it correctly as a cover art in the file.

The ogg metadata block picture structure appears to be the same as flac's.

Script is generating incomplete metadata block picture, seems to be missing metadata header. Note below, mainly, the information in --add padding. The script doesn't seem to be considering the 4 bytes when generating the metadata block picture.

--import-picture-from={FILENAME|SPECIFICATION}  
Import a picture and store it in a PICTURE metadata block. 
See the flac option --picture for an explanation of the SPECIFICATION syntax.

--add-padding=# 
Add a padding block of the given length (in bytes). The overall length of the new 
block will be 4 + length; the extra 4 bytes is for the metadata block header.
  
  Note: Maybe that's the problem with your file not being generated with the header.

--dont-use-padding  
By default metaflac tries to use padding where possible to avoid rewriting the entire 
file if the metadata size changes. Use this option to tell metaflac to not take 
advantage of padding this way.

Note: Another possibility of metadata generation error, look here: https://github.com/taglib/taglib

Is there no ffmpeg function or program that does the conversion correctly so that it can be used in a batch file?

@Tom Yan, first i wanted to thank you for your post, because it was exactly what I was looking for many days, thank you!

I followed your step by step to run vorbis_ca, but I had some problems:

Step 1:

I created a folder called Vorbis in the following path:
C:\Users\CMG\Vorbis

I copied the vorbis_ca.c into the Vorbis folder and compiled the file:
gcc vorbis_ca.c -o vorbis_ca.exe

I changed the path to my desktop, which is where the image is on my PC:
cd "C:/Users/CMG/Desktop"

I ran the file command on the image:
file cover.jpeg

Output file command:

Exif Standard: [TIFF image data, little-endian, direntries=2, datetime=2019:10:18 13:58:59], baseline, 
precision 8, 1018x1023, components 3

Step 2:

I ran the ./vorbis_ca command:
$ ./vorbis_ca 1018 1023 cover.jpeg | hexdump -C

Output ./vorbis_ca command:
-bash: ./vorbis_ca: No such file or directory

so i tried:

"C:/Users/CMG/Vorbis/"./vorbis_ca 1018 1023 cover.jpeg | hexdump -C

Output ./vorbis_ca command inserting full path:

00000000  00 00 00 03 00 00 00 09  69 6d 61 67 65 2f 6a 70  |........image/jp|
00000010  67 00 00 00 00 00 00 03  fa 00 00 03 ff 00 00 00  |g...............|
00000020  18 00 00 00 00 00 04 39  24                       |.......9$|
00000029

./vorbis_ca only runs when I put the full path.

Note:

When I compiled the vorbis_ca.c which is in the folder in the path: C:\Users\CMG\Vorbis I can't run the generated ./vorbis_ca in any location, how to make ./vorbis_ca run without me having to put the full path? eg. in the file cover.jpeg command, I didn't need to put the full path of it for it to work.

Step 3:

Run vorbiscomment command: note that I had to put the full path of ./vorbis_ca in this command.

$ vorbiscomment -w -t "METADATA_BLOCK_PICTURE=$(("C:/Users/CMG/Vorbis/"./vorbis_ca 1018 1023 cover.jpeg; cat cover.jpeg) | base64 -w 0)" "audio_cover.ogg"

Output vorbiscomment command:

-bash: /cygdrive/c/vorbis-tools-master/bin/x64/vorbiscomment: Argument list too long

Why did the above message appear when I ran vorbiscomment?

Another question: in Step 2, I ran the command ./vorbis_ca 1018 1023 cover.jpeg | hexdump -C and your last command again has the ./vorbis_ca 1018 1023 cover.jpeg. This command needs to be run twice, or did you just show it in detail as an example?

That is, the official command is the last command, correct?

Clamarc
  • 593
  • 1
  • 5
  • 21
  • 1
    Would you mind adding what your question is? – mashuptwice Mar 14 '22 at 02:09
  • @Clamarc Just downvote the answer over there if you find it wrong / not useful. For the record, `METADATA_BLOCK_PICTURE` should consists of more than just the image file: https://xiph.org/flac/format.html#metadata_block_picture – Tom Yan Mar 14 '22 at 02:19
  • @TomYan I don't see any reason to downvote the answer according to the [guideline](https://superuser.com/help/privileges/vote-down) (Downvotes should be used to indicate issues with quality, effort, or accuracy of a post). Note that OP doesn't even have the privileges to downvote. Also note that the question is missing basic information, like that OP is using cygwin on windows, full commands, example data and he basically asks for a software recommendation. – mashuptwice Mar 14 '22 at 02:56
  • @mashuptwice The post is not related to problems regarding the use of Cygwin or the errors regarding the execution of the script, which is duly informed in the link, the post refers only to the results of the script regarding the creation of the metadata. If my question is about that alone, there's no point in mentioning things I have no doubts about. The programs I mentioned, not related to commercial programs, but packages or some tool that can do the correct conversion of the metadata. eg. exiv2 tool, ExifTool...etc. – Clamarc Mar 14 '22 at 07:24
  • @mashuptwice As I implied, as far as I'm concerned there's apparently a `quality / accuracy of a post` problem in the linked answer. Whether @Clamarc want to just downvote because it doesn't work, or research / confirm it is wrong before downvoting, or comment instead/before/after downvoting, or simply ignore the answer is entirely his choice. And again, as far as I'm concerned, it makes more sense to do *any* of those instead of posting a "question" to point out there's a apparent problem in the answer. (As you suggested, this is not exactly a question, not even from a general perspective.) – Tom Yan Mar 14 '22 at 08:04
  • TL;DR, this is not a bug report site. Not even one for answers in another question. – Tom Yan Mar 14 '22 at 08:05
  • @mashuptwice Ok, I understand what you're saying, is that since the script post is very old and I didn't know how to refer to it, I posted the tests I did thinking that someone could help me with this. – Clamarc Mar 14 '22 at 08:17
  • @TomYan In my case, how should I go about asking or posting a question that interests me in an old post that is no longer being discussed? – Clamarc Mar 14 '22 at 08:21
  • If I were you I'll just ask away how to *properly* embed a picture onto an ogg vorbis file with `vorbiscomment`, even though it might get marked as duplicate because of similar questions answered with only poor answers. (With that said, consider looking for / into other answers in the question you linked / other similar questions before you do so. Even better, get to understand the actual specifications of the file format instead relying on random scripts you found on this site. Some of them could be awful even when the votes are high.) – Tom Yan Mar 14 '22 at 09:00
  • @Clamarc FFmpeg supports only parsing/decoding `METADATA_BLOCK_PICTURE` in Ogg Vorbis: https://github.com/FFmpeg/FFmpeg/search?q=METADATA_BLOCK_PICTURE. You might be find a patch somewhere though. – Tom Yan Mar 14 '22 at 11:59

1 Answers1

1

As I mentioned in my comment, METADATA_BLOCK_PICTURE is not expected to consists of just the image file. You need to "prefix" the image file with some more metadata bytes as per the specification:

Here's an example C program that outputs such a prefix:

$ ./vorbis_ca 
Usage: ./vorbis_ca width height image_file

The image width and height can be obtained with e.g. file (note that they are near the end of the output; not to be confused with density):

$ file test_ca.jpg 
test_ca.jpg: JPEG image data, JFIF standard 1.01, resolution (DPI), density 300x300, segment length 16, comment: "Created with GIMP", progressive, precision 8, 600x600, components 3

Using hexdump -C to see what (bytes) it actually outputs:

$ ./vorbis_ca 600 600 test_ca.jpg | hexdump -C
00000000  00 00 00 03 00 00 00 09  69 6d 61 67 65 2f 6a 70  |........image/jp|
00000010  67 00 00 00 00 00 00 02  58 00 00 02 58 00 00 00  |g.......X...X...|
00000020  18 00 00 00 00 00 00 37  e6                       |.......7.|
00000029

(FFmpeg doesn't really care about the width and height in the prefix though, so you may as well just use 0 for both of them if you don't care about standard conformance / portability of the file)

Reproducing the problem you bumped into:

$ vorbiscomment -w -t "METADATA_BLOCK_PICTURE=$(cat test_ca.jpg | base64 -w 0)" test.ogg 
$ ffprobe /tmp/test.ogg 
ffprobe version n5.0 Copyright (c) 2007-2022 the FFmpeg developers
  built with gcc 11.2.0 (GCC)
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-amf --enable-avisynth --enable-cuda-llvm --enable-lto --enable-fontconfig --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libdav1d --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libiec61883 --enable-libjack --enable-libmfx --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librav1e --enable-librsvg --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-libzimg --enable-nvdec --enable-nvenc --enable-shared --enable-version3
  libavutil      57. 17.100 / 57. 17.100
  libavcodec     59. 18.100 / 59. 18.100
  libavformat    59. 16.100 / 59. 16.100
  libavdevice    59.  4.100 / 59.  4.100
  libavfilter     8. 24.100 /  8. 24.100
  libswscale      6.  4.100 /  6.  4.100
  libswresample   4.  3.100 /  4.  3.100
  libpostproc    56.  3.100 / 56.  3.100
[ogg @ 0x55910a096700] Invalid picture type: -2555936.
[ogg @ 0x55910a096700] Could not read mimetype from an attached picture.
Input #0, ogg, from '/tmp/test.ogg':
  Duration: 00:00:10.00, start: 0.000000, bitrate: 19 kb/s
  Stream #0:0: Audio: vorbis, 44100 Hz, stereo, fltp, 112 kb/s

With the prefix added, problem solved:

$ vorbiscomment -w -t "METADATA_BLOCK_PICTURE=$((./vorbis_ca 600 600 test_ca.jpg; cat test_ca.jpg) | base64 -w 0)" test.ogg 
$ ffprobe /tmp/test.ogg 
ffprobe version n5.0 Copyright (c) 2007-2022 the FFmpeg developers
  built with gcc 11.2.0 (GCC)
  configuration: --prefix=/usr --disable-debug --disable-static --disable-stripping --enable-amf --enable-avisynth --enable-cuda-llvm --enable-lto --enable-fontconfig --enable-gmp --enable-gnutls --enable-gpl --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libdav1d --enable-libdrm --enable-libfreetype --enable-libfribidi --enable-libgsm --enable-libiec61883 --enable-libjack --enable-libmfx --enable-libmodplug --enable-libmp3lame --enable-libopencore_amrnb --enable-libopencore_amrwb --enable-libopenjpeg --enable-libopus --enable-libpulse --enable-librav1e --enable-librsvg --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libssh --enable-libsvtav1 --enable-libtheora --enable-libv4l2 --enable-libvidstab --enable-libvmaf --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxcb --enable-libxml2 --enable-libxvid --enable-libzimg --enable-nvdec --enable-nvenc --enable-shared --enable-version3
  libavutil      57. 17.100 / 57. 17.100
  libavcodec     59. 18.100 / 59. 18.100
  libavformat    59. 16.100 / 59. 16.100
  libavdevice    59.  4.100 / 59.  4.100
  libavfilter     8. 24.100 /  8. 24.100
  libswscale      6.  4.100 /  6.  4.100
  libswresample   4.  3.100 /  4.  3.100
  libpostproc    56.  3.100 / 56.  3.100
Input #0, ogg, from '/tmp/test.ogg':
  Duration: 00:00:10.00, start: 0.000000, bitrate: 19 kb/s
  Stream #0:0: Audio: vorbis, 44100 Hz, stereo, fltp, 112 kb/s
  Stream #0:1: Video: mjpeg (Progressive), yuvj444p(pc, bt470bg/unknown/unknown), 600x600 [SAR 300:300 DAR 1:1], 90k tbr, 90k tbn (attached pic)
    Metadata:
      comment         : Cover (front)
$ 

(Note that the prefix is base64-encoded as well)

Tom Yan
  • 9,075
  • 2
  • 17
  • 36
  • i did some tests following this post but I had some problems I edited the post of my question and put the tests there, is this correct? – Clamarc Mar 15 '22 at 06:04
  • Most of your new doubts are irrelevant to the original problem though, such as `PATH` question (for either Windows or cygwin) or apparent cygwin-specific bash issue. If you look at the code of the example program, it writes the generated "prefix" to standard output (the image file is only passed to it for the file size probing) so it does not cause any changes to any file, no matter how many times you run it, and the `hexdump` part was meant to show you this fact (and what the program outputs). – Tom Yan Mar 15 '22 at 09:37
  • Ah actually the bash error might be due to the fact that the image you used was much larger than what I used in my test. You can probably use something like `(echo -n METADATA_BLOCK_PICTURE=; (./vorbis_ca 600 600 test_ca.jpg; cat test_ca.jpg) | base64 -w 0) > tagfile` and use `-c tagfile` for `vorbiscomment` instead of `-t ...`. – Tom Yan Mar 15 '22 at 09:43
  • @Clamarc For the record, the program is only meant to be an example. Renaming a TIFF with the extension name `jpeg` does not make any difference. If you really want the file to be *correct*, at least make a change to the hard coded mime type in the program. (There seems to be a peculiar relationship between TIFF and JPEG though...not familiar with it.) – Tom Yan Mar 15 '22 at 09:52
  • in the code there is a field named char mime_type, which has the value image/jpg. I just change it to image/tiff for the correction you mentioned, is that it? – Clamarc Mar 15 '22 at 17:14
  • yeah that's what I meant – Tom Yan Mar 15 '22 at 19:29
  • I ran the command vorbiscomment -w -c tagfile (echo -n METADATA_BLOCK_PICTURE=;... changing the -t to -c tagfile as you indicated, but the message appears -bash: syntax error near unexpected token `(' – Clamarc Mar 16 '22 at 20:01
  • `(echo -n METADATA_BLOCK_PICTURE=; (./vorbis_ca 600 600 test_ca.jpg; cat test_ca.jpg) | base64 -w 0) > tagfile` is supposed to be a *separate* command that that *you run before running `vorbiscomment`* to create a file called `tagfile`, which in turn can be used for `-c` of `vorbiscomment`. Please get to understand what the commands are doing (and perhaps, read more carefully, or even familiarize yourself with bash first). – Tom Yan Mar 17 '22 at 02:12
  • OK, it worked... really since I downloaded cygwin on my PC I'm studying to improve, sorry for not correctly understanding something you say, it's just that I'm from Brazil and sometimes, even with the internet, something It's a little misunderstood by me. The vorbis_ca doesn't generate the information of tags like Album, Singer, Name of the song, ... I'll study more to be able to change the vorbis_ca and be able to recover this information from the original file to the tagfile, thanks! – Clamarc Mar 17 '22 at 04:24
  • No it does not. The example program serves merely for the purpose of showing what prefix bytes are needed for the image that is being embedded as `METADATA_BLOCK_PICTURE`. With that said, you can prepend/append the extra tags you want to `tagfile`. See the difference between `>` and `>>` in bash and/or that between `-w` and `-a` of `vorbiscomment`. (You can/should always read the man page.) – Tom Yan Mar 17 '22 at 04:55
  • Ok, I'll do this later, now it's 2 o'clock on Thursday morning, I'll try to get some sleep, I have insomnia problems!. thank you for the help. – Clamarc Mar 17 '22 at 05:20
  • With this command: echo "$(cat comments.txt tagfile.txt)" > tagfile.txt, I was able to add the rest of the information I want in the tagfile. Is there a way to join it with your command (echo -n METADATA_BLOCK_PICTURE=;... so that it does everything on a single line? – Clamarc Mar 17 '22 at 22:44
  • You really just need to put `cat comments.txt; ` before `echo -n METADATA_BLOCK_PICTURE=; ...` (inside the first pair of parentheses). Make sure `comments.txt` has a trailing newline btw. – Tom Yan Mar 18 '22 at 02:20
  • OK, it worked!... I did some tests and realized that both in creating the tagfile, when adding the cover art in the audio ogg, if any of them have the exclamation mark in the name, the program cancels. Of course, it is enough for me to remove the exclamation mark and it will work, but there was this doubt as to why this happens? – Clamarc Mar 18 '22 at 06:57
  • Probably has something to do with https://www.gnu.org/software/bash/manual/html_node/History-Interaction.html, i.e. you didn't escape the exclamation mark properly – Tom Yan Mar 18 '22 at 07:57
  • got the exclamation mark problem, just putting the name in single quotes works. Thank you for your help. – Clamarc Mar 18 '22 at 08:43
  • hi, a question, I use cigwin and all the commands we did, I did it via the terminal screen. I tested the commands via the dos prompt as follows: I change the directory to where the ogg audio files and the image are, then I run the command to create the tagfile and the message ```base64: invalid wrap size: '0) '``` and below it, tells all commands on the ``` No such file or directory``` line. Can I run this command at the prompt, or can it only be run via terminal, which is where it normally works? – Clamarc Mar 20 '22 at 11:49
  • Unless in this "dos prompt" you are still running bash, then no, as the commands were written with bash in mind. While your *programs* (i.e. `cat`, `file`, `vorbiscomment`, `base64` and maybe even `vorbis_ca`; but not `echo`) might be built in a way such that it can be used natively in Windows (I mean like no Cygwin dll required but MinGW builds), if you are not in bash, you'll still need to rewrite the command lines with whatever syntax that is suitable (probably https://en.wikipedia.org/wiki/Batch_file#Windows_NT / https://en.wikipedia.org/wiki/Cmd.exe). – Tom Yan Mar 20 '22 at 14:48
  • Yam OK, it was just to know if it was just changing the cigwin path to some place where the prompt could also execute the programs cat, vorbis_ca, etc... thanks – Clamarc Mar 20 '22 at 15:27
  • I'm not sure if most of the programs that were built for cygwin can be run directly in `cmd.exe`. They might work to a certain extent but it's likely that with at least some of them, you would bump into problems (less likely with relatively more simple programs like `cat` though). In the case of msys2, the build variants in its MinGW repos can pretty much be considered "native" Windows programs and can most likely work fine in `cmd.exe`. However, not all programs have MinGW builds there either (and not all programs can have MinGW builds, AFAIK, at least not without heavy modification). – Tom Yan Mar 20 '22 at 16:19