0
# OGG Formats
1
2
This document covers Mutagen's support for OGG container-based audio formats including OGG Vorbis, OGG FLAC, OGG Opus, OGG Speex, and OGG Theora. All OGG formats use Vorbis Comments for metadata and share a common container structure.
3
4
## Imports
5
6
```python { .api }
7
# Base OGG container support
8
from mutagen.ogg import OggPage, OggFileType
9
10
# OGG Vorbis
11
from mutagen.oggvorbis import OggVorbis, OggVorbisInfo
12
from mutagen.oggvorbis import Open as OggVorbisOpen, delete as oggvorbis_delete
13
14
# OGG FLAC
15
from mutagen.oggflac import OggFLAC, OggFLACInfo
16
from mutagen.oggflac import Open as OggFLACOpen, delete as oggflac_delete
17
18
# OGG Opus
19
from mutagen.oggopus import OggOpus, OggOpusInfo
20
from mutagen.oggopus import Open as OggOpusOpen, delete as oggopus_delete
21
22
# OGG Speex
23
from mutagen.oggspeex import OggSpeex, OggSpeexInfo
24
from mutagen.oggspeex import Open as OggSpeexOpen, delete as oggspeex_delete
25
26
# OGG Theora (video)
27
from mutagen.oggtheora import OggTheora, OggTheoraInfo
28
from mutagen.oggtheora import Open as OggTheoraOpen, delete as oggtheora_delete
29
30
# Vorbis Comments (shared by all OGG formats)
31
from mutagen._vorbis import VCommentDict
32
```
33
34
## OGG Container Basics
35
36
### Base OGG Support
37
38
```python { .api }
39
class OggPage:
40
"""Individual OGG container page.
41
42
OGG files are composed of pages containing packet data.
43
Each page has headers with sequence numbers, checksums, and flags.
44
45
Attributes:
46
version: OGG version (always 0)
47
type: Page type flags
48
granule_pos: Granule position for timing
49
serial: Logical bitstream serial number
50
sequence: Page sequence number
51
crc: CRC32 checksum
52
data: Page payload data
53
"""
54
55
class OggFileType:
56
"""Base class for OGG-based audio formats.
57
58
All OGG formats inherit from this class and use Vorbis Comments
59
for metadata storage.
60
61
Attributes:
62
tags: VCommentDict (Vorbis Comments) container
63
info: Format-specific stream information
64
"""
65
66
def add_tags(self) -> None:
67
"""Add empty Vorbis Comments if none exist."""
68
69
def save(self) -> None:
70
"""Save Vorbis Comments back to OGG file."""
71
72
def delete(self) -> None:
73
"""Remove all Vorbis Comments from file."""
74
75
# All OGG formats share Vorbis Comments structure
76
class VCommentDict:
77
"""Vorbis Comments dictionary container.
78
79
Case-insensitive field names supporting multiple values per field.
80
Standard fields include TITLE, ARTIST, ALBUM, DATE, etc.
81
"""
82
83
# Standard field names (case-insensitive)
84
STANDARD_FIELDS = [
85
"TITLE", "VERSION", "ALBUM", "TRACKNUMBER", "ARTIST", "PERFORMER",
86
"COPYRIGHT", "LICENSE", "ORGANIZATION", "DESCRIPTION", "GENRE",
87
"DATE", "LOCATION", "CONTACT", "ISRC", "DISCNUMBER", "ALBUMARTIST",
88
"COMPOSER", "LYRICIST", "CONDUCTOR", "REMIXER", "PRODUCER", "ENGINEER"
89
]
90
```
91
92
## OGG Vorbis
93
94
### OggVorbis Class
95
96
```python { .api }
97
class OggVorbis(OggFileType):
98
"""OGG Vorbis audio file.
99
100
Lossy audio compression with high quality and efficient encoding.
101
Uses Vorbis Comments for metadata.
102
103
Attributes:
104
info: OggVorbisInfo with stream details
105
tags: VCommentDict (Vorbis Comments) container
106
filename: Path to OGG Vorbis file
107
"""
108
109
def __init__(self, filename: str) -> None:
110
"""Load OGG Vorbis file and parse metadata.
111
112
Args:
113
filename: Path to .ogg file
114
115
Raises:
116
MutagenError: If file is not valid OGG Vorbis or corrupted
117
"""
118
119
class OggVorbisInfo:
120
"""OGG Vorbis stream information.
121
122
Attributes:
123
length: Duration in seconds (float)
124
bitrate: Average bitrate in bits per second (int)
125
sample_rate: Sample rate in Hz (int)
126
channels: Number of audio channels (int)
127
bitrate_nominal: Nominal bitrate from headers
128
bitrate_minimum: Minimum bitrate (VBR)
129
bitrate_maximum: Maximum bitrate (VBR)
130
version: Vorbis encoder version
131
vendor: Encoder identification string
132
"""
133
134
# Function aliases
135
Open = OggVorbis
136
137
def delete(filename: str) -> None:
138
"""Remove Vorbis Comments from OGG Vorbis file.
139
140
Args:
141
filename: Path to OGG Vorbis file
142
"""
143
144
# Usage examples
145
from mutagen.oggvorbis import OggVorbis
146
147
# Load OGG Vorbis file
148
ogg_file = OggVorbis("song.ogg")
149
150
# Access stream info
151
info = ogg_file.info
152
print(f"Sample rate: {info.sample_rate} Hz")
153
print(f"Channels: {info.channels}")
154
print(f"Bitrate: {info.bitrate} bps")
155
print(f"Encoder: {info.vendor}")
156
157
# Access Vorbis Comments
158
print(ogg_file["TITLE"]) # Title
159
print(ogg_file["ARTIST"]) # Artist
160
print(ogg_file["ALBUM"]) # Album
161
162
# Modify tags
163
ogg_file["TITLE"] = ["New Title"]
164
ogg_file["ARTIST"] = ["New Artist"]
165
ogg_file.save()
166
167
# Multi-value fields
168
ogg_file["GENRE"] = ["Rock", "Alternative"]
169
ogg_file["ARTIST"] = ["Primary Artist", "Featured Artist"]
170
ogg_file.save()
171
```
172
173
## OGG FLAC
174
175
### OggFLAC Class
176
177
```python { .api }
178
class OggFLAC(OggFileType):
179
"""OGG-wrapped FLAC audio file.
180
181
FLAC lossless compression in OGG container instead of native FLAC.
182
Uses Vorbis Comments for metadata (not FLAC metadata blocks).
183
184
Attributes:
185
info: OggFLACInfo with stream details
186
tags: VCommentDict (Vorbis Comments) container
187
filename: Path to OGG FLAC file
188
"""
189
190
class OggFLACInfo:
191
"""OGG FLAC stream information.
192
193
Attributes:
194
length: Duration in seconds (float)
195
bitrate: Average bitrate in bits per second (int)
196
sample_rate: Sample rate in Hz (int)
197
channels: Number of audio channels (int)
198
bits_per_sample: Bit depth (typically 16 or 24)
199
total_samples: Total number of audio samples
200
"""
201
202
# Function aliases
203
Open = OggFLAC
204
205
def delete(filename: str) -> None:
206
"""Remove Vorbis Comments from OGG FLAC file."""
207
208
# Usage examples
209
from mutagen.oggflac import OggFLAC
210
211
# Load OGG FLAC file
212
oggflac_file = OggFLAC("song.oga")
213
214
# Stream info (similar to regular FLAC)
215
info = oggflac_file.info
216
print(f"Sample rate: {info.sample_rate} Hz")
217
print(f"Bit depth: {info.bits_per_sample} bits")
218
print(f"Total samples: {info.total_samples}")
219
220
# Vorbis Comments (not FLAC metadata blocks)
221
oggflac_file["TITLE"] = ["Song Title"]
222
oggflac_file["ARTIST"] = ["Artist Name"]
223
oggflac_file.save()
224
```
225
226
## OGG Opus
227
228
### OggOpus Class
229
230
```python { .api }
231
class OggOpus(OggFileType):
232
"""OGG Opus audio file.
233
234
Modern low-latency audio codec optimized for speech and music.
235
Excellent quality at low bitrates with Vorbis Comments metadata.
236
237
Attributes:
238
info: OggOpusInfo with stream details
239
tags: VCommentDict (Vorbis Comments) container
240
filename: Path to OGG Opus file
241
"""
242
243
class OggOpusInfo:
244
"""OGG Opus stream information.
245
246
Attributes:
247
length: Duration in seconds (float)
248
bitrate: Bitrate in bits per second (int)
249
sample_rate: Original sample rate before encoding (int)
250
channels: Number of audio channels (int)
251
version: Opus version
252
gain: Output gain adjustment in dB
253
pre_skip: Pre-skip samples for padding
254
vendor: Encoder identification string
255
"""
256
257
# Function aliases
258
Open = OggOpus
259
260
def delete(filename: str) -> None:
261
"""Remove Vorbis Comments from OGG Opus file."""
262
263
# Usage examples
264
from mutagen.oggopus import OggOpus
265
266
# Load OGG Opus file
267
opus_file = OggOpus("song.opus")
268
269
# Opus-specific info
270
info = opus_file.info
271
print(f"Original sample rate: {info.sample_rate} Hz")
272
print(f"Output gain: {info.gain} dB")
273
print(f"Pre-skip: {info.pre_skip} samples")
274
print(f"Encoder: {info.vendor}")
275
276
# Standard Vorbis Comments
277
opus_file["TITLE"] = ["Song Title"]
278
opus_file["ARTIST"] = ["Artist Name"]
279
opus_file.save()
280
```
281
282
## OGG Speex
283
284
### OggSpeex Class
285
286
```python { .api }
287
class OggSpeex(OggFileType):
288
"""OGG Speex audio file.
289
290
Speech-optimized lossy compression codec designed for voice.
291
Uses Vorbis Comments for metadata.
292
293
Attributes:
294
info: OggSpeexInfo with stream details
295
tags: VCommentDict (Vorbis Comments) container
296
filename: Path to OGG Speex file
297
"""
298
299
class OggSpeexInfo:
300
"""OGG Speex stream information.
301
302
Attributes:
303
length: Duration in seconds (float)
304
bitrate: Bitrate in bits per second (int)
305
sample_rate: Sample rate in Hz (int)
306
channels: Number of audio channels (int)
307
mode: Speex encoding mode
308
vbr: Variable bitrate flag
309
version: Speex version
310
vendor: Encoder identification string
311
"""
312
313
# Function aliases
314
Open = OggSpeex
315
316
def delete(filename: str) -> None:
317
"""Remove Vorbis Comments from OGG Speex file."""
318
319
# Usage examples
320
from mutagen.oggspeex import OggSpeex
321
322
# Load OGG Speex file
323
speex_file = OggSpeex("speech.spx")
324
325
# Speex-specific info
326
info = speex_file.info
327
print(f"Encoding mode: {info.mode}")
328
print(f"Variable bitrate: {info.vbr}")
329
print(f"Speex version: {info.version}")
330
331
# Vorbis Comments
332
speex_file["TITLE"] = ["Speech Recording"]
333
speex_file["ARTIST"] = ["Speaker Name"]
334
speex_file.save()
335
```
336
337
## OGG Theora (Video)
338
339
### OggTheora Class
340
341
```python { .api }
342
class OggTheora(OggFileType):
343
"""OGG Theora video file.
344
345
Open video codec in OGG container. Supports Vorbis Comments
346
for metadata even though it's primarily a video format.
347
348
Attributes:
349
info: OggTheoraInfo with stream details
350
tags: VCommentDict (Vorbis Comments) container
351
filename: Path to OGG Theora file
352
"""
353
354
class OggTheoraInfo:
355
"""OGG Theora stream information.
356
357
Attributes:
358
length: Duration in seconds (float)
359
bitrate: Video bitrate in bits per second (int)
360
fps: Frames per second (float)
361
width: Video width in pixels (int)
362
height: Video height in pixels (int)
363
version: Theora version tuple
364
vendor: Encoder identification string
365
"""
366
367
# Function aliases
368
Open = OggTheora
369
370
def delete(filename: str) -> None:
371
"""Remove Vorbis Comments from OGG Theora file."""
372
373
# Usage examples
374
from mutagen.oggtheora import OggTheora
375
376
# Load OGG Theora file
377
theora_file = OggTheora("video.ogv")
378
379
# Video-specific info
380
info = theora_file.info
381
print(f"Resolution: {info.width}x{info.height}")
382
print(f"Frame rate: {info.fps} fps")
383
print(f"Encoder: {info.vendor}")
384
385
# Metadata for video
386
theora_file["TITLE"] = ["Video Title"]
387
theora_file["DESCRIPTION"] = ["Video description"]
388
theora_file.save()
389
```
390
391
## Vorbis Comments (Shared Metadata)
392
393
All OGG formats use Vorbis Comments for metadata:
394
395
```python { .api }
396
# Standard Vorbis Comment fields (case-insensitive)
397
VORBIS_FIELDS = {
398
# Basic metadata
399
"TITLE": "Track title",
400
"VERSION": "Version of track (e.g. remix info)",
401
"ALBUM": "Album name",
402
"TRACKNUMBER": "Track number",
403
"ARTIST": "Artist name",
404
"PERFORMER": "Performer name",
405
"ALBUMARTIST": "Album artist",
406
407
# Additional credits
408
"COMPOSER": "Composer name",
409
"LYRICIST": "Lyricist name",
410
"CONDUCTOR": "Conductor name",
411
"REMIXER": "Remixer name",
412
"PRODUCER": "Producer name",
413
"ENGINEER": "Engineer name",
414
415
# Classification
416
"GENRE": "Genre classification",
417
"DATE": "Date of recording/release",
418
"DISCNUMBER": "Disc number in set",
419
420
# Technical/legal
421
"ORGANIZATION": "Organization/label",
422
"COPYRIGHT": "Copyright information",
423
"LICENSE": "License information",
424
"ISRC": "International Standard Recording Code",
425
"LOCATION": "Recording location",
426
"CONTACT": "Contact information",
427
428
# Content
429
"DESCRIPTION": "Description/comment",
430
"LYRICS": "Song lyrics",
431
}
432
433
# Usage examples for any OGG format
434
ogg_file = OggVorbis("song.ogg") # or OggFLAC, OggOpus, etc.
435
436
# Basic tags
437
ogg_file["TITLE"] = ["Song Title"]
438
ogg_file["ARTIST"] = ["Artist Name"]
439
ogg_file["ALBUM"] = ["Album Name"]
440
ogg_file["DATE"] = ["2023"]
441
ogg_file["TRACKNUMBER"] = ["1"]
442
ogg_file["DISCNUMBER"] = ["1"]
443
444
# Multiple values
445
ogg_file["GENRE"] = ["Rock", "Alternative"]
446
ogg_file["ARTIST"] = ["Primary Artist", "Featured Artist"]
447
448
# Extended metadata
449
ogg_file["ALBUMARTIST"] = ["Album Artist"]
450
ogg_file["COMPOSER"] = ["Composer Name"]
451
ogg_file["PRODUCER"] = ["Producer Name"]
452
ogg_file["ORGANIZATION"] = ["Record Label"]
453
ogg_file["COPYRIGHT"] = ["2023 Copyright Holder"]
454
455
# Custom fields (any name allowed)
456
ogg_file["CUSTOM_FIELD"] = ["Custom Value"]
457
ogg_file["MOOD"] = ["Happy"]
458
ogg_file["TEMPO"] = ["Fast"]
459
460
# Case insensitive access
461
ogg_file["title"] = ["Same as TITLE"]
462
ogg_file["Title"] = ["Same as TITLE"]
463
464
ogg_file.save()
465
466
# Reading tags
467
for key, values in ogg_file.items():
468
print(f"{key}: {', '.join(values)}")
469
```
470
471
## Practical Examples
472
473
### Cross-OGG Format Tagging
474
475
```python
476
def tag_ogg_file(filename, metadata):
477
"""Tag any OGG format file with standard metadata."""
478
import mutagen
479
480
ogg_file = mutagen.File(filename)
481
if not ogg_file or not hasattr(ogg_file, 'tags'):
482
return False
483
484
# All OGG formats use Vorbis Comments
485
if ogg_file.tags is None:
486
ogg_file.add_tags()
487
488
# Standard fields
489
field_mapping = {
490
'title': 'TITLE',
491
'artist': 'ARTIST',
492
'album': 'ALBUM',
493
'date': 'DATE',
494
'track': 'TRACKNUMBER',
495
'disc': 'DISCNUMBER',
496
'genre': 'GENRE',
497
'albumartist': 'ALBUMARTIST',
498
'composer': 'COMPOSER'
499
}
500
501
for source_key, vorbis_key in field_mapping.items():
502
if source_key in metadata:
503
value = metadata[source_key]
504
if isinstance(value, list):
505
ogg_file[vorbis_key] = value
506
else:
507
ogg_file[vorbis_key] = [str(value)]
508
509
ogg_file.save()
510
return True
511
512
# Usage with different OGG formats
513
metadata = {
514
'title': 'Song Title',
515
'artist': 'Artist Name',
516
'album': 'Album Name',
517
'date': '2023',
518
'track': 1,
519
'genre': ['Rock', 'Alternative']
520
}
521
522
tag_ogg_file("song.ogg", metadata) # OGG Vorbis
523
tag_ogg_file("song.oga", metadata) # OGG FLAC
524
tag_ogg_file("song.opus", metadata) # OGG Opus
525
tag_ogg_file("speech.spx", metadata) # OGG Speex
526
```
527
528
### OGG Format Detection
529
530
```python
531
def identify_ogg_format(filename):
532
"""Identify specific OGG format and codec."""
533
import mutagen
534
535
ogg_file = mutagen.File(filename)
536
if not ogg_file:
537
return "Unknown"
538
539
format_name = ogg_file.__class__.__name__
540
format_info = {
541
'OggVorbis': 'OGG Vorbis (Lossy)',
542
'OggFLAC': 'OGG FLAC (Lossless)',
543
'OggOpus': 'OGG Opus (Low-latency)',
544
'OggSpeex': 'OGG Speex (Speech)',
545
'OggTheora': 'OGG Theora (Video)'
546
}
547
548
format_desc = format_info.get(format_name, format_name)
549
550
# Additional details
551
info = ogg_file.info
552
details = {
553
'format': format_desc,
554
'sample_rate': getattr(info, 'sample_rate', 'N/A'),
555
'channels': getattr(info, 'channels', 'N/A'),
556
'bitrate': getattr(info, 'bitrate', 'N/A'),
557
'duration': getattr(info, 'length', 0)
558
}
559
560
if hasattr(info, 'vendor'):
561
details['encoder'] = info.vendor
562
563
return details
564
565
# Usage
566
details = identify_ogg_format("audio.ogg")
567
print(f"Format: {details['format']}")
568
print(f"Sample rate: {details['sample_rate']} Hz")
569
print(f"Bitrate: {details['bitrate']} bps")
570
```
571
572
### Batch OGG Processing
573
574
```python
575
import os
576
import mutagen
577
578
def process_ogg_directory(directory):
579
"""Process all OGG files in directory."""
580
ogg_extensions = ['.ogg', '.oga', '.opus', '.spx', '.ogv']
581
582
for filename in os.listdir(directory):
583
if any(filename.lower().endswith(ext) for ext in ogg_extensions):
584
filepath = os.path.join(directory, filename)
585
586
try:
587
ogg_file = mutagen.File(filepath)
588
if ogg_file and hasattr(ogg_file, 'tags'):
589
590
# Print current metadata
591
print(f"\n{filename}:")
592
print(f" Format: {ogg_file.__class__.__name__}")
593
print(f" Duration: {ogg_file.info.length:.2f}s")
594
595
if ogg_file.tags:
596
for key, values in ogg_file.tags.items():
597
print(f" {key}: {', '.join(values)}")
598
else:
599
print(" No metadata found")
600
601
except Exception as e:
602
print(f"Error processing {filename}: {e}")
603
604
# Usage
605
process_ogg_directory("/path/to/ogg/files")
606
```
607
608
## Format Comparison
609
610
| Format | Codec | Quality | Use Case | Container |
611
|--------|-------|---------|----------|-----------|
612
| OGG Vorbis | Vorbis | High quality lossy | General music | OGG |
613
| OGG FLAC | FLAC | Lossless | Archival quality | OGG |
614
| OGG Opus | Opus | Excellent at low bitrates | Streaming, VoIP | OGG |
615
| OGG Speex | Speex | Speech optimized | Voice recordings | OGG |
616
| OGG Theora | Theora | Video codec | Video files | OGG |
617
618
All formats share:
619
- **Vorbis Comments** for metadata
620
- **Open source** codecs
621
- **Cross-platform** support
622
- **Streaming** capabilities
623
624
## See Also
625
626
- [Mutagen](./index.md) - Main documentation and overview
627
- [Lossless Audio Formats](./lossless-formats.md) - Native FLAC and other lossless formats
628
- [Core Functionality](./core-functionality.md) - Base classes and common patterns
629
- [Easy Interfaces](./easy-interfaces.md) - Simplified cross-format tag access