Python library for handling audio metadata across multiple formats including MP3, FLAC, MP4, OGG and many others
—
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.
# Base OGG container support
from mutagen.ogg import OggPage, OggFileType
# OGG Vorbis
from mutagen.oggvorbis import OggVorbis, OggVorbisInfo
from mutagen.oggvorbis import Open as OggVorbisOpen, delete as oggvorbis_delete
# OGG FLAC
from mutagen.oggflac import OggFLAC, OggFLACInfo
from mutagen.oggflac import Open as OggFLACOpen, delete as oggflac_delete
# OGG Opus
from mutagen.oggopus import OggOpus, OggOpusInfo
from mutagen.oggopus import Open as OggOpusOpen, delete as oggopus_delete
# OGG Speex
from mutagen.oggspeex import OggSpeex, OggSpeexInfo
from mutagen.oggspeex import Open as OggSpeexOpen, delete as oggspeex_delete
# OGG Theora (video)
from mutagen.oggtheora import OggTheora, OggTheoraInfo
from mutagen.oggtheora import Open as OggTheoraOpen, delete as oggtheora_delete
# Vorbis Comments (shared by all OGG formats)
from mutagen._vorbis import VCommentDictclass OggPage:
"""Individual OGG container page.
OGG files are composed of pages containing packet data.
Each page has headers with sequence numbers, checksums, and flags.
Attributes:
version: OGG version (always 0)
type: Page type flags
granule_pos: Granule position for timing
serial: Logical bitstream serial number
sequence: Page sequence number
crc: CRC32 checksum
data: Page payload data
"""
class OggFileType:
"""Base class for OGG-based audio formats.
All OGG formats inherit from this class and use Vorbis Comments
for metadata storage.
Attributes:
tags: VCommentDict (Vorbis Comments) container
info: Format-specific stream information
"""
def add_tags(self) -> None:
"""Add empty Vorbis Comments if none exist."""
def save(self) -> None:
"""Save Vorbis Comments back to OGG file."""
def delete(self) -> None:
"""Remove all Vorbis Comments from file."""
# All OGG formats share Vorbis Comments structure
class VCommentDict:
"""Vorbis Comments dictionary container.
Case-insensitive field names supporting multiple values per field.
Standard fields include TITLE, ARTIST, ALBUM, DATE, etc.
"""
# Standard field names (case-insensitive)
STANDARD_FIELDS = [
"TITLE", "VERSION", "ALBUM", "TRACKNUMBER", "ARTIST", "PERFORMER",
"COPYRIGHT", "LICENSE", "ORGANIZATION", "DESCRIPTION", "GENRE",
"DATE", "LOCATION", "CONTACT", "ISRC", "DISCNUMBER", "ALBUMARTIST",
"COMPOSER", "LYRICIST", "CONDUCTOR", "REMIXER", "PRODUCER", "ENGINEER"
]class OggVorbis(OggFileType):
"""OGG Vorbis audio file.
Lossy audio compression with high quality and efficient encoding.
Uses Vorbis Comments for metadata.
Attributes:
info: OggVorbisInfo with stream details
tags: VCommentDict (Vorbis Comments) container
filename: Path to OGG Vorbis file
"""
def __init__(self, filename: str) -> None:
"""Load OGG Vorbis file and parse metadata.
Args:
filename: Path to .ogg file
Raises:
MutagenError: If file is not valid OGG Vorbis or corrupted
"""
class OggVorbisInfo:
"""OGG Vorbis stream information.
Attributes:
length: Duration in seconds (float)
bitrate: Average bitrate in bits per second (int)
sample_rate: Sample rate in Hz (int)
channels: Number of audio channels (int)
bitrate_nominal: Nominal bitrate from headers
bitrate_minimum: Minimum bitrate (VBR)
bitrate_maximum: Maximum bitrate (VBR)
version: Vorbis encoder version
vendor: Encoder identification string
"""
# Function aliases
Open = OggVorbis
def delete(filename: str) -> None:
"""Remove Vorbis Comments from OGG Vorbis file.
Args:
filename: Path to OGG Vorbis file
"""
# Usage examples
from mutagen.oggvorbis import OggVorbis
# Load OGG Vorbis file
ogg_file = OggVorbis("song.ogg")
# Access stream info
info = ogg_file.info
print(f"Sample rate: {info.sample_rate} Hz")
print(f"Channels: {info.channels}")
print(f"Bitrate: {info.bitrate} bps")
print(f"Encoder: {info.vendor}")
# Access Vorbis Comments
print(ogg_file["TITLE"]) # Title
print(ogg_file["ARTIST"]) # Artist
print(ogg_file["ALBUM"]) # Album
# Modify tags
ogg_file["TITLE"] = ["New Title"]
ogg_file["ARTIST"] = ["New Artist"]
ogg_file.save()
# Multi-value fields
ogg_file["GENRE"] = ["Rock", "Alternative"]
ogg_file["ARTIST"] = ["Primary Artist", "Featured Artist"]
ogg_file.save()class OggFLAC(OggFileType):
"""OGG-wrapped FLAC audio file.
FLAC lossless compression in OGG container instead of native FLAC.
Uses Vorbis Comments for metadata (not FLAC metadata blocks).
Attributes:
info: OggFLACInfo with stream details
tags: VCommentDict (Vorbis Comments) container
filename: Path to OGG FLAC file
"""
class OggFLACInfo:
"""OGG FLAC stream information.
Attributes:
length: Duration in seconds (float)
bitrate: Average bitrate in bits per second (int)
sample_rate: Sample rate in Hz (int)
channels: Number of audio channels (int)
bits_per_sample: Bit depth (typically 16 or 24)
total_samples: Total number of audio samples
"""
# Function aliases
Open = OggFLAC
def delete(filename: str) -> None:
"""Remove Vorbis Comments from OGG FLAC file."""
# Usage examples
from mutagen.oggflac import OggFLAC
# Load OGG FLAC file
oggflac_file = OggFLAC("song.oga")
# Stream info (similar to regular FLAC)
info = oggflac_file.info
print(f"Sample rate: {info.sample_rate} Hz")
print(f"Bit depth: {info.bits_per_sample} bits")
print(f"Total samples: {info.total_samples}")
# Vorbis Comments (not FLAC metadata blocks)
oggflac_file["TITLE"] = ["Song Title"]
oggflac_file["ARTIST"] = ["Artist Name"]
oggflac_file.save()class OggOpus(OggFileType):
"""OGG Opus audio file.
Modern low-latency audio codec optimized for speech and music.
Excellent quality at low bitrates with Vorbis Comments metadata.
Attributes:
info: OggOpusInfo with stream details
tags: VCommentDict (Vorbis Comments) container
filename: Path to OGG Opus file
"""
class OggOpusInfo:
"""OGG Opus stream information.
Attributes:
length: Duration in seconds (float)
bitrate: Bitrate in bits per second (int)
sample_rate: Original sample rate before encoding (int)
channels: Number of audio channels (int)
version: Opus version
gain: Output gain adjustment in dB
pre_skip: Pre-skip samples for padding
vendor: Encoder identification string
"""
# Function aliases
Open = OggOpus
def delete(filename: str) -> None:
"""Remove Vorbis Comments from OGG Opus file."""
# Usage examples
from mutagen.oggopus import OggOpus
# Load OGG Opus file
opus_file = OggOpus("song.opus")
# Opus-specific info
info = opus_file.info
print(f"Original sample rate: {info.sample_rate} Hz")
print(f"Output gain: {info.gain} dB")
print(f"Pre-skip: {info.pre_skip} samples")
print(f"Encoder: {info.vendor}")
# Standard Vorbis Comments
opus_file["TITLE"] = ["Song Title"]
opus_file["ARTIST"] = ["Artist Name"]
opus_file.save()class OggSpeex(OggFileType):
"""OGG Speex audio file.
Speech-optimized lossy compression codec designed for voice.
Uses Vorbis Comments for metadata.
Attributes:
info: OggSpeexInfo with stream details
tags: VCommentDict (Vorbis Comments) container
filename: Path to OGG Speex file
"""
class OggSpeexInfo:
"""OGG Speex stream information.
Attributes:
length: Duration in seconds (float)
bitrate: Bitrate in bits per second (int)
sample_rate: Sample rate in Hz (int)
channels: Number of audio channels (int)
mode: Speex encoding mode
vbr: Variable bitrate flag
version: Speex version
vendor: Encoder identification string
"""
# Function aliases
Open = OggSpeex
def delete(filename: str) -> None:
"""Remove Vorbis Comments from OGG Speex file."""
# Usage examples
from mutagen.oggspeex import OggSpeex
# Load OGG Speex file
speex_file = OggSpeex("speech.spx")
# Speex-specific info
info = speex_file.info
print(f"Encoding mode: {info.mode}")
print(f"Variable bitrate: {info.vbr}")
print(f"Speex version: {info.version}")
# Vorbis Comments
speex_file["TITLE"] = ["Speech Recording"]
speex_file["ARTIST"] = ["Speaker Name"]
speex_file.save()class OggTheora(OggFileType):
"""OGG Theora video file.
Open video codec in OGG container. Supports Vorbis Comments
for metadata even though it's primarily a video format.
Attributes:
info: OggTheoraInfo with stream details
tags: VCommentDict (Vorbis Comments) container
filename: Path to OGG Theora file
"""
class OggTheoraInfo:
"""OGG Theora stream information.
Attributes:
length: Duration in seconds (float)
bitrate: Video bitrate in bits per second (int)
fps: Frames per second (float)
width: Video width in pixels (int)
height: Video height in pixels (int)
version: Theora version tuple
vendor: Encoder identification string
"""
# Function aliases
Open = OggTheora
def delete(filename: str) -> None:
"""Remove Vorbis Comments from OGG Theora file."""
# Usage examples
from mutagen.oggtheora import OggTheora
# Load OGG Theora file
theora_file = OggTheora("video.ogv")
# Video-specific info
info = theora_file.info
print(f"Resolution: {info.width}x{info.height}")
print(f"Frame rate: {info.fps} fps")
print(f"Encoder: {info.vendor}")
# Metadata for video
theora_file["TITLE"] = ["Video Title"]
theora_file["DESCRIPTION"] = ["Video description"]
theora_file.save()All OGG formats use Vorbis Comments for metadata:
# Standard Vorbis Comment fields (case-insensitive)
VORBIS_FIELDS = {
# Basic metadata
"TITLE": "Track title",
"VERSION": "Version of track (e.g. remix info)",
"ALBUM": "Album name",
"TRACKNUMBER": "Track number",
"ARTIST": "Artist name",
"PERFORMER": "Performer name",
"ALBUMARTIST": "Album artist",
# Additional credits
"COMPOSER": "Composer name",
"LYRICIST": "Lyricist name",
"CONDUCTOR": "Conductor name",
"REMIXER": "Remixer name",
"PRODUCER": "Producer name",
"ENGINEER": "Engineer name",
# Classification
"GENRE": "Genre classification",
"DATE": "Date of recording/release",
"DISCNUMBER": "Disc number in set",
# Technical/legal
"ORGANIZATION": "Organization/label",
"COPYRIGHT": "Copyright information",
"LICENSE": "License information",
"ISRC": "International Standard Recording Code",
"LOCATION": "Recording location",
"CONTACT": "Contact information",
# Content
"DESCRIPTION": "Description/comment",
"LYRICS": "Song lyrics",
}
# Usage examples for any OGG format
ogg_file = OggVorbis("song.ogg") # or OggFLAC, OggOpus, etc.
# Basic tags
ogg_file["TITLE"] = ["Song Title"]
ogg_file["ARTIST"] = ["Artist Name"]
ogg_file["ALBUM"] = ["Album Name"]
ogg_file["DATE"] = ["2023"]
ogg_file["TRACKNUMBER"] = ["1"]
ogg_file["DISCNUMBER"] = ["1"]
# Multiple values
ogg_file["GENRE"] = ["Rock", "Alternative"]
ogg_file["ARTIST"] = ["Primary Artist", "Featured Artist"]
# Extended metadata
ogg_file["ALBUMARTIST"] = ["Album Artist"]
ogg_file["COMPOSER"] = ["Composer Name"]
ogg_file["PRODUCER"] = ["Producer Name"]
ogg_file["ORGANIZATION"] = ["Record Label"]
ogg_file["COPYRIGHT"] = ["2023 Copyright Holder"]
# Custom fields (any name allowed)
ogg_file["CUSTOM_FIELD"] = ["Custom Value"]
ogg_file["MOOD"] = ["Happy"]
ogg_file["TEMPO"] = ["Fast"]
# Case insensitive access
ogg_file["title"] = ["Same as TITLE"]
ogg_file["Title"] = ["Same as TITLE"]
ogg_file.save()
# Reading tags
for key, values in ogg_file.items():
print(f"{key}: {', '.join(values)}")def tag_ogg_file(filename, metadata):
"""Tag any OGG format file with standard metadata."""
import mutagen
ogg_file = mutagen.File(filename)
if not ogg_file or not hasattr(ogg_file, 'tags'):
return False
# All OGG formats use Vorbis Comments
if ogg_file.tags is None:
ogg_file.add_tags()
# Standard fields
field_mapping = {
'title': 'TITLE',
'artist': 'ARTIST',
'album': 'ALBUM',
'date': 'DATE',
'track': 'TRACKNUMBER',
'disc': 'DISCNUMBER',
'genre': 'GENRE',
'albumartist': 'ALBUMARTIST',
'composer': 'COMPOSER'
}
for source_key, vorbis_key in field_mapping.items():
if source_key in metadata:
value = metadata[source_key]
if isinstance(value, list):
ogg_file[vorbis_key] = value
else:
ogg_file[vorbis_key] = [str(value)]
ogg_file.save()
return True
# Usage with different OGG formats
metadata = {
'title': 'Song Title',
'artist': 'Artist Name',
'album': 'Album Name',
'date': '2023',
'track': 1,
'genre': ['Rock', 'Alternative']
}
tag_ogg_file("song.ogg", metadata) # OGG Vorbis
tag_ogg_file("song.oga", metadata) # OGG FLAC
tag_ogg_file("song.opus", metadata) # OGG Opus
tag_ogg_file("speech.spx", metadata) # OGG Speexdef identify_ogg_format(filename):
"""Identify specific OGG format and codec."""
import mutagen
ogg_file = mutagen.File(filename)
if not ogg_file:
return "Unknown"
format_name = ogg_file.__class__.__name__
format_info = {
'OggVorbis': 'OGG Vorbis (Lossy)',
'OggFLAC': 'OGG FLAC (Lossless)',
'OggOpus': 'OGG Opus (Low-latency)',
'OggSpeex': 'OGG Speex (Speech)',
'OggTheora': 'OGG Theora (Video)'
}
format_desc = format_info.get(format_name, format_name)
# Additional details
info = ogg_file.info
details = {
'format': format_desc,
'sample_rate': getattr(info, 'sample_rate', 'N/A'),
'channels': getattr(info, 'channels', 'N/A'),
'bitrate': getattr(info, 'bitrate', 'N/A'),
'duration': getattr(info, 'length', 0)
}
if hasattr(info, 'vendor'):
details['encoder'] = info.vendor
return details
# Usage
details = identify_ogg_format("audio.ogg")
print(f"Format: {details['format']}")
print(f"Sample rate: {details['sample_rate']} Hz")
print(f"Bitrate: {details['bitrate']} bps")import os
import mutagen
def process_ogg_directory(directory):
"""Process all OGG files in directory."""
ogg_extensions = ['.ogg', '.oga', '.opus', '.spx', '.ogv']
for filename in os.listdir(directory):
if any(filename.lower().endswith(ext) for ext in ogg_extensions):
filepath = os.path.join(directory, filename)
try:
ogg_file = mutagen.File(filepath)
if ogg_file and hasattr(ogg_file, 'tags'):
# Print current metadata
print(f"\n{filename}:")
print(f" Format: {ogg_file.__class__.__name__}")
print(f" Duration: {ogg_file.info.length:.2f}s")
if ogg_file.tags:
for key, values in ogg_file.tags.items():
print(f" {key}: {', '.join(values)}")
else:
print(" No metadata found")
except Exception as e:
print(f"Error processing {filename}: {e}")
# Usage
process_ogg_directory("/path/to/ogg/files")| Format | Codec | Quality | Use Case | Container |
|---|---|---|---|---|
| OGG Vorbis | Vorbis | High quality lossy | General music | OGG |
| OGG FLAC | FLAC | Lossless | Archival quality | OGG |
| OGG Opus | Opus | Excellent at low bitrates | Streaming, VoIP | OGG |
| OGG Speex | Speex | Speech optimized | Voice recordings | OGG |
| OGG Theora | Theora | Video codec | Video files | OGG |
All formats share:
Install with Tessl CLI
npx tessl i tessl/pypi-mutagen