4

Given this file:

youtube-dl -f 140 -o in.m4a --fixup warn https://youtube.com/watch?v=j-70HbaR4g4

I am having mixed results writing metadata. For example these commands:

ffmpeg -i in.m4a -c copy in.mp4
ffmpeg -i in.mp4 -c copy good.aac
ffmpeg -i good.aac -c copy -bsf aac_adtstoasc -metadata title=Confetti `
   -movflags faststart good.m4a

Will generate an M4A file that plays correctly with metadata that is recognized. However this command:

ffmpeg -i in.m4a -c copy -movflags faststart -metadata title=Confetti bad.m4a

Generates a file that plays correctly, but my player does not recognize the metadata. Also, I remembered that I worked on this problem years ago, and I think I know part of the problem. I ran both files through mp4dump [1], and I noticed a difference. Here is good file:

[moov] size=8+41912
  [trak] size=8+41666
    [mdia] size=8+41530
      [minf] size=8+41445
        [stbl] size=8+41385
          [stsd] size=12+91
            [mp4a] size=8+79
              [esds] size=12+39
                [ESDescriptor] size=5+34
                  [DecoderConfig] size=5+20
                    DecoderSpecificInfo = 12 10 

and bad file:

[moov] size=8+41976
  [trak] size=8+41730
    [mdia] size=8+41594
      [minf] size=8+41483
        [stbl] size=8+41423
          [stsd] size=12+105
            [mp4a] size=8+93
              [esds] size=12+53
                [ESDescriptor] size=5+48
                  [DecoderConfig] size=5+34
                    DecoderSpecificInfo = 12 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

If you notice, the bad file has more bytes under DecoderSpecificInfo. However, it seems FFmpeg is just copying that info from the original file. If FFmpeg has a way to just trash that data it would be ideal. Essentially I think thats why my "good" command are doing, but it would be nice to be able to do it in one command.

  1. https://bento4.com/documentation/mp4dump
Zombo
  • 1

2 Answers2

1

When you extract/convert the audio stream to "raw AAC" (ADTS), the metadata of the source file is discarded as it consists of only a minimal header.

To strip the metadata without the extra step, you can do:

ffmpeg -i in.m4a -c copy -map_metadata -1 out.m4a

A negative file index for the switch -map_metadata disables the copying of metadata (which does NOT include chapters by the way; there's -map_chapters for that).

The switch shouldn't prevent you from creating new metadata items in the same process, so you can add -metadata title=Confetti after it.

I couldn't tell what exactly prevent the particular player you use from recognizing the metadata in the source (or maybe just the copy of it in the output), but since apparently creating metadata "from scratch" works for it, and an abbreviated approach is what you asked for, here's the answer.

Tom Yan
  • 10,996
0

Based on Tom's answer, I think I was able to solve this. If I run these commands:

ffmpeg -i in.m4a -c copy -movflags faststart -metadata title=Confetti bad.m4a
ffmpeg -i in.m4a -c copy -movflags faststart -metadata title=Confetti `
   -map_metadata -1 good.m4a
mp4dump bad.m4a > bad.txt
mp4dump good.m4a > good.txt
git diff bad.txt good.txt

I get this result:

-        handler_name = ISO Media file produced by Google Inc.
+        handler_name = SoundHandler

I tested some more, and it seems any handler_name more than 29 characters will fail, which is probably 30 including a null byte, or maybe a length byte. Here is an example that will just barely pass:

ffmpeg -i in.m4a -c copy -movflags faststart -metadata title=Confetti `
-metadata:s handler_name=SoundHandlerSoundHandlerSound good.m4a
Zombo
  • 1