tinytag is a Python library for reading audio file metadata
python3 -m pip install tinytag
Important
Support for changing/writing metadata will not be added. Use another library such as Mutagen for this.
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 = TinyTag.get('/some/music.mp3') print(f'This track is by {tag.artist}.') print(f'It is {tag.duration:.2f} seconds long.')
Warning
The ignore_errors
parameter of TinyTag.get()
is obsolete as of tinytag 2.0.0, and will be removed in the future.
Alternatively you can use tinytag directly on the command line:
$ python3 -m tinytag /some/music.mp3
{
"filename": "/some/music.mp3",
"filesize": 3243226,
"duration": 173.52,
"channels": 2,
"bitrate": 128,
"samplerate": 44100,
"artist": [
"artist name"
],
"album": [
"album name"
],
"title": [
"track name"
],
"track": 4,
"genre": [
"Jazz"
],
"year": [
"2010"
],
"comment": [
"Some comment here"
]
}
Check python3 -m tinytag --help
for all CLI options, for example other output formats.
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')
tinytag provides some common attributes, which always contain a single value. These are helpful when you need quick access to common metadata.
tag.bitdepth # bit depth as integer (for lossless audio)
tag.bitrate # bitrate in kBits/s as float
tag.duration # audio duration in seconds as float
tag.filename # filename as string
tag.filesize # file size in bytes as integer
tag.samplerate # samples per second as integer
Warning
The tag.audio_offset
attribute is obsolete as of tinytag 2.0.0, and will be removed in the future.
tag.album # album as string
tag.albumartist # album artist as string
tag.artist # artist name as string
tag.comment # file comment as string
tag.composer # composer as string
tag.disc # disc number as integer
tag.disc_total # total number of discs as integer
tag.genre # genre as string
tag.title # title of the song as string
tag.track # track number as integer
tag.track_total # total number of tracks as integer
tag.year # year or date as string
For additional values of the same field type, non-common metadata fields, or metadata specific to certain file formats, use other
:
tag.other # a dictionary of additional fields
Warning
The other
dictionary has replaced the extra
dictionary in tinytag 2.0.0. The latter will be removed in a future release.
The following other
field names are standardized in tinytag, and optionally present when files provide such metadata:
barcode
bpm
catalog_number
conductor
copyright
director
encoded_by
encoder_settings
initial_key
isrc
language
license
lyricist
lyrics
media
publisher
set_subtitle
url
Additional other
field names not documented above may be present, but are format-specific and may change or disappear in future tinytag releases. If tinytag does not expose metadata you need, or you wish to standardize more field names, open a feature request on GitHub for discussion.
other
values are always provided as strings, and are not guaranteed to be valid. Should e.g. the bpm
value in the file contain non-numeric characters, tinytag will provide the string as-is. It is your responsibility to handle possible exceptions, e.g. when converting the value to an integer.
Multiple values of the same field type are provided if a file contains them. Values are always provided as a list, even when only a single value exists.
Example:
from tinytag import OtherFields, TinyTag tag: TinyTag = TinyTag.get('/some/music.mp3') other_fields: OtherFields = tag.other catalog_numbers: list[str] | None = other_fields.get('catalog_number') if catalog_numbers: catalog_number: str = catalog_numbers[0] print(catalog_number) print(catalog_numbers)
Output:
When a file contains multiple values for a common metadata field (e.g. artist
), the primary value is accessed through the common attribute (tag.artist
), and any additional values through the other
dictionary (tag.other['artist']
).
Example:
from tinytag import TinyTag tag: TinyTag = TinyTag.get('/some/music.mp3') artist: str | None = tag.artist additional_artists: list[str] | None = tag.other.get('artist') print(artist) print(additional_artists)
Output:
> main artist
> ['another artist', 'yet another artist']
If you need to receive all available metadata as key-value pairs in a flat dictionary, use the as_dict()
method. This combines the common attributes and other
dictionary, which can be more convenient in some cases.
from tinytag import TinyTag
tag: TinyTag = TinyTag.get('/some/music.mp3')
metadata: dict = tag.as_dict()
Additionally, you can also read embedded images by passing a image=True
keyword argument to TinyTag.get()
.
If you need to receive an image of a specific kind, including its description, use images
:
tag.images # available embedded images
The following common image attributes are available, providing the first located image of each kind:
tag.images.front_cover # front cover as 'Image' object
tag.images.back_cover # back cover as 'Image' object
tag.images.media # media (e.g. CD label) as 'Image' object
When present, any additional images are available in an images.other
dictionary, using the following standardized key names:
generic
icon
alt_icon
front_cover
back_cover
media
leaflet
lead_artist
artist
conductor
band
composer
lyricist
recording_location
during_recording
during_performance
screen_capture
bright_colored_fish
illustration
band_logo
publisher_logo
unknown
Provided values are always lists containing at least one Image
object.
The Image
object provides the following attributes:
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 any available image, prioritizing the front cover, use images.any
:
from tinytag import Image, TinyTag tag: TinyTag = TinyTag.get('/some/music.ogg', image=True) image: Image | None = tag.images.any if image is not None: data: bytes = image.data name: str = image.name mime_type: str = image.mime_type description: str = image.description print(len(data)) print(name) print(mime_type) print(description)
Output:
> 74452
> front_cover
> image/jpeg
> some image description
Warning
tag.images.any
has replaced tag.get_image()
in tinytag 2.0.0. tag.get_image()
will be removed in the future.
To receive a common image, e.g. front_cover
:
from tinytag import Image, Images, TinyTag tag: TinyTag = TinyTag.get('/some/music.ogg', image=True) images: Images = tag.images cover_image: Image = images.front_cover if cover_image is not None: data: bytes = cover_image.data description: str = cover_image.description
To receive an additional image, e.g. bright_colored_fish
:
from tinytag import Image, OtherImages, TinyTag tag: TinyTag = TinyTag.get('/some/music.ogg', image=True) other_images: OtherImages = tag.images.other fish_images: list[Image] | None = other_images.get('bright_colored_fish') if fish_images: image = fish_images[0] # Use first image data = image.data description = image.description
To open files using a specific encoding, you can use the encoding
parameter. This parameter is however only used for formats where the encoding is not explicitly specified.
TinyTag.get('a_file_with_gbk_encoding.mp3', encoding='gbk')
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)
TinyTagException # Base class for exceptions
ParseError # Parsing an audio file failed
UnsupportedFormatError # File format is not supported
__version__
attributeTinyTag.get(..., encoding='gbk'))
)extra['isrc']
field (thanks to aw-was-here)extra['initial_key']
extra['lyrics']
extra
field, which may contain additional metadata not available in all file formatsignore_errors
#73TinyTag.is_supported(filename)
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4