0
# Lossless Audio Formats
1
2
This document covers Mutagen's support for lossless audio compression formats including FLAC, WavPack, TrueAudio, APE (Monkey's Audio), and other lossless codecs. These formats preserve perfect audio quality while providing compression and comprehensive metadata support.
3
4
## Imports
5
6
```python { .api }
7
# FLAC format
8
from mutagen.flac import FLAC, StreamInfo, VCFLACDict, MetadataBlock
9
from mutagen.flac import SeekTable, SeekPoint, CueSheet, CueSheetTrack, Picture, Padding
10
from mutagen.flac import Open, delete
11
12
# WavPack format
13
from mutagen.wavpack import WavPack, WavPackInfo
14
from mutagen.wavpack import Open as WavPackOpen, delete as wavpack_delete
15
16
# TrueAudio format
17
from mutagen.trueaudio import TrueAudio, TrueAudioInfo, EasyTrueAudio
18
from mutagen.trueaudio import Open as TrueAudioOpen, delete as trueaudio_delete
19
20
# APE format (Monkey's Audio)
21
from mutagen.monkeysaudio import MonkeysAudio, MonkeysAudioInfo
22
23
# APEv2 tags (standalone and attached)
24
from mutagen.apev2 import APEv2, APEv2File, APEItem, APEValue, APETextValue, APEBinaryValue
25
26
# Other lossless formats
27
from mutagen.tak import TAK, TAKInfo
28
from mutagen.optimfrog import OptimFROG, OptimFROGInfo
29
30
# Uncompressed formats
31
from mutagen.wave import WAVE, WaveInfo
32
from mutagen.aiff import AIFF, AIFFInfo
33
34
# High-resolution formats
35
from mutagen.dsf import DSF, DSFInfo
36
from mutagen.dsdiff import DSDIFF, DSDIFFInfo
37
```
38
39
## FLAC (Free Lossless Audio Codec)
40
41
### FLAC Class
42
43
```python { .api }
44
class FLAC:
45
"""Free Lossless Audio Codec file with Vorbis Comments.
46
47
FLAC provides lossless compression with excellent metadata support through
48
Vorbis Comments and metadata blocks for pictures, cue sheets, and more.
49
50
Attributes:
51
info: FLAC StreamInfo with technical details
52
tags: VCFLACDict (Vorbis Comments) container
53
metadata_blocks: List of all FLAC metadata blocks
54
filename: Path to the FLAC file
55
"""
56
57
def __init__(self, filename: str) -> None:
58
"""Load FLAC file and parse metadata blocks.
59
60
Args:
61
filename: Path to FLAC file
62
63
Raises:
64
MutagenError: If file is not valid FLAC or corrupted
65
"""
66
67
def add_tags(self) -> None:
68
"""Add empty Vorbis Comments block if none exists."""
69
70
def clear_pictures(self) -> None:
71
"""Remove all embedded picture blocks."""
72
73
def add_picture(self, picture: Picture) -> None:
74
"""Add embedded picture metadata block.
75
76
Args:
77
picture: Picture metadata block instance
78
"""
79
80
def save(self, deleteid3=False, padding=None) -> None:
81
"""Save FLAC metadata and tags.
82
83
Args:
84
deleteid3: Remove ID3 tags if present
85
padding: Custom padding function or None for default
86
"""
87
88
class StreamInfo:
89
"""FLAC stream information metadata block.
90
91
Contains technical details about the FLAC audio stream.
92
93
Attributes:
94
length: Duration in seconds (float)
95
bitrate: Average bitrate in bits per second (int)
96
sample_rate: Sample rate in Hz (int)
97
channels: Number of audio channels (int)
98
bits_per_sample: Bit depth (typically 16 or 24)
99
total_samples: Total number of audio samples
100
min_blocksize: Minimum block size used
101
max_blocksize: Maximum block size used
102
min_framesize: Minimum frame size used
103
max_framesize: Maximum frame size used
104
md5_signature: MD5 hash of audio data (bytes)
105
"""
106
107
# Function aliases
108
Open = FLAC
109
110
def delete(filename: str) -> None:
111
"""Remove FLAC metadata while preserving audio.
112
113
Args:
114
filename: Path to FLAC file
115
"""
116
117
# Usage examples
118
from mutagen.flac import FLAC
119
120
# Load FLAC file
121
flac_file = FLAC("song.flac")
122
123
# Access stream info
124
info = flac_file.info
125
print(f"Sample rate: {info.sample_rate} Hz")
126
print(f"Bit depth: {info.bits_per_sample} bits")
127
print(f"Channels: {info.channels}")
128
print(f"Duration: {info.length} seconds")
129
130
# Access Vorbis Comments
131
print(flac_file["TITLE"]) # Title
132
print(flac_file["ARTIST"]) # Artist
133
print(flac_file["ALBUM"]) # Album
134
135
# Modify tags
136
flac_file["TITLE"] = ["New Title"]
137
flac_file["ARTIST"] = ["New Artist"]
138
flac_file.save()
139
```
140
141
### FLAC Metadata Blocks
142
143
```python { .api }
144
class MetadataBlock:
145
"""Generic FLAC metadata block.
146
147
Base class for all FLAC metadata block types including
148
StreamInfo, Vorbis Comments, Pictures, CueSheet, etc.
149
"""
150
151
class Picture:
152
"""FLAC picture metadata block for embedded artwork.
153
154
Attributes:
155
type: Picture type (same as ID3 APIC types)
156
mime: MIME type string (e.g., 'image/jpeg')
157
desc: Picture description string
158
width: Image width in pixels
159
height: Image height in pixels
160
depth: Color depth in bits
161
colors: Number of colors for indexed images
162
data: Image data bytes
163
"""
164
165
class CueSheet:
166
"""FLAC cue sheet metadata block.
167
168
Contains CD track layout information for audio CDs.
169
170
Attributes:
171
media_catalog_number: CD media catalog number
172
lead_in: Number of lead-in samples
173
compact_disc: True if from compact disc
174
tracks: List of CueSheetTrack instances
175
"""
176
177
class CueSheetTrack:
178
"""Individual track in FLAC cue sheet.
179
180
Attributes:
181
track_number: Track number (1-99, or 170 for lead-out)
182
start_offset: Track start offset in samples
183
isrc: International Standard Recording Code
184
type: Track type flags
185
pre_emphasis: Pre-emphasis flag
186
indexes: List of index points
187
"""
188
189
class SeekTable:
190
"""FLAC seek table metadata block for fast seeking.
191
192
Contains seek points for efficient random access.
193
194
Attributes:
195
seekpoints: List of SeekPoint instances
196
"""
197
198
class SeekPoint:
199
"""Individual seek point in FLAC seek table.
200
201
Attributes:
202
sample_number: Sample number for this seek point
203
stream_offset: Byte offset in stream
204
frame_samples: Number of samples in frame
205
"""
206
207
# Usage examples
208
from mutagen.flac import FLAC, Picture
209
210
# Add embedded artwork
211
flac_file = FLAC("song.flac")
212
213
with open("cover.jpg", "rb") as f:
214
image_data = f.read()
215
216
picture = Picture()
217
picture.type = 3 # Front cover
218
picture.mime = "image/jpeg"
219
picture.desc = "Album Cover"
220
picture.data = image_data
221
222
flac_file.add_picture(picture)
223
flac_file.save()
224
225
# Access all metadata blocks
226
for block in flac_file.metadata_blocks:
227
print(f"Block type: {block.__class__.__name__}")
228
```
229
230
### Vorbis Comments in FLAC
231
232
```python { .api }
233
class VCFLACDict:
234
"""Vorbis Comments container for FLAC files.
235
236
Dictionary-like interface for FLAC Vorbis Comment tags.
237
Field names are case-insensitive and support multiple values.
238
"""
239
240
# Common field names (case-insensitive)
241
# TITLE, ARTIST, ALBUM, DATE, TRACKNUMBER, DISCNUMBER
242
# GENRE, ALBUMARTIST, COMPOSER, PERFORMER, etc.
243
244
# Usage examples
245
flac_file = FLAC("song.flac")
246
tags = flac_file.tags
247
248
# Standard fields
249
tags["TITLE"] = ["Song Title"]
250
tags["ARTIST"] = ["Artist Name"]
251
tags["ALBUM"] = ["Album Name"]
252
tags["DATE"] = ["2023"]
253
tags["TRACKNUMBER"] = ["1"]
254
tags["DISCNUMBER"] = ["1"]
255
256
# Multi-value fields
257
tags["GENRE"] = ["Rock", "Alternative"]
258
tags["ARTIST"] = ["Primary Artist", "Featured Artist"]
259
260
# Custom fields
261
tags["CUSTOM_FIELD"] = ["Custom Value"]
262
263
# Case insensitive access
264
tags["title"] = ["Same as TITLE"]
265
tags["Title"] = ["Same as TITLE"]
266
267
flac_file.save()
268
```
269
270
## WavPack
271
272
```python { .api }
273
class WavPack:
274
"""WavPack lossless/hybrid audio file.
275
276
Supports both lossless and hybrid (lossy + correction) modes.
277
Uses APEv2 tags for metadata.
278
279
Attributes:
280
info: WavPackInfo with stream details
281
tags: APEv2 tag container
282
filename: Path to WavPack file
283
"""
284
285
class WavPackInfo:
286
"""WavPack stream information.
287
288
Attributes:
289
length: Duration in seconds
290
bitrate: Bitrate in bits per second
291
sample_rate: Sample rate in Hz
292
channels: Number of channels
293
bits_per_sample: Bit depth
294
version: WavPack version
295
mode: Compression mode info
296
"""
297
298
# Usage examples
299
from mutagen.wavpack import WavPack
300
301
wv_file = WavPack("song.wv")
302
print(f"Sample rate: {wv_file.info.sample_rate}")
303
print(f"Mode: {wv_file.info.mode}")
304
305
# APEv2 tags
306
wv_file["Title"] = "Song Title"
307
wv_file["Artist"] = "Artist Name"
308
wv_file.save()
309
```
310
311
## TrueAudio
312
313
```python { .api }
314
class TrueAudio:
315
"""TrueAudio lossless audio file.
316
317
Uses ID3v2 tags (like MP3) for metadata.
318
319
Attributes:
320
info: TrueAudioInfo with stream details
321
tags: ID3 tag container
322
filename: Path to TrueAudio file
323
"""
324
325
class EasyTrueAudio(TrueAudio):
326
"""TrueAudio with EasyID3 interface."""
327
328
class TrueAudioInfo:
329
"""TrueAudio stream information.
330
331
Attributes:
332
length: Duration in seconds
333
bitrate: Bitrate in bits per second
334
sample_rate: Sample rate in Hz
335
channels: Number of channels
336
bits_per_sample: Bit depth
337
version: TrueAudio version
338
"""
339
340
# Usage examples
341
from mutagen.trueaudio import TrueAudio, EasyTrueAudio
342
343
# Standard interface (uses ID3 frames)
344
tta_file = TrueAudio("song.tta")
345
tta_file["TIT2"] = "Song Title" # ID3 frame
346
tta_file.save()
347
348
# Easy interface
349
easy_tta = EasyTrueAudio("song.tta")
350
easy_tta["title"] = ["Song Title"] # Normalized name
351
easy_tta.save()
352
```
353
354
## APE (Monkey's Audio)
355
356
```python { .api }
357
class MonkeysAudio:
358
"""Monkey's Audio lossless file.
359
360
Uses APEv2 tags for metadata.
361
362
Attributes:
363
info: MonkeysAudioInfo with stream details
364
tags: APEv2 tag container
365
filename: Path to APE file
366
"""
367
368
class MonkeysAudioInfo:
369
"""Monkey's Audio stream information.
370
371
Attributes:
372
length: Duration in seconds
373
bitrate: Bitrate in bits per second
374
sample_rate: Sample rate in Hz
375
channels: Number of channels
376
bits_per_sample: Bit depth
377
compression_level: Compression level used
378
version: APE format version
379
"""
380
381
# Usage examples
382
from mutagen.monkeysaudio import MonkeysAudio
383
384
ape_file = MonkeysAudio("song.ape")
385
print(f"Compression: {ape_file.info.compression_level}")
386
387
# APEv2 tags
388
ape_file["Title"] = "Song Title"
389
ape_file["Artist"] = "Artist Name"
390
ape_file.save()
391
```
392
393
## APEv2 Tags
394
395
```python { .api }
396
class APEv2:
397
"""APEv2 tag container.
398
399
Can be used standalone or attached to audio files.
400
Dictionary-like interface with case-insensitive keys.
401
402
Attributes:
403
version: APEv2 version (usually 2000)
404
is_header: True if header is present
405
is_footer: True if footer is present
406
read_only: True if tags are read-only
407
"""
408
409
class APEv2File:
410
"""File with APEv2 tags attached.
411
412
Base class for formats that use APEv2 tags.
413
"""
414
415
class APEItem:
416
"""Individual APEv2 tag item.
417
418
Can contain text, binary data, or external references.
419
420
Attributes:
421
key: Tag key name
422
value: APEValue instance containing data
423
read_only: True if item is read-only
424
"""
425
426
# Usage examples
427
from mutagen.apev2 import APEv2
428
429
# Standalone APEv2 tags
430
tags = APEv2("file_with_ape_tags.mp3")
431
432
# Text items
433
tags["Title"] = "Song Title"
434
tags["Artist"] = "Artist Name"
435
tags["Album"] = "Album Name"
436
437
# Multi-value text
438
tags["Genre"] = "Rock\0Alternative" # Null-separated
439
440
# Custom binary data
441
tags["CustomData"] = b"Binary content here"
442
443
tags.save()
444
```
445
446
## Other Lossless Formats
447
448
### TAK (Tom's lossless Audio Kompressor)
449
450
```python { .api }
451
class TAK:
452
"""TAK lossless audio file.
453
454
Uses APEv2 tags for metadata.
455
"""
456
457
class TAKInfo:
458
"""TAK stream information."""
459
460
# Usage
461
from mutagen.tak import TAK
462
463
tak_file = TAK("song.tak")
464
tak_file["Title"] = "Song Title"
465
tak_file.save()
466
```
467
468
### OptimFROG
469
470
```python { .api }
471
class OptimFROG:
472
"""OptimFROG lossless audio file.
473
474
Uses APEv2 tags for metadata.
475
"""
476
477
class OptimFROGInfo:
478
"""OptimFROG stream information."""
479
480
# Usage
481
from mutagen.optimfrog import OptimFROG
482
483
ofr_file = OptimFROG("song.ofr")
484
ofr_file["Title"] = "Song Title"
485
ofr_file.save()
486
```
487
488
## Uncompressed Formats
489
490
### WAVE Files
491
492
```python { .api }
493
class WAVE:
494
"""WAVE audio file.
495
496
Supports ID3v2 tags and RIFF INFO chunks.
497
"""
498
499
class WaveInfo:
500
"""WAVE stream information.
501
502
Attributes:
503
length: Duration in seconds
504
bitrate: Bitrate in bits per second
505
sample_rate: Sample rate in Hz
506
channels: Number of channels
507
bits_per_sample: Bit depth
508
"""
509
510
# Usage
511
from mutagen.wave import WAVE
512
513
wave_file = WAVE("song.wav")
514
print(f"Sample rate: {wave_file.info.sample_rate}")
515
516
# Uses ID3v2 tags like MP3
517
wave_file["TIT2"] = "Song Title"
518
wave_file.save()
519
```
520
521
### AIFF Files
522
523
```python { .api }
524
class AIFF:
525
"""Audio Interchange File Format file.
526
527
Supports ID3v2 tags.
528
"""
529
530
class AIFFInfo:
531
"""AIFF stream information."""
532
533
# Usage
534
from mutagen.aiff import AIFF
535
536
aiff_file = AIFF("song.aiff")
537
aiff_file["TIT2"] = "Song Title" # ID3v2 tags
538
aiff_file.save()
539
```
540
541
## High-Resolution Formats
542
543
### DSF (DSD Stream File)
544
545
```python { .api }
546
class DSF:
547
"""DSD Stream File (Super Audio CD format).
548
549
High-resolution 1-bit audio format.
550
Uses ID3v2 tags for metadata.
551
"""
552
553
class DSFInfo:
554
"""DSF stream information.
555
556
Attributes:
557
length: Duration in seconds
558
bitrate: Bitrate in bits per second
559
sample_rate: DSD sample rate (typically 2.8MHz or 5.6MHz)
560
channels: Number of channels
561
"""
562
563
# Usage
564
from mutagen.dsf import DSF
565
566
dsf_file = DSF("song.dsf")
567
print(f"DSD sample rate: {dsf_file.info.sample_rate}")
568
569
# ID3v2 tags
570
dsf_file["TIT2"] = "Song Title"
571
dsf_file.save()
572
```
573
574
### DSDIFF (DSD Interchange File Format)
575
576
```python { .api }
577
class DSDIFF:
578
"""DSD Interchange File Format file.
579
580
Another DSD format with different metadata handling.
581
"""
582
583
class DSDIFFInfo:
584
"""DSDIFF stream information."""
585
586
# Usage
587
from mutagen.dsdiff import DSDIFF
588
589
dff_file = DSDIFF("song.dff")
590
print(f"DSD sample rate: {dff_file.info.sample_rate}")
591
```
592
593
## Practical Examples
594
595
### Cross-Format Lossless Tagging
596
597
```python
598
def tag_lossless_file(filename, metadata):
599
"""Tag lossless audio file with common metadata."""
600
import mutagen
601
602
audio_file = mutagen.File(filename)
603
if not audio_file:
604
return False
605
606
format_name = audio_file.__class__.__name__
607
608
if format_name == "FLAC":
609
# Vorbis Comments
610
audio_file["TITLE"] = [metadata.get("title", "")]
611
audio_file["ARTIST"] = [metadata.get("artist", "")]
612
audio_file["ALBUM"] = [metadata.get("album", "")]
613
614
elif format_name in ["WavPack", "MonkeysAudio", "TAK", "OptimFROG"]:
615
# APEv2 tags
616
audio_file["Title"] = metadata.get("title", "")
617
audio_file["Artist"] = metadata.get("artist", "")
618
audio_file["Album"] = metadata.get("album", "")
619
620
elif format_name in ["TrueAudio", "WAVE", "AIFF", "DSF"]:
621
# ID3v2 tags
622
from mutagen.id3 import TIT2, TPE1, TALB
623
audio_file["TIT2"] = TIT2(encoding=3, text=[metadata.get("title", "")])
624
audio_file["TPE1"] = TPE1(encoding=3, text=[metadata.get("artist", "")])
625
audio_file["TALB"] = TALB(encoding=3, text=[metadata.get("album", "")])
626
627
audio_file.save()
628
return True
629
630
# Usage
631
metadata = {
632
"title": "Song Title",
633
"artist": "Artist Name",
634
"album": "Album Name"
635
}
636
637
tag_lossless_file("song.flac", metadata)
638
tag_lossless_file("song.wv", metadata)
639
tag_lossless_file("song.tta", metadata)
640
```
641
642
### FLAC with Complete Metadata
643
644
```python
645
from mutagen.flac import FLAC, Picture
646
647
def setup_flac_complete(filename, metadata, cover_path=None):
648
"""Set up FLAC file with complete metadata and artwork."""
649
flac_file = FLAC(filename)
650
651
# Basic tags
652
flac_file["TITLE"] = [metadata["title"]]
653
flac_file["ARTIST"] = [metadata["artist"]]
654
flac_file["ALBUM"] = [metadata["album"]]
655
flac_file["DATE"] = [metadata["date"]]
656
flac_file["TRACKNUMBER"] = [str(metadata["track"])]
657
flac_file["DISCNUMBER"] = [str(metadata.get("disc", 1))]
658
659
# Optional tags
660
if "albumartist" in metadata:
661
flac_file["ALBUMARTIST"] = [metadata["albumartist"]]
662
if "genre" in metadata:
663
flac_file["GENRE"] = metadata["genre"] if isinstance(metadata["genre"], list) else [metadata["genre"]]
664
665
# Add artwork
666
if cover_path:
667
with open(cover_path, "rb") as f:
668
image_data = f.read()
669
670
picture = Picture()
671
picture.type = 3 # Front cover
672
picture.mime = "image/jpeg"
673
picture.desc = "Front Cover"
674
picture.data = image_data
675
676
flac_file.clear_pictures() # Remove existing
677
flac_file.add_picture(picture)
678
679
flac_file.save()
680
print(f"FLAC file tagged: {filename}")
681
682
# Usage
683
metadata = {
684
"title": "Song Title",
685
"artist": "Artist Name",
686
"album": "Album Name",
687
"date": "2023",
688
"track": 1,
689
"disc": 1,
690
"albumartist": "Album Artist",
691
"genre": ["Rock", "Alternative"]
692
}
693
694
setup_flac_complete("song.flac", metadata, "cover.jpg")
695
```
696
697
## See Also
698
699
- [Mutagen](./index.md) - Main documentation and overview
700
- [MP3 and ID3 Tags](./mp3-id3.md) - MP3 format and ID3 tagging
701
- [Container Formats](./container-formats.md) - MP4, ASF/WMA containers
702
- [OGG Formats](./ogg-formats.md) - OGG-based audio formats