thebigmunch / audio-metadata

A library for reading and, in the future, writing audio metadata. https://audio-metadata.readthedocs.io/
https://forum.thebigmunch.me
MIT License
53 stars 11 forks source link

audio_Metadata.load() hangs forever with some MP3 files. #44

Open rosyth opened 1 year ago

rosyth commented 1 year ago

Checklist

audio-metadata version

Name: audio-metadata Version: 0.11.1 Summary: A library for reading and, in the future, writing metadata from audio files. Home-page: https://github.com/thebigmunch/audio-metadata Author: thebigmunch Author-email: mail@thebigmunch.me License: MIT Location: /home/bill/.local/lib/python3.8/site-packages Requires: attrs, bidict, bitstruct, more-itertools, pendulum, pprintpp, tbm-utils, wrapt Required-by:

Python version

3.8.10 (default, Nov 14 2022, 12:59:47) [GCC 9.4.0]

Operating system

Linux Mint 20.0 System: Kernel: 5.15.0-58-generic x86_64 bits: 64 compiler: N/A Desktop: Cinnamon 5.0.7 wm: muffin dm: LightDM Distro: Linux Mint 20.2 Uma base: Ubuntu 20.04 focal

Exception traceback

audio_metadata.load(Path(df.loc[3421]['FileA']))
Traceback (most recent call last):

  File "/tmp/ipykernel_384411/3107725757.py", line 1, in <cell line: 1>
    audio_metadata.load(Path(df.loc[3421]['FileA']))

  File "/home/me/.local/lib/python3.8/site-packages/audio_metadata/api.py", line 113, in load
    parser_cls = determine_format(data)

  File "/home/me/.local/lib/python3.8/site-packages/audio_metadata/api.py", line 72, in determine_format
    ID3v2.parse(data)

  File "/home/me/.local/lib/python3.8/site-packages/tbm_utils/decorators.py", line 44, in wrapper
    return wrapped(*args, **kwargs)

  File "/home/me/.local/lib/python3.8/site-packages/audio_metadata/formats/id3v2.py", line 416, in parse
    self.tags = ID3v2Frames.parse(

  File "/home/me/.local/lib/python3.8/site-packages/tbm_utils/decorators.py", line 44, in wrapper
    return wrapped(*args, **kwargs)

  File "/home/me/.local/lib/python3.8/site-packages/audio_metadata/formats/id3v2.py", line 246, in parse
    frame = ID3v2Frame.parse(data, id3_version, unsync)

  File "/home/me/.local/lib/python3.8/site-packages/tbm_utils/decorators.py", line 44, in wrapper
    return wrapped(*args, **kwargs)

  File "/home/me/.local/lib/python3.8/site-packages/audio_metadata/formats/id3v2frames.py", line 538, in parse
    frame_data = remove_unsynchronization(data.read(read_size))

  File "/home/me/.local/lib/python3.8/site-packages/audio_metadata/utils.py", line 59, in remove_unsynchronization
    data = data[sync_index + 3:]

KeyboardInterrupt

Steps/conditions to reproduce the bug

If I run audio_metadata.load(Path(df.loc[3421]['FileA'])) Or this file is accessed during my dataframe.appy() loop, then the process freezes.
If I wrap this call in a function eg..

import time
import timeout_decorator
@timeout_decorator.timeout(1)
def mp3meta(path):
    audio_metadata.load(path)

mp3meta(Path(poo.srcdest[0], poo.df.loc[3421]['FileA']))
Traceback (most recent call last):

  File "/tmp/ipykernel_384411/3184206738.py", line 1, in <cell line: 1>
    mp3meta(Path(poo.srcdest[0], poo.df.loc[3421]['FileA']))

  File "/home/me/.local/lib/python3.8/site-packages/timeout_decorator/timeout_decorator.py", line 82, in new_function
    return function(*args, **kwargs)

  File "/tmp/ipykernel_384411/2936242082.py", line 3, in mp3meta
    audio_metadata.load(path)

  File "/home/me/.local/lib/python3.8/site-packages/audio_metadata/api.py", line 113, in load
    parser_cls = determine_format(data)

  File "/home/me/.local/lib/python3.8/site-packages/audio_metadata/api.py", line 72, in determine_format
    ID3v2.parse(data)

  File "/home/me/.local/lib/python3.8/site-packages/tbm_utils/decorators.py", line 44, in wrapper
    return wrapped(*args, **kwargs)

  File "/home/me/.local/lib/python3.8/site-packages/audio_metadata/formats/id3v2.py", line 416, in parse
    self.tags = ID3v2Frames.parse(

  File "/home/me/.local/lib/python3.8/site-packages/tbm_utils/decorators.py", line 44, in wrapper
    return wrapped(*args, **kwargs)

  File "/home/me/.local/lib/python3.8/site-packages/audio_metadata/formats/id3v2.py", line 246, in parse
    frame = ID3v2Frame.parse(data, id3_version, unsync)

  File "/home/me/.local/lib/python3.8/site-packages/tbm_utils/decorators.py", line 44, in wrapper
    return wrapped(*args, **kwargs)

  File "/home/me/.local/lib/python3.8/site-packages/audio_metadata/formats/id3v2frames.py", line 538, in parse
    frame_data = remove_unsynchronization(data.read(read_size))

  File "/home/me/.local/lib/python3.8/site-packages/audio_metadata/utils.py", line 57, in remove_unsynchronization
    if data[sync_index + 1 : sync_index + 3] == b'\x00\x00':

  File "/home/me/.local/lib/python3.8/site-packages/timeout_decorator/timeout_decorator.py", line 69, in handler
    _raise_exception(timeout_exception, exception_message)

  File "/home/me/.local/lib/python3.8/site-packages/timeout_decorator/timeout_decorator.py", line 45, in _raise_exception
    raise exception()

TimeoutError: 'Timed Out'

So it seems that somewhere inside 'remove_unsynchronization' there is the capability to create an endless 'while' loop. I don't know what is special about this file. It plays ok as does the previous file (ie the track before).

Include file(s)