Skip to main content

Crate audex

Crate audex 

Source
Expand description

Audex strives to deliver a comprehensive audio metadata tagging solution.

§Basic Usage

Load metadata from a file:

use audex::File;

let metadata = File::load("audio.mp3")?;

metadata acts like a dictionary of tags in the file. Tags are generally a list of string-like values, but may have additional methods available depending on tag or format. They may also be entirely different objects for certain keys, again depending on format.

§Async Operations

All format types support async operations when the async feature is enabled. Async methods use the _async suffix:

// Note: This example requires the `async` feature and a tokio runtime.
// Enable with: audex = { version = "*", features = ["async"] }
use audex::flac::FLAC;
use audex::FileType;

// Load file asynchronously
let mut flac = FLAC::load_async("audio.flac").await?;

// Modify tags
flac.set("artist", vec!["Artist Name".to_string()])?;

// Save asynchronously
flac.save_async().await?;

§Loading from In-Memory Buffers

You can load files from in-memory buffers or any Read + Seek source:

use audex::File;
use std::io::Cursor;

let audio_data = vec![/* audio file bytes */];
let cursor = Cursor::new(audio_data);
let metadata = File::load_from_reader(cursor, None)?;

§Easy Wrappers

Use EasyID3 for simplified MP3 tag access. Note that EasyID3’s set() method takes &[String] (a slice), while the FileType trait’s set() takes Vec<String>. The easy wrappers have their own dedicated API.

use audex::easyid3::EasyID3;
use audex::FileType;

let mut tags = EasyID3::load("song.mp3")?;
// EasyID3::set() takes &[String], not Vec<String>
tags.set("artist", &["Artist Name".to_string()])?;
tags.set("album", &["Album Title".to_string()])?;
tags.save()?;

Use EasyMP4 for simplified MP4/M4A tag access. Note that EasyMP4’s set() method takes Vec<String>, while EasyID3’s set() takes &[String].

use audex::easymp4::EasyMP4;
use audex::FileType;

let mut tags = EasyMP4::load("song.m4a")?;
tags.set("title", vec!["Track Title".to_string()])?;
tags.set("artist", vec!["Artist Name".to_string()])?;
tags.save()?;

EasyMP4 also supports custom key registration:

use audex::easymp4::EasyMP4;
use audex::FileType;

let mut tags = EasyMP4::load("song.m4a")?;
tags.register_text_key("my_tag", "----:TXXX:My Tag")?;
tags.set("my_tag", vec!["custom_value".to_string()])?;
tags.save()?;

§Dynamic Key Registration

Register custom keys for EasyID3. Two registration methods are available:

  • register_txxx_key(key, description) — maps a human-readable key to a TXXX (user-defined text) frame with the given description
  • register_text_key(key, frame_id) — maps a human-readable key to a standard ID3v2 text frame (e.g., "TDRC", "TCOM")
use audex::easyid3::EasyID3;
use audex::FileType;

let mut tags = EasyID3::load("song.mp3")?;

// Map "barcode" to a TXXX frame with description "BARCODE"
tags.register_txxx_key("barcode", "BARCODE")?;
tags.set("barcode", &["1234567890123".to_string()])?;

// Map "composer" to the standard TCOM frame
tags.register_text_key("composer", "TCOM")?;
tags.set("composer", &["J.S. Bach".to_string()])?;

tags.save()?;

§M4A/MP4 Compatibility

The m4a module provides compatibility aliases:

use audex::m4a::M4A;
use audex::FileType;

let audio = M4A::load("song.m4a")?;

§Tag Deletion

Delete ID3 tags from MP3 files:

use audex::mp3;

// Delete all ID3 tags
mp3::clear("song.mp3")?;

// Delete only ID3v2 tags
mp3::clear_with_options("song.mp3", false, true)?;

§Advanced Examples

§Custom I/O with In-Memory Buffers

Load and manipulate audio metadata entirely in memory:

use audex::File;
use std::io::Cursor;

// Read file into memory
let audio_data = std::fs::read("music.flac")?;

// Create a cursor for seeking within the buffer
let cursor = Cursor::new(audio_data.clone());

// Load metadata from the in-memory buffer
let mut metadata = File::load_from_reader(cursor, Some("music.flac".into()))?;

// Modify tags
metadata.set("artist", vec!["New Artist".to_string()])?;
metadata.set("album", vec!["New Album".to_string()])?;

// Save back to an in-memory buffer via save_to_writer
let mut out_cursor = std::io::Cursor::new(audio_data);
metadata.save_to_writer(&mut out_cursor)?;

§Async File Processing with Tokio

Process multiple files concurrently using async operations:

// Note: This example requires the `async` feature and tokio runtime.
// Enable with: audex = { version = "*", features = ["async"] }
use audex::File;
use audex::FileType;
use tokio::task;

// Process multiple files concurrently
let files = vec!["song1.mp3", "song2.flac", "song3.m4a"];

let mut tasks = Vec::new();
for file_path in files {
    tasks.push(task::spawn(async move {
        // Load file asynchronously
        let mut file = File::load_async(file_path).await?;

        // Update metadata
        file.set("album", vec!["Compilation".to_string()])?;

        // Save changes asynchronously
        file.save_async().await?;

        Ok::<_, audex::AudexError>(())
    }));
}

// Wait for all tasks to complete
for task in tasks {
    task.await??;
}

§Format-Specific Operations

Work directly with specific format types for advanced features:

use audex::flac::FLAC;
use audex::{FileType, StreamInfo};

// Load as a specific format for format-specific features
let mut flac = FLAC::load("audio.flac")?;

// Access stream information via the StreamInfo trait
let info = flac.info();
println!("Sample rate: {} Hz", info.sample_rate().unwrap_or(0));
println!("Channels: {}", info.channels().unwrap_or(0));
println!("Bits per sample: {}", info.bits_per_sample().unwrap_or(0));

// Modify tags using the dictionary interface
flac.set("comment", vec!["Remastered edition".to_string()])?;

// Save changes back to file
flac.save()?;

§Batch Tag Updates

Update multiple tags at once using the update method:

use audex::File;

let mut file = File::load("track.mp3")?;

// Prepare batch updates
let updates = vec![
    ("artist".to_string(), vec!["Artist Name".to_string()]),
    ("album".to_string(), vec!["Album Title".to_string()]),
    ("title".to_string(), vec!["Track Title".to_string()]),
    ("date".to_string(), vec!["2024".to_string()]),
    ("genre".to_string(), vec!["Electronic".to_string()]),
];

// Apply all updates at once
file.update(updates)?;
file.save()?;

§Read-Only Formats

Some formats only provide stream information and do not support tag reading or writing:

  • AAC (aac): ADTS/ADIF stream info only — read-only, no tagging (use M4A container for tags)
  • AC-3/E-AC-3 (ac3): Stream info only — read-only, no tagging (use a container format for tags)
  • SMF/MIDI (smf): Duration only (MIDI has no tag concept)

Calling set() or remove() on these formats is a no-op or returns an error.

§APEv2 and ASF Tag Access

Formats using APEv2 tags (Monkey’s Audio, Musepack, WavPack, TAK, OptimFROG) and ASF/WMA files store tag values internally as APEValue and ASFAttribute types respectively, not as plain strings. The get(), set(), remove(), and keys() methods on the file types handle conversion automatically, so the unified interface works across all formats:

use audex::wavpack::WavPack;
use audex::FileType;

let wv = WavPack::load("song.wv")?;
// get() converts APEValue to Vec<String> automatically
if let Some(values) = wv.get("Title") {
    println!("Title: {}", values[0]);
}

For direct access to the underlying typed values (e.g., binary data in APEv2 or typed attributes in ASF), use the native format-specific API:

use audex::wavpack::WavPack;
use audex::FileType;

let wv = WavPack::load("song.wv")?;
if let Some(ref tags) = wv.tags {
    // Native APEv2 get() returns Option<&APEValue>
    if let Some(value) = tags.get("Title") {
        println!("Title: {}", value.as_string().unwrap_or_default());
    }
}

Note: The low-level Tags trait impl on APEv2Tags and ASFTags returns None from get() because that trait returns &[String] which cannot reference the non-string internal storage. Always use the file-level methods (e.g., WavPack::get(), ASF::get()) for the converting interface.

§Troubleshooting

§Unsupported Format Errors

If you encounter UnsupportedFormat errors, ensure:

  • The file extension matches the actual file format
  • The file is not corrupted or truncated
  • The format is supported by this library (check the module list)

§Tag Encoding Issues

Text tags are expected to be UTF-8 encoded. If you encounter encoding errors:

  • Verify the source text is valid UTF-8
  • For ID3v2 tags, encoding is handled automatically
  • For legacy formats (ID3v1), non-ASCII characters may be limited

§File Corruption Warnings

Always work on copies of important files:

// Create a backup before modifying
std::fs::copy("original.mp3", "original.mp3.backup")?;

// Now safe to modify
// ... your code here ...

§Async Feature Not Available

If async methods are not available, enable the async feature:

[dependencies]
audex = { version = "*", features = ["async"] }

Re-exports§

pub use tags::BasicTags;
pub use tags::Metadata;
pub use tags::MetadataFields;
pub use tags::PaddingInfo;
pub use tags::Tags;
pub use tagmap::ConversionOptions;
pub use tagmap::ConversionReport;
pub use tagmap::SkipReason;
pub use tagmap::StandardField;
pub use tagmap::TagMap;
pub use tagmap::convert_tags;
pub use tagmap::convert_tags_with_options;
pub use diff::DiffOptions;
pub use diff::FieldChange;
pub use diff::FieldEntry;
pub use diff::StreamInfoDiff;
pub use diff::TagDiff;
pub use diff::diff_normalized;
pub use diff::diff_normalized_with_options;
pub use snapshot::StreamInfoSnapshot;
pub use snapshot::TagSnapshot;
pub use mp4::clear_async as mp4_clear_async;
pub use ogg::seek_end_async;
pub use iff::IffChunkAsync;
pub use iff::IffFileAsync;
pub use iff::RiffFileAsync;
pub use iff::delete_chunk_async;
pub use iff::insert_iff_chunk_async;
pub use iff::insert_riff_chunk_async;
pub use iff::resize_iff_chunk_async;
pub use iff::resize_riff_chunk_async;
pub use iff::update_iff_file_size_async;
pub use iff::update_riff_file_size_async;
pub use aiff::clear_async as aiff_clear_async;
pub use aiff::open_async as aiff_open_async;
pub use wave::clear_async as wave_clear_async;
pub use wave::open_async as wave_open_async;
pub use util::delete_bytes_async;
pub use util::insert_bytes_async;
pub use util::loadfile_read_async;
pub use util::loadfile_write_async;
pub use util::read_full_async;
pub use util::resize_bytes_async;
pub use util::DEFAULT_BUFFER_SIZE;
pub use limits::ParseLimits;

Modules§

aac
AAC (Advanced Audio Coding) stream info — ADTS/ADIF parsing (read-only, no tagging)
ac3
AC-3/E-AC-3 (Dolby Digital) stream info (read-only, no tagging) Support for AC-3 (Dolby Digital) and E-AC-3 audio files.
aiff
AIFF (Audio Interchange File Format) support with ID3v2 tagging
apev2
APEv2 tag format used by Monkey’s Audio, WavPack, Musepack, and others APEv2 tag support for audio files
asf
ASF/WMA (Advanced Systems Format) metadata support Advanced Systems Format (ASF) container support
constants
Genre constants, ID3v1 genre table, and genre string parsing utilities Constants used across the library, primarily ID3v1 genres
diff
Tag diffing — structured comparison of metadata between two files or states
dsdiff
DSDIFF (DSD Interchange File Format) support with ID3v2 tagging DSDIFF (Direct Stream Digital Interchange File Format) format support
dsf
DSF (DSD Stream File) support with ID3v2 tagging
easyid3
Simplified ID3v2 interface with human-readable key names for MP3 files Simplified ID3v2 tag interface with key-value access
easymp4
Simplified MP4/M4A tag interface with human-readable key names Simplified MP4/M4A tag interface with key-value access
flac
FLAC (Free Lossless Audio Codec) support with Vorbis Comment tagging
id3
ID3v1/ID3v2 tag reading and writing (used by MP3, AIFF, WAV, and others) ID3v2 tag support for MP3 and other audio files
iff
IFF (Interchange File Format) container primitives for AIFF and similar formats IFF (Interchange File Format) container support
limits
Global parse limits — configurable ceilings on tag and image allocations Parse limits for all audio format parsers.
m4a
Compatibility shim: re-exports mp4::MP4 as M4A, easymp4::EasyMP4 as EasyM4A, and easymp4::EasyMP4Tags as EasyM4ATags M4A (MPEG-4 Audio) format compatibility module.
monkeysaudio
Monkey’s Audio (APE) lossless format with APEv2 tagging Support for Monkey’s Audio (APE) files.
mp3
MP3 (MPEG Layer III) format support with ID3v1, ID3v2, and APEv2 tagging. Includes mp3::EasyMP3 for simplified tag access via the easyid3::EasyID3 interface.
mp4
MP4/M4A (MPEG-4 Part 14) format support with iTunes-style atom tags
musepack
Musepack (MPC) format with APEv2 tagging Support for Musepack audio files.
ogg
Ogg container format primitives (pages, packets, streams) Ogg container format support
oggflac
Ogg FLAC (FLAC in Ogg container) with Vorbis Comment tagging Support for Ogg FLAC audio files.
oggopus
Ogg Opus audio with Vorbis Comment tagging
oggspeex
Ogg Speex audio with Vorbis Comment tagging Support for Ogg Speex audio files.
oggtheora
Ogg Theora video with Vorbis Comment tagging Support for Ogg Theora video files.
oggvorbis
Ogg Vorbis audio with Vorbis Comment tagging
optimfrog
OptimFROG lossless format with APEv2 tagging Support for OptimFROG audio files.
replaygain
ReplayGain metadata reading, writing, and conversion utilities ReplayGain utility module for loudness normalization metadata.
riff
RIFF (Resource Interchange File Format) container primitives for WAV and similar formats Resource Interchange File Format (RIFF) container support
serde_helpers
Custom serde serialization helpers for audio metadata types.
smf
SMF (Standard MIDI File) — duration-only parsing (read-only, no tagging) Standard MIDI File (SMF) format support
snapshot
Unified serializable view of an audio file’s metadata.
tagmap
Tag conversion and cross-format metadata transfer Tag conversion and cross-format metadata transfer
tags
Core tagging traits: Tags, Metadata, MetadataFields, and BasicTags Core tagging interfaces and metadata handling
tak
TAK (Tom’s Lossless Audio Kompressor) with APEv2 tagging Support for TAK (Tom’s lossless Audio Kompressor) files.
trueaudio
TrueAudio (TTA) lossless format with ID3v1/v2 and APEv2 tagging Support for TrueAudio (TTA) files.
util
Low-level utilities: binary readers, byte manipulation, file I/O helpers Internal utility functions and data structures for audio file processing.
vorbis
Vorbis Comment tagging support shared by FLAC, Ogg Vorbis, Ogg Opus, and related formats
wave
WAVE (WAV) format support with ID3v2 tagging WAV/WAVE format support
wavpack
WavPack lossless/lossy format with APEv2 tagging Support for WavPack audio files.

Macros§

flags
Macro to create a flags enum that supports bitwise operations. This provides flag enum functionality.
int_enum
Macro to create an integer-backed enum with From, Debug, and Display support.

Structs§

DynamicFileType
Polymorphic wrapper for any audio file format
DynamicStreamInfo
Dynamic stream information wrapper for runtime polymorphism
File
Export FileStruct as File for the struct API Primary entry point for loading audio files with automatic format detection.
SerializableError
Serializable representation of an AudexError.

Enums§

AudexError
Primary error type for audio metadata operations

Constants§

VERSION_STRING
Version string - automatically derived from Cargo.toml

Traits§

FileType
Base trait for all file format implementations
ReadSeek
Combined trait for types that implement both Read and Seek.
ReadWriteSeek
Combined trait for types that implement Read, Write, and Seek.
StreamInfo
Stream information trait for audio properties

Functions§

detect_format
Detect the audio format of a file without fully loading it.
detect_format_async
Auto-detect file format asynchronously.
detect_format_from_bytes
Detect audio format from raw bytes using header-based scoring only.
detect_ogg_format
Detect specific OGG format from header bytes. Requires at least 36 bytes to identify sub-formats like Opus, Vorbis, etc.

Type Aliases§

Result
Convenience result type used throughout the library