1
1
mirror of https://github.com/wader/fq.git synced 2024-12-23 05:13:30 +03:00

mp4: Decode udta metadata boxes without meta box

This commit is contained in:
Mattias Wadman 2023-01-16 12:00:49 +01:00
parent c2795a7c2f
commit c3e3b3e90d
5 changed files with 91 additions and 10 deletions

View File

@ -1,7 +1,5 @@
package mp4 package mp4
// TODO: flags?
import ( import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
@ -1639,9 +1637,41 @@ func decodeBox(ctx *decodeContext, d *decode.D, typ string) {
} }
}) })
default: default:
// there are at least 3 ways to encode udta metadata in mov/mp4 files.
//
// mdta subtype:
//
// udta:
// meta
// hdlr with subtype "mdta"
// keys with 1-based <index> to key namespace.name table
// ilst
// <index>-box
// data box with value
//
// mdir subtype:
//
// udta
// meta
// hdlr with subtype "mdir"
// ilst
// ©<abc> or similar
// data with value
//
// no-meta-box:
//
// udta
// ©<abc> or similar
// data with length, language and value
if mb := ctx.currentMetaBox(); mb != nil && ctx.parent().typ == "ilst" { if mb := ctx.currentMetaBox(); mb != nil && ctx.parent().typ == "ilst" {
// unknown type inside a metadata box with ilst as parent, decode item boxes // unknown type under a meta box with ilst as parent, decode as boxes
// is probably one or more data boxes
decodeBoxes(ctx, d) decodeBoxes(ctx, d)
} else if ctx.parent().typ == "udta" {
length := d.FieldU16("length")
d.FieldStrFn("language", decodeLang)
d.FieldUTF8("value", int(length))
} else { } else {
d.FieldRawLen("data", d.BitsLeft()) d.FieldRawLen("data", d.BitsLeft())
} }

View File

@ -282,7 +282,53 @@ var boxDescriptions = scalar.StrMapDescription{
"tvnn": "Network", "tvnn": "Network",
"©lyr": "Lyrics", "©lyr": "Lyrics",
// some from ffmpeg libavformat/mov.c
"©too": "Encoder", "©too": "Encoder",
"@PRM": "Premiere version",
"@PRQ": "QuickTime version",
"akID": "Account type",
"apID": "Account id",
"catg": "Category",
"cpil": "Compilation",
"disk": "Disc",
"egid": "Episode UID",
"FIRM": "Firmware",
"hdvd": "HD video",
"keyw": "Keywords",
"pcst": "Podcast",
"pgap": "Gapless playback",
"purd": "Purchase date",
"soaa": "Sort album artist",
"soal": "Sort album",
"soar": "Sort artist",
"soco": "Sort composer",
"sonm": "Sort name",
"sosn": "Sort show",
"stik": "Media type",
"©PRD": "Producer",
"©aut": "Artist",
"©chp": "Chapter",
"©com": "Composer",
"©dir": "Director",
"©dis": "Disclaimer",
"©ed1": "Edit date",
"©enc": "Encoder",
"©fmt": "Original format",
"©hst": "Host computer",
"©inf": "Comment",
"©mak": "Make",
"©mod": "Model",
"©ope": "Original artist",
"©prd": "Producer",
"©prf": "Performers",
"©req": "Playback requirements",
"©src": "Original source",
"©st3": "Subtitle",
"©swr": "Encoder",
"©trk": "Track",
"©url": "URL",
"©wrn": "Warning",
"©xyz": "Location",
"\x00\x00\x00\x00": "Terminator Atom", "\x00\x00\x00\x00": "Terminator Atom",
} }

View File

@ -279,8 +279,10 @@ $ fq dv in24.mp4
| | | boxes[0:1]: 0x3d3-0x3eb.7 (25) | | | boxes[0:1]: 0x3d3-0x3eb.7 (25)
| | | [0]{}: box 0x3d3-0x3eb.7 (25) | | | [0]{}: box 0x3d3-0x3eb.7 (25)
0x3d0| 00 00 00 19 | .... | size: 25 0x3d3-0x3d6.7 (4) 0x3d0| 00 00 00 19 | .... | size: 25 0x3d3-0x3d6.7 (4)
0x3d0| a9 73 77 72 | .swr | type: "©swr" 0x3d7-0x3da.7 (4) 0x3d0| a9 73 77 72 | .swr | type: "©swr" (Encoder) 0x3d7-0x3da.7 (4)
0x3d0| 00 0d 55 c4 4c| ..U.L| data: raw bits 0x3db-0x3eb.7 (17) 0x3d0| 00 0d | .. | length: 13 0x3db-0x3dc.7 (2)
0x3d0| 55 c4 | U. | language: "und" 0x3dd-0x3de.7 (2)
0x3d0| 4c| L| value: "Lavf58.76.100" 0x3df-0x3eb.7 (13)
0x3e0|61 76 66 35 38 2e 37 36 2e 31 30 30| |avf58.76.100| | 0x3e0|61 76 66 35 38 2e 37 36 2e 31 30 30| |avf58.76.100| |
| | | tracks[0:1]: 0x3ec-NA (0) | | | tracks[0:1]: 0x3ec-NA (0)
| | | [0]{}: track 0x3ec-NA (0) | | | [0]{}: track 0x3ec-NA (0)

View File

@ -269,9 +269,11 @@ $ fq dv lpcm.mp4
| | | boxes[0:1]: 0x4f9-0x511.7 (25) | | | boxes[0:1]: 0x4f9-0x511.7 (25)
| | | [0]{}: box 0x4f9-0x511.7 (25) | | | [0]{}: box 0x4f9-0x511.7 (25)
0x4f0| 00 00 00 19 | .... | size: 25 0x4f9-0x4fc.7 (4) 0x4f0| 00 00 00 19 | .... | size: 25 0x4f9-0x4fc.7 (4)
0x4f0| a9 73 77| .sw| type: "©swr" 0x4fd-0x500.7 (4) 0x4f0| a9 73 77| .sw| type: "©swr" (Encoder) 0x4fd-0x500.7 (4)
0x500|72 |r | 0x500|72 |r |
0x500| 00 0d 55 c4 4c 61 76 66 35 38 2e 37 36 2e 31| ..U.Lavf58.76.1| data: raw bits 0x501-0x511.7 (17) 0x500| 00 0d | .. | length: 13 0x501-0x502.7 (2)
0x500| 55 c4 | U. | language: "und" 0x503-0x504.7 (2)
0x500| 4c 61 76 66 35 38 2e 37 36 2e 31| Lavf58.76.1| value: "Lavf58.76.100" 0x505-0x511.7 (13)
0x510|30 30| |00| | 0x510|30 30| |00| |
| | | tracks[0:1]: 0x512-NA (0) | | | tracks[0:1]: 0x512-NA (0)
| | | [0]{}: track 0x512-NA (0) | | | [0]{}: track 0x512-NA (0)

View File

@ -294,9 +294,10 @@ $ fq -d mp4 dv prores_frame.mov
| | | boxes[0:1]: 0x6ee6-0x6efe.7 (25) | | | boxes[0:1]: 0x6ee6-0x6efe.7 (25)
| | | [0]{}: box 0x6ee6-0x6efe.7 (25) | | | [0]{}: box 0x6ee6-0x6efe.7 (25)
0x6ee0| 00 00 00 19 | .... | size: 25 0x6ee6-0x6ee9.7 (4) 0x6ee0| 00 00 00 19 | .... | size: 25 0x6ee6-0x6ee9.7 (4)
0x6ee0| a9 73 77 72 | .swr | type: "©swr" 0x6eea-0x6eed.7 (4) 0x6ee0| a9 73 77 72 | .swr | type: "©swr" (Encoder) 0x6eea-0x6eed.7 (4)
0x6ee0| 00 0d| ..| data: raw bits 0x6eee-0x6efe.7 (17) 0x6ee0| 00 0d| ..| length: 13 0x6eee-0x6eef.7 (2)
0x6ef0|55 c4 4c 61 76 66 35 39 2e 31 36 2e 31 30 30| |U.Lavf59.16.100|| 0x6ef0|55 c4 |U. | language: "und" 0x6ef0-0x6ef1.7 (2)
0x6ef0| 4c 61 76 66 35 39 2e 31 36 2e 31 30 30| | Lavf59.16.100|| value: "Lavf59.16.100" 0x6ef2-0x6efe.7 (13)
| | | tracks[0:1]: 0x24-0x6efe.7 (28379) | | | tracks[0:1]: 0x24-0x6efe.7 (28379)
| | | [0]{}: track 0x24-0x6efe.7 (28379) | | | [0]{}: track 0x24-0x6efe.7 (28379)
| | | samples[0:1]: 0x24-0x6c3c.7 (27673) | | | samples[0:1]: 0x24-0x6c3c.7 (27673)