5

Question

I have 2 files:

  • audio.opus (extension also possible: .opus.ogg),
  • cover.jpg.

How can I use ffmpeg to put cover.jpg as an embedded "cover" image into audio.opus?

Constraints

  • I don't want to re-encode the audio (so unfortunately, opusenc --picture seems out of scope),
  • I don't want to re-encode the image (jpeg), although that's not much of a problem,
  • I don't want to transform the image into a video (!),
  • I'd really prefer doing it with ffmpeg and not another tool,
  • I don't want to hear about mp3.

Expected result

Here is how it should look like when it's properly done:

$ opusinfo audio_with_cover.opus
Processing file "audio_with_cover.opus"...

New logical stream (#1, serial: 39a74bbb): type opus
Encoded with libopus 1.3.1
User comments section follows...
    ENCODER=opusenc from opus-tools 0.1.10
    METADATA_BLOCK_PICTURE=3|image/jpeg||1280x720x24|<45952 bytes of image data>
    ENCODER_OPTIONS=--bitrate 56
Opus stream 1:
    Pre-skip: 312
    [...]

Or seen from ffprobe:

$ ffprobe audio_with_cover.opus 
[ogg @ 0x55675650ca80] 761 bytes of comment header remain
Input #0, ogg, from 'audio_with_cover.opus':
  Duration: 00:02:25.64, start: 0.000000, bitrate: 71 kb/s
  Stream #0:0: Audio: opus, 48000 Hz, stereo, fltp
    Metadata:
      ENCODER         : opusenc from opus-tools 0.1.10
      ENCODER_OPTIONS : --bitrate 56
  Stream #0:1: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 1280x720, 90k tbr, 90k tbn (attached pic)
    Metadata:
      comment         : Cover (front)

Not possible?

If you know it is not possible, please let me know, I will open a feature request at ffmpeg.

2

2 Answers 2

1

I could not find a simple working solution with ffmpeg, so I turned to opustags, an easy to use opus tag editor. Install opustags with sudo apt install opustags or something similar in your distribution.
To add the cover art, use the command, opustags --set-cover cover.jpg audio.opus -i, to quickly add the cover art to the opus file.
As a quick bonus, you can extract cover art with opustags --output-cover cover.jpg audio.opus.

Second solution

When I said working solution with ffmpeg, I meant not re-encoding the JPEG file, but you don't mind that too much. I have found a solution with ffmpeg that re-encodes the image, but keeps the OPUS file. The drawback of re-encoding the image is that the quality of the cover art is extremely compressed. I could not find any way to make the jpeg image high quality. The command is: ffmpeg -i audio.ogg -i cover.jpg -c:a copy -disposition attached_pic audio_1.ogg.

Edit for second solution

To make a high(er) quality thumbnail for the ffmpeg solution, you can set the CRF of the image that is converted to a Theora file to 2 with ffmpeg -i audio.ogg -i cover.jpg -c:a copy -q:v 2 -disposition attached_pic audio_1.ogg. Because the Theora file is lossy, the thumbnail will always be a little off from the original when using this command.

0

You can use the -metadata:s:a METADATA_BLOCK_PICTURE=... to add the image data manually, but the provided data has to follow the Xiph Vorbis Comment structure.

First, you have to create a matching header block (which fortunately can be reused when the image size etc. stays the same), and then concatenate it with the base64 encoded image data.

For more details, see https://superuser.com/a/1816195/1860118

4
  • Nice hint! Would you give an example of the commands needed to do this (if the starting file is, for example, cover.jpg)?
    – Totor
    Commented Dec 18, 2023 at 13:47
  • I get zsh: argument list too long: ffmpeg when I use this solution.
    – horsey_guy
    Commented Apr 20 at 21:06
  • @Totor - Please follow the link, there you should find everything required. Commented May 15 at 21:33
  • 1
    @horsey_guy - The maximum argument length is ~2MByte. Due to the base64 encoding, each 6 bits is expanded to 2 bytes, i.e. the cover image has to be less than ~750 kByte for this to work as shown. Commented May 15 at 21:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .