tinytag 2.2.0__tar.gz → 2.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of tinytag might be problematic. Click here for more details.
- {tinytag-2.2.0 → tinytag-2.3.0}/LICENSE +1 -1
- {tinytag-2.2.0 → tinytag-2.3.0}/PKG-INFO +224 -82
- {tinytag-2.2.0 → tinytag-2.3.0}/README.md +222 -81
- {tinytag-2.2.0 → tinytag-2.3.0}/pyproject.toml +14 -2
- {tinytag-2.2.0 → tinytag-2.3.0}/tinytag/__init__.py +2 -2
- {tinytag-2.2.0 → tinytag-2.3.0}/tinytag/tinytag.py +1289 -810
- {tinytag-2.2.0 → tinytag-2.3.0}/tinytag/__main__.py +0 -0
- {tinytag-2.2.0 → tinytag-2.3.0}/tinytag/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
MIT License
|
|
2
2
|
|
|
3
|
-
Copyright (c) 2014-
|
|
3
|
+
Copyright (c) 2014-2026 Tom Wallroth, Mat (mathiascode), et al.
|
|
4
4
|
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tinytag
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.3.0
|
|
4
4
|
Summary: Read audio file metadata
|
|
5
5
|
Keywords: metadata,audio,music,mp3,m4a,wav,ogg,opus,flac,wma,aiff
|
|
6
6
|
Author: Tom Wallroth, Mat (mathiascode)
|
|
@@ -16,6 +16,7 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.12
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.13
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.14
|
|
19
|
+
Classifier: Programming Language :: Python :: Free Threading :: 4 - Resilient
|
|
19
20
|
Classifier: License :: OSI Approved :: MIT License
|
|
20
21
|
Classifier: Development Status :: 5 - Production/Stable
|
|
21
22
|
Classifier: Environment :: Web Environment
|
|
@@ -37,7 +38,7 @@ Project-URL: Homepage, https://github.com/tinytag/tinytag
|
|
|
37
38
|
Provides-Extra: tests
|
|
38
39
|
|
|
39
40
|
<!--
|
|
40
|
-
SPDX-FileCopyrightText: 2014-
|
|
41
|
+
SPDX-FileCopyrightText: 2014-2026 tinytag Contributors
|
|
41
42
|
SPDX-License-Identifier: MIT
|
|
42
43
|
-->
|
|
43
44
|
|
|
@@ -64,12 +65,13 @@ python3 -m pip install tinytag
|
|
|
64
65
|
|
|
65
66
|
* Read tags, images and properties of audio files
|
|
66
67
|
* Supported formats:
|
|
67
|
-
*
|
|
68
|
-
*
|
|
68
|
+
* ID3 v1, v1.1, v2.2, v2.3, v2.4
|
|
69
|
+
* MP3 / MP2 / MP1
|
|
70
|
+
* MP4 (MPEG-4 Audio / AAC / ALAC)
|
|
69
71
|
* WAVE / WAV
|
|
70
72
|
* OGG (FLAC / Opus / Speex / Vorbis)
|
|
71
73
|
* FLAC
|
|
72
|
-
* WMA
|
|
74
|
+
* ASF (WMA)
|
|
73
75
|
* AIFF / AIFF-C
|
|
74
76
|
* Same API for all formats
|
|
75
77
|
* Small, portable library
|
|
@@ -79,7 +81,8 @@ python3 -m pip install tinytag
|
|
|
79
81
|
|
|
80
82
|
> [!IMPORTANT]
|
|
81
83
|
> Support for changing/writing metadata will not be added. Use another library
|
|
82
|
-
> such as [Mutagen](https://mutagen.readthedocs.io/)
|
|
84
|
+
> such as [Mutagen](https://mutagen.readthedocs.io/) or [pytaglib](https://github.com/supermihi/pytaglib)
|
|
85
|
+
> for this.
|
|
83
86
|
|
|
84
87
|
|
|
85
88
|
## Usage
|
|
@@ -102,34 +105,40 @@ print(f'It is {tag.duration:.2f} seconds long.')
|
|
|
102
105
|
|
|
103
106
|
Alternatively you can use tinytag directly on the command line:
|
|
104
107
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
108
|
+
```console
|
|
109
|
+
$ python3 -m tinytag /some/music.mp3
|
|
110
|
+
{
|
|
111
|
+
"filename": "/some/music.mp3",
|
|
112
|
+
"filesize": 3243226,
|
|
113
|
+
"mime_type": "audio/mpeg",
|
|
114
|
+
"is_lossless": false,
|
|
115
|
+
"duration": 173.52,
|
|
116
|
+
"channels": 2,
|
|
117
|
+
"bitrate": 128,
|
|
118
|
+
"samplerate": 44100,
|
|
119
|
+
"artist": [
|
|
120
|
+
"artist name"
|
|
121
|
+
],
|
|
122
|
+
"album": [
|
|
123
|
+
"album name"
|
|
124
|
+
],
|
|
125
|
+
"title": [
|
|
126
|
+
"track name"
|
|
127
|
+
],
|
|
128
|
+
"track": [
|
|
129
|
+
"4"
|
|
130
|
+
],
|
|
131
|
+
"genre": [
|
|
132
|
+
"Jazz"
|
|
133
|
+
],
|
|
134
|
+
"year": [
|
|
135
|
+
"2010"
|
|
136
|
+
],
|
|
137
|
+
"comment": [
|
|
138
|
+
"Some comment here"
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
```
|
|
133
142
|
|
|
134
143
|
Check `python3 -m tinytag --help` for all CLI options, for example other
|
|
135
144
|
output formats.
|
|
@@ -156,12 +165,17 @@ These are helpful when you need quick access to common metadata.
|
|
|
156
165
|
|
|
157
166
|
#### File/Audio Properties
|
|
158
167
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
168
|
+
```python
|
|
169
|
+
tag.filename: str | None # file name
|
|
170
|
+
tag.filesize: int # file size in bytes
|
|
171
|
+
tag.bitdepth: int | None # audio bit depth
|
|
172
|
+
tag.bitrate: float | None # audio bitrate in kbps
|
|
173
|
+
tag.channels: int | None # number of audio channels
|
|
174
|
+
tag.duration: float | None # audio duration in seconds
|
|
175
|
+
tag.is_lossless: bool | None # is audio lossless? (added in tinytag 2.3.0)
|
|
176
|
+
tag.mime_type: str | None # audio MIME type (added in tinytag 2.3.0)
|
|
177
|
+
tag.samplerate: int | None # audio samples per second
|
|
178
|
+
```
|
|
165
179
|
|
|
166
180
|
> [!WARNING]
|
|
167
181
|
> The `tag.audio_offset` attribute is obsolete as of tinytag 2.0.0, and will
|
|
@@ -169,25 +183,75 @@ These are helpful when you need quick access to common metadata.
|
|
|
169
183
|
|
|
170
184
|
#### Metadata Fields
|
|
171
185
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
186
|
+
```python
|
|
187
|
+
tag.album: str | None # album name
|
|
188
|
+
tag.albumartist: str | None # album artist name
|
|
189
|
+
tag.artist: str | None # artist name
|
|
190
|
+
tag.comment: str | None # file comment
|
|
191
|
+
tag.composer: str | None # composer name
|
|
192
|
+
tag.disc: int | None # disc number
|
|
193
|
+
tag.disc_total: int | None # total number of discs
|
|
194
|
+
tag.genre: str | None # genre
|
|
195
|
+
tag.title: str | None # title
|
|
196
|
+
tag.track: int | None # track number
|
|
197
|
+
tag.track_total: int | None # total number of tracks
|
|
198
|
+
tag.year: str | None # year/date
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
#### Audio MIME Types
|
|
202
|
+
|
|
203
|
+
At present, tinytag may return the audio MIME types documented in this section.
|
|
204
|
+
When available, a `codecs` parameter as described in the [RFC 6381](https://www.rfc-editor.org/info/rfc6381)
|
|
205
|
+
standard is included.
|
|
206
|
+
|
|
207
|
+
For standard codec values, see:
|
|
208
|
+
* `audio/mp4`: [RFC 6381](https://www.rfc-editor.org/info/rfc6381)
|
|
209
|
+
* `audio/ogg`: [RFC 5334](https://www.rfc-editor.org/info/rfc5334)
|
|
210
|
+
and [RFC 7845](https://www.rfc-editor.org/info/rfc7845)
|
|
211
|
+
* `audio/wav`: [RFC 2361](https://www.rfc-editor.org/info/rfc2361)
|
|
212
|
+
|
|
213
|
+
No official standards exists for `codecs` values for the
|
|
214
|
+
`application/vnd.ms-asf` and `audio/aiff` MIME types. The most appropriate
|
|
215
|
+
value provided by the format is used.
|
|
216
|
+
|
|
217
|
+
# ASF
|
|
218
|
+
application/vnd.ms-asf
|
|
219
|
+
application/vnd.ms-asf; codecs="<1..>" # WAVE format tag, e.g. "161" (WMA)
|
|
220
|
+
|
|
221
|
+
# AIFF
|
|
222
|
+
audio/aiff
|
|
223
|
+
audio/aiff; codecs="<FourCC>" # AIFF-C compression type, e.g. "alaw"
|
|
224
|
+
|
|
225
|
+
# FLAC
|
|
226
|
+
audio/flac
|
|
227
|
+
|
|
228
|
+
# MP4
|
|
229
|
+
audio/mp4
|
|
230
|
+
audio/mp4; codecs="alac"
|
|
231
|
+
audio/mp4; codecs="mp4a.oo[.A]" # E.g. "mp4a.40.2" for AAC-LC
|
|
232
|
+
|
|
233
|
+
# MP3 / MP2 / MP1
|
|
234
|
+
audio/mpeg
|
|
235
|
+
|
|
236
|
+
# OGG
|
|
237
|
+
audio/ogg
|
|
238
|
+
audio/ogg; codecs="flac"
|
|
239
|
+
audio/ogg; codecs="opus"
|
|
240
|
+
audio/ogg; codecs="speex"
|
|
241
|
+
audio/ogg; codecs="vorbis"
|
|
242
|
+
|
|
243
|
+
# WAV
|
|
244
|
+
audio/wav
|
|
245
|
+
audio/wav; codecs="<1..>" # WAVE format tag, e.g. "1" for PCM
|
|
184
246
|
|
|
185
247
|
### Additional Metadata
|
|
186
248
|
|
|
187
249
|
For additional values of the same field type, uncommon metadata fields, or
|
|
188
250
|
metadata specific to certain file formats, use `other`:
|
|
189
251
|
|
|
190
|
-
|
|
252
|
+
```python
|
|
253
|
+
tag.other: OtherFields # a dictionary of additional fields
|
|
254
|
+
```
|
|
191
255
|
|
|
192
256
|
> [!WARNING]
|
|
193
257
|
> The `other` dictionary has replaced the `extra` dictionary in tinytag 2.0.0.
|
|
@@ -220,6 +284,7 @@ present when files provide such metadata:
|
|
|
220
284
|
show_movement
|
|
221
285
|
url
|
|
222
286
|
work
|
|
287
|
+
xmp
|
|
223
288
|
|
|
224
289
|
Additional `other` field names not documented above may be present, but are
|
|
225
290
|
format-specific and may change or disappear in future tinytag releases. If
|
|
@@ -252,8 +317,10 @@ print(catalog_numbers)
|
|
|
252
317
|
|
|
253
318
|
Output:
|
|
254
319
|
|
|
255
|
-
|
|
256
|
-
|
|
320
|
+
```console
|
|
321
|
+
> 10
|
|
322
|
+
> ['10']
|
|
323
|
+
```
|
|
257
324
|
|
|
258
325
|
When a file contains multiple values for a [common metadata field](#common-metadata)
|
|
259
326
|
(e.g. `artist`), the primary value is accessed through the common attribute
|
|
@@ -275,8 +342,10 @@ print(additional_artists)
|
|
|
275
342
|
|
|
276
343
|
Output:
|
|
277
344
|
|
|
278
|
-
|
|
279
|
-
|
|
345
|
+
```console
|
|
346
|
+
> main artist
|
|
347
|
+
> ['another artist', 'yet another artist']
|
|
348
|
+
```
|
|
280
349
|
|
|
281
350
|
### All Metadata
|
|
282
351
|
|
|
@@ -284,10 +353,12 @@ If you need to receive all available metadata as key-value pairs in a flat
|
|
|
284
353
|
dictionary, use the `as_dict()` method. This combines the common attributes
|
|
285
354
|
and `other` dictionary, which can be more convenient in some cases.
|
|
286
355
|
|
|
287
|
-
|
|
356
|
+
```python
|
|
357
|
+
from tinytag import TinyTag
|
|
288
358
|
|
|
289
|
-
|
|
290
|
-
|
|
359
|
+
tag: TinyTag = TinyTag.get('/some/music.mp3')
|
|
360
|
+
metadata: dict = tag.as_dict()
|
|
361
|
+
```
|
|
291
362
|
|
|
292
363
|
### Images
|
|
293
364
|
|
|
@@ -297,14 +368,18 @@ keyword argument to `TinyTag.get()`.
|
|
|
297
368
|
If you need to receive an image of a specific kind, including its description,
|
|
298
369
|
use `images`:
|
|
299
370
|
|
|
300
|
-
|
|
371
|
+
```python
|
|
372
|
+
tag.images: Images # available embedded images
|
|
373
|
+
```
|
|
301
374
|
|
|
302
375
|
The following common image attributes are available, providing the first
|
|
303
|
-
located
|
|
376
|
+
located `Image` object of each kind:
|
|
304
377
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
378
|
+
```python
|
|
379
|
+
tag.images.front_cover: Image # front cover
|
|
380
|
+
tag.images.back_cover: Image # back cover
|
|
381
|
+
tag.images.media: Image # media (e.g. CD label)
|
|
382
|
+
```
|
|
308
383
|
|
|
309
384
|
When present, any additional images are available in an `images.other`
|
|
310
385
|
dictionary, using the following standardized key names:
|
|
@@ -336,10 +411,13 @@ Provided values are always lists containing at least one `Image` object.
|
|
|
336
411
|
|
|
337
412
|
The `Image` object provides the following attributes:
|
|
338
413
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
414
|
+
```python
|
|
415
|
+
image.data: bytes # image data
|
|
416
|
+
image.size: int # image size in bytes (added in tinytag 2.3.0)
|
|
417
|
+
image.name: str # image name/kind
|
|
418
|
+
image.mime_type: str | None # image MIME type
|
|
419
|
+
image.description: str | None # image description
|
|
420
|
+
```
|
|
343
421
|
|
|
344
422
|
To receive any available image, prioritizing the front cover, use `images.any`:
|
|
345
423
|
|
|
@@ -351,11 +429,13 @@ image: Image | None = tag.images.any
|
|
|
351
429
|
|
|
352
430
|
if image is not None:
|
|
353
431
|
data: bytes = image.data
|
|
432
|
+
size: int = image.size
|
|
354
433
|
name: str = image.name
|
|
355
|
-
mime_type: str = image.mime_type
|
|
356
|
-
description: str = image.description
|
|
434
|
+
mime_type: str | None = image.mime_type
|
|
435
|
+
description: str | None = image.description
|
|
357
436
|
|
|
358
437
|
print(len(data))
|
|
438
|
+
print(size)
|
|
359
439
|
print(name)
|
|
360
440
|
print(mime_type)
|
|
361
441
|
print(description)
|
|
@@ -363,10 +443,13 @@ if image is not None:
|
|
|
363
443
|
|
|
364
444
|
Output:
|
|
365
445
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
446
|
+
```console
|
|
447
|
+
> 74452
|
|
448
|
+
> 74452
|
|
449
|
+
> front_cover
|
|
450
|
+
> image/jpeg
|
|
451
|
+
> some image description
|
|
452
|
+
```
|
|
370
453
|
|
|
371
454
|
> [!WARNING]
|
|
372
455
|
> `tag.images.any` has replaced `tag.get_image()` in tinytag 2.0.0.
|
|
@@ -383,7 +466,7 @@ cover_image: Image = images.front_cover
|
|
|
383
466
|
|
|
384
467
|
if cover_image is not None:
|
|
385
468
|
data: bytes = cover_image.data
|
|
386
|
-
description: str = cover_image.description
|
|
469
|
+
description: str | None = cover_image.description
|
|
387
470
|
```
|
|
388
471
|
|
|
389
472
|
To receive an additional image, e.g. `bright_colored_fish`:
|
|
@@ -401,6 +484,19 @@ if fish_images:
|
|
|
401
484
|
description = image.description
|
|
402
485
|
```
|
|
403
486
|
|
|
487
|
+
### Magic Byte Detection
|
|
488
|
+
|
|
489
|
+
By default, tinytag will determine the file type by 1. checking the file name
|
|
490
|
+
extension, and 2. reading and inspecting magic bytes in the file header.
|
|
491
|
+
|
|
492
|
+
In case you want to disable magic byte detection, e.g. to minimize read
|
|
493
|
+
operations when many non-audio files exist in a folder, pass a
|
|
494
|
+
`check_magic_bytes` argument with a value of `False` (added in tinytag 2.3.0).
|
|
495
|
+
|
|
496
|
+
```python
|
|
497
|
+
tag: TinyTag = TinyTag.get('invalid_file.jpg', check_magic_bytes=False)
|
|
498
|
+
```
|
|
499
|
+
|
|
404
500
|
### Encoding
|
|
405
501
|
|
|
406
502
|
To open files using a specific encoding, you can use the `encoding` parameter.
|
|
@@ -408,7 +504,7 @@ This parameter is however only used for formats where the encoding is not
|
|
|
408
504
|
explicitly specified.
|
|
409
505
|
|
|
410
506
|
```python
|
|
411
|
-
TinyTag.get('a_file_with_gbk_encoding.mp3', encoding='gbk')
|
|
507
|
+
tag: TinyTag = TinyTag.get('a_file_with_gbk_encoding.mp3', encoding='gbk')
|
|
412
508
|
```
|
|
413
509
|
|
|
414
510
|
### File-like Objects
|
|
@@ -417,18 +513,64 @@ To use a file-like object (e.g. BytesIO) instead of a file path, pass a
|
|
|
417
513
|
`file_obj` keyword argument:
|
|
418
514
|
|
|
419
515
|
```python
|
|
420
|
-
TinyTag.get(file_obj=your_file_obj)
|
|
516
|
+
tag: TinyTag = TinyTag.get(file_obj=your_file_obj)
|
|
421
517
|
```
|
|
422
518
|
|
|
423
519
|
### Exceptions
|
|
424
520
|
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
521
|
+
```python
|
|
522
|
+
TinyTagException # Base class for exceptions
|
|
523
|
+
ParseError # Parsing an audio file failed
|
|
524
|
+
UnsupportedFormatError # File format is not supported
|
|
525
|
+
```
|
|
428
526
|
|
|
429
527
|
|
|
430
528
|
## Changelog
|
|
431
529
|
|
|
530
|
+
### 2.3.0 (2026-07-31)
|
|
531
|
+
|
|
532
|
+
- Add 'mime_type' attribute for audio MIME type/codec
|
|
533
|
+
- Add 'is_lossless' attribute to indicate lossless audio
|
|
534
|
+
- Add 'size' attribute to images for size in bytes
|
|
535
|
+
- Add option to disable magic byte detection
|
|
536
|
+
- Make XMP metadata available under 'other.xmp' field
|
|
537
|
+
- Make bit depth available for lossy files providing it
|
|
538
|
+
- Add .asf, .ogv and .wmv to list of supported file extensions
|
|
539
|
+
- Mark deprecated 'extra' dictionary as obsolete
|
|
540
|
+
- Fix incorrect key when adding common images to 'other' dictionary
|
|
541
|
+
- Fix disc/track numbers not being returned as lists in 'as_dict()'
|
|
542
|
+
- Only set audio properties with a positive value
|
|
543
|
+
- Always read tags and audio properties in a single pass
|
|
544
|
+
- ID3: Parse multi-value text frames correctly
|
|
545
|
+
- ID3: Parse COMM and USLT frames correctly
|
|
546
|
+
- ID3: Fix some errors in parsed size calculations
|
|
547
|
+
- ID3: Exclude a few frames with custom structures
|
|
548
|
+
- MPEG: Read VBRI and Xing Info headers for duration/bitrate
|
|
549
|
+
- MPEG: Fix parsing of layer I and MPEG-2 layer III audio properties
|
|
550
|
+
- MPEG: Fix slightly incorrect duration estimation
|
|
551
|
+
- MPEG/MP4: Raise ParseError if header is invalid
|
|
552
|
+
- MP4: Add 'image/bmp' and 'image/gif' MIME types
|
|
553
|
+
- MP4: Fix infinite loop if size of certain sub-atoms is zero
|
|
554
|
+
- MP4: Fix incorrect parsing of descriptor size
|
|
555
|
+
- MP4: Don't read image data when image reading is disabled
|
|
556
|
+
- OGG: Parse multi-stream files correctly
|
|
557
|
+
- Speex: Don't read vendor string as comment
|
|
558
|
+
- FLAC: Provide actual audio bitrate instead of overall bitrate
|
|
559
|
+
- FLAC: Parse VORBIS_COMMENT and PICTURE blocks with invalid size
|
|
560
|
+
- FLAC: Ignore subsequent STREAMINFO blocks
|
|
561
|
+
- WAV: Include unknown fields in 'other' dictionary
|
|
562
|
+
- WAV: Calculate bitrate/duration correctly
|
|
563
|
+
- AIFF/WAV: Read whole ID3 chunk before parsing
|
|
564
|
+
- ASF: Support parsing additional metadata objects
|
|
565
|
+
- ASF: Stop parsing if object size is smaller than header
|
|
566
|
+
- ASF: Make magic header detection more strict
|
|
567
|
+
- Various performance improvements
|
|
568
|
+
- Various code refactors
|
|
569
|
+
|
|
570
|
+
### 2.2.1 (2026-03-15)
|
|
571
|
+
|
|
572
|
+
- ID3: Prevent infinite loop due to malformed SYLT strings
|
|
573
|
+
|
|
432
574
|
### 2.2.0 (2025-12-15)
|
|
433
575
|
|
|
434
576
|
- Add support for movement, work and grouping fields
|
|
@@ -636,7 +778,7 @@ TinyTag.get(file_obj=your_file_obj)
|
|
|
636
778
|
|
|
637
779
|
- fixed decoding of UTF-16LE ID3v2 Tags, improved overall stability
|
|
638
780
|
|
|
639
|
-
### 0.14.0 (2016-06-05)
|
|
781
|
+
### 0.14.0 (2016-06-05)
|
|
640
782
|
|
|
641
783
|
- MP4/M4A and Opus support
|
|
642
784
|
|