• Stars
    star
    634
  • Rank 70,925 (Top 2 %)
  • Language
    Python
  • License
    MIT License
  • Created almost 11 years ago
  • Updated almost 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Read audio and music meta data and duration of MP3, OGG, OPUS, MP4, M4A, FLAC, WMA, Wave and AIFF files with python 2 or 3

tinytag

tinytag is a Python library for reading audio file metadata

Build Status Coverage Status PyPI Version PyPI Downloads

Install

python3 -m pip install tinytag

Features

  • Read tags, images and properties of audio files
  • Supported formats:
    • MP3 / MP2 / MP1 (ID3 v1, v1.1, v2.2, v2.3+)
    • M4A (AAC / ALAC)
    • WAVE / WAV
    • OGG (FLAC / Opus / Speex / Vorbis)
    • FLAC
    • WMA
    • AIFF / AIFF-C
  • Same API for all formats
  • Pure Python, no dependencies
  • Supports Python 3.7 or higher
  • High test coverage
  • A few hundred lines of code (just include it in your project!)

Usage

tinytag only provides the minimum needed for reading metadata, and presents it in a simple format. It can determine track number, total tracks, title, artist, album, year, duration and more.

from tinytag import TinyTag
tag = TinyTag.get('/some/music.mp3')
print(f'This track is by {tag.artist}.')
print(f'It is {tag.duration:.2f} seconds long.')

Alternatively you can use tinytag directly on the command line:

$ python -m tinytag --format csv /some/music.mp3
> {"filename": "/some/music.mp3", "filesize": 30212227, "album": "Album", "albumartist": "Artist", "artist": "Artist", "audio_offset": null, "bitrate": 256, "channels": 2, "comment": null, "composer": null, "disc": "1", "disc_total": null, "duration": 10, "genre": null, "samplerate": 44100, "title": "Title", "track": "5", "track_total": null, "year": "2012"}

Check python -m tinytag --help for all CLI options, for example other output formats.

Support for changing/writing metadata will not be added, use another library for this.

Supported Files

To receive a tuple of file extensions tinytag supports, use the SUPPORTED_FILE_EXTENSIONS constant:

TinyTag.SUPPORTED_FILE_EXTENSIONS

Alternatively, check if a file is supported by providing its path:

is_supported = TinyTag.is_supported('/some/music.mp3')

Attributes

List of common attributes tinytag provides:

tag.album         # album as string
tag.albumartist   # album artist as string
tag.artist        # artist name as string
tag.bitdepth      # bit depth for lossless audio
tag.bitrate       # bitrate in kBits/s
tag.comment       # file comment as string
tag.disc          # disc number
tag.disc_total    # the total number of discs
tag.duration      # duration of the song in seconds
tag.filesize      # file size in bytes
tag.genre         # genre as string
tag.samplerate    # samples per second
tag.title         # title of the song
tag.track         # track number
tag.track_total   # total number of tracks
tag.year          # year or date as string

For non-common fields and fields specific to certain file formats, use extra:

tag.extra         # a dict of additional data

The following standard extra field names are used when file formats provide relevant data:

other_artists     # additional artists as list
other_genres      # additional genres as list

bpm
composer
conductor
copyright
director
encoded_by
encoder_settings
initial_key
isrc
language
lyricist
lyrics
media
publisher
set_subtitle
url

Any other extra field names are not guaranteed to be consistent across audio formats.

Additionally, you can also get images from ID3 tags. To receive any available image, prioritizing the front cover:

tag: TinyTag = TinyTag.get('/some/music.mp3', image=True)
image: TagImage | None = tag.images.any

if image is not None:
    data: bytes = image.data
    name: str = image.name
    description: str = image.description

If you need to receive an image of a specific kind, including its description, use images:

tag.images        # available embedded images

The following common images are available:

front_cover
back_cover
leaflet
media
other

The following less common images are provided in an extra dict when present:

icon
other_icon
lead_artist
artist
conductor
band
composer
lyricist
recording_location
during_recording
during_performance
video
bright_colored_fish
illustration
band_logo
publisher_logo
unknown

The following image attributes are available:

data           # image data as bytes
name           # image name/kind as string
mime_type      # image MIME type as string
description    # image description as string

To receive a common image, e.g. front_cover:

from tinytag import TinyTag, TagImage, TagImages

tag: TinyTag = TinyTag.get('/some/music.ogg')
images: TagImages = tag.images
front_cover_images: list[TagImage] = images.front_cover

if front_cover_images:
    image: TagImage = front_cover_images[0]  # Use first image
    data: bytes = image.data
    description: str = image.description

To receive an extra image, e.g. bright_colored_fish:

fish_images = tag.images.extra.get('bright_colored_fish')

if fish_images:
    image = fish_images[0]  # Use first image
    data = image.data
    description = image.description

Encoding

To open files using a specific encoding, you can use the encoding parameter. This parameter is however only used for formats where the encoding isn't explicitly specified.

TinyTag.get('a_file_with_gbk_encoding.mp3', encoding='gbk')

File-like Objects

To use a file-like object (e.g. BytesIO) instead of a file path, pass a file_obj keyword argument:

TinyTag.get(file_obj=your_file_obj)

Exceptions

TinyTagException        # Base class for exceptions
ParseError              # Parsing an audio file failed
UnsupportedFormatError  # File format is not supported

Changelog

2.0.0 (Unreleased)

  • BREAKING: Store 'disc', 'disc_total', 'track' and 'track_total' values as int instead of str
  • BREAKING: TinyTagException no longer inherits LookupError
  • BREAKING: TinyTag subclasses are now private
  • BREAKING: Remove function to use custom audio file samples in tests
  • BREAKING: Remove support for Python 2
  • Mark 'ignore_errors' parameter for TinyTag.get() as obsolete
  • Mark 'audio_offset' attribute as obsolete
  • Deprecate 'composer' attribute in favor of 'extra.composer'
  • Deprecate 'get_image()' method in favor of 'images.any' property
  • Provide access to custom metadata fields through the 'extra' dict
  • Provide access to all available images
  • Add more standard 'extra' fields
  • FLAC: Apply ID3 tags after Vorbis
  • OGG/WMA: set missing 'channels' field
  • WMA: set missing 'extra.copyright' field
  • WMA: raise exception if file is invalid
  • Add type hints to codebase
  • Various optimizations

1.10.1 (2023-10-26)

  • Update 'extra' fields with data from other tags #188
  • ID3: Add missing 'extra.copyright' field

1.10.0 (2023-10-18)

  • Add support for OGG FLAC format #182
  • Add support for OGG Speex format #181
  • Wave: support image loading
  • Add support for file-like objects (BytesIO) #178
  • Add list of supported file extensions #177
  • Fix deprecations related to setuptools #176
  • Fix pathlib support in TinyTag.is_supported()
  • Only remove zero bytes at the end of strings
  • Stricter conditions in while loops
  • OGG: Add stricter magic byte matching for OGG files
  • Compatibility with Python 3.4 and 3.5 is no longer tested

1.9.0 (2023-04-23)

  • Add bitdepth attribute for lossless audio #157
  • Add recognition of Audible formats #163 (thanks to snowskeleton)
  • Add .m4v to list of supported file extensions #142
  • Aiff: Implement replacement for Python's aifc module #164
  • ID3: Only check for language in COMM and USLT frames #147
  • ID3: Read the correct number of bytes from Xing header #154
  • ID3: Add support for ID3v2.4 TDRC frame #156 (thanks to Uninen)
  • M4A: Add description fields #168 (thanks to snowskeleton)
  • RIFF: Handle tags containing extra zero-byte #141
  • Vorbis: Parse OGG cover art #144 (thanks to Pseurae)
  • Vorbis: Support standard disctotal/tracktotal comments #171
  • Wave: Add proper support for padded IFF chunks

1.8.1 (2022-03-12) [still mathiascode-edition]

  • MP3 ID3: Set correct file position if tag reading is disabled #119 (thanks to mathiascode)
  • MP3: Fix incorrect calculation of duration for VBR encoded MP3s #128 (thanks to mathiascode)

1.8.0 (2022-03-05) [mathiascode-edition]

  • Add support for ALAC audio files #130 (thanks to mathiascode)
  • AIFF: Fixed bitrate calculation for certain files #129 (thanks to mathiascode)
  • MP3: Do not round MP3 bitrates #131 (thanks to mathiascode)
  • MP3 ID3: Support any language in COMM and USLT frames #135 (thanks to mathiascode)
  • Performance: Don't use regex when parsing genre #136 (thanks to mathiascode)
  • Disable tag parsing for all formats when requested #137 (thanks to mathiascode)
  • M4A: Fix invalid bitrates in certain files #132 (thanks to mathiascode)
  • WAV: Fix metadata parsing for certain files #133 (thanks to mathiascode)

1.7.0. (2021-12-14)

  • fixed rare occasion of ID3v2 tags missing their first character, #106
  • allow overriding the default encoding of ID3 tags (e.g. TinyTag.get(..., encoding='gbk')))
  • fixed calculation of bitrate for very short mp3 files, #99
  • utf-8 support for AIFF files, #123
  • fixed image parsing for id3v2 with images containing utf-16LE descriptions, #117
  • fixed ID3v1 tags overwriting ID3v2 tags, #121
  • Set correct file position if tag reading is disabled for ID3 (thanks to mathiascode)

1.6.0 (2021-08-28) [aw-edition]

  • fixed handling of non-latin encoding types for images (thanks to aw-was-here)
  • added support for ISRC data, available in extra['isrc'] field (thanks to aw-was-here)
  • added support for AIFF/AIFF-C (thanks to aw-was-here)
  • fixed import deprecation warnings (thanks to idotobi)
  • fixed exception for TinyTag misuse being different in different python versions (thanks to idotobi)
  • added support for ID3 initial key tonality hint, available in extra['initial_key']
  • added support for ID3 unsynchronized lyrics, available in extra['lyrics']
  • added extra field, which may contain additional metadata not available in all file formats

1.5.0 (2020-11-05)

  • fixed data type to always return str for disc, disc_total, track, track_total #97 (thanks to kostalski)
  • fixed package install being reported as UNKNOWN for some python/pip variations #90 (thanks to russpoutine)
  • Added automatic detection for certain MP4 file headers

1.4.0 (2020-04-23)

  • detecting file types based on their magic header bytes, #85
  • fixed opus duration being wrong for files with lower sample rate #81
  • implemented support for binary paths #72
  • always cast mp3 bitrates to int, so that CBR and VBR output behaves the sam
  • made str deterministic and use json as output format

1.3.0 (2020-03-09)

  • added option to ignore encoding errors ignore_errors #73
  • Improved text decoding for many malformed files

1.2.2 (2019-04-13)

  • Improved stability when reading corrupted mp3 files

1.2.1 (2019-04-13)

  • fixed wav files not correctly reporting the number of channels #61

1.2.0 (2019-04-13)

  • using setup.cfg instead of setup.py (thanks to scivision)
  • added support for calling TinyTag.get with pathlib.Path (thanks to scivision)
  • added appveyor windows test CI (thanks to scivision)
  • using pytest instead of nosetest (thanks to scivision)

1.1.0 (2019-04-13)

  • added new field "composer" (Thanks to Phil Borman)

1.0.1 (2019-04-13)

  • fixed ID3 loading for files with corrupt header (thanks to Ian Homer)
  • fixed parsing of duration in wav file (thanks to Ian Homer)

1.0.0 (2018-12-12)

  • added comment field
  • added wav-riff format support
  • use MP4 parser for m4b files
  • added simple cli tool
  • fix parsing of FLAC files with ID3 header (thanks to minus7)
  • added method TinyTag.is_supported(filename)

0.19.0 (2018-02-11)

  • fixed corrupted images for some mp3s (#45)

0.18.0 (2017-04-29)

  • fixed wrong bitrate and crash when parsing xing header

0.17.0 (2016-10-02)

  • supporting ID3v2.2 images

0.16.0 (2016-08-06)

  • MP4 cover image support

0.15.2 (2016-08-06)

  • fixed crash for malformed MP4 files (#34)

0.15.0 (2016-08-06)

  • fixed decoding of UTF-16LE ID3v2 Tags, improved overall stability

0.14.0 (2016-06-05):

  • MP4/M4A and Opus support