@@ -340,17 +340,27 @@ def __init__(self, *args, **kwargs):
340
340
if args or kwargs :
341
341
self .load (* args , ** kwargs )
342
342
343
- def load (self , atoms , fileobj ):
344
- try :
345
- path = atoms .path (b"moov" , b"udta" , b"meta" , b"ilst" )
346
- except KeyError as key :
347
- raise MP4MetadataError (key )
348
-
349
- free = _find_padding (path )
350
- self ._padding = free .datalength if free is not None else 0
343
+ def load (self , atoms : Atoms , fileobj ):
344
+ for atom in atoms .atoms :
345
+ if atom .children is not None :
346
+ self ._recurse_atom (atom , fileobj )
347
+
348
+ def _recurse_atom (self , parent : Atom , fileobj ):
349
+ """Recursively search for an ilst atom to read metadata from.
350
+
351
+ Recursing helps if the mp4/m4a container didn't store metadata correctly,
352
+ which is usually expected at moov.udta.meta.ilst"""
353
+ if parent .name != b"ilst" :
354
+ for atom in parent .children :
355
+ if parent .name == b"meta" and atom .name == b"ilst" :
356
+ free = _find_padding ([parent , atom ])
357
+ self ._padding = free .datalength if free is not None else 0
358
+
359
+ if atom .children is not None and atom .name != 'ilst' :
360
+ self ._recurse_atom (atom , fileobj )
361
+ return
351
362
352
- ilst = path [- 1 ]
353
- for atom in ilst .children :
363
+ for atom in parent .children :
354
364
ok , data = atom .read (fileobj )
355
365
if not ok :
356
366
raise MP4MetadataError ("Not enough data" )
0 commit comments