Automatically detect and probe media formats from streams and files
Symphonia can automatically detect the format of audio files by examining the stream content, or you can provide hints to optimize the detection process.
The simplest way to detect formats is to use the default probe.
1
Create a media source
use std::fs::File;use symphonia::core::io::MediaSourceStream;let file = File::open("audio.mp3")?;let mss = MediaSourceStream::new(Box::new(file), Default::default());
2
Get the default probe
use symphonia::core::probe::Hint;use symphonia::core::formats::FormatOptions;use symphonia::core::meta::MetadataOptions;// Get probe with all enabled formats registeredlet probe = symphonia::default::get_probe();let hint = Hint::new();let fmt_opts = FormatOptions::default();let meta_opts = MetadataOptions::default();// Probe will auto-detect the formatlet probed = probe.format(&hint, mss, &fmt_opts, &meta_opts)?;
3
Use the format reader
let mut format = probed.format;// The correct format reader is now instantiatedprintln!("Detected format tracks: {}", format.tracks().len());// Use format reader normallylet packet = format.next_packet()?;
use symphonia::core::probe::Hint;let mut hint = Hint::new();// Provide MIME type (e.g., from HTTP Content-Type header)hint.mime_type("audio/mpeg");let probed = symphonia::default::get_probe() .format(&hint, mss, &fmt_opts, &meta_opts)?;
let mut hint = Hint::new();hint.with_extension("mp3");hint.mime_type("audio/mpeg");// Both hints will be usedlet probed = probe.format(&hint, mss, &fmt_opts, &meta_opts)?;
Hints are optional and won’t cause problems if they’re incorrect. They simply help optimize the detection process.
Some formats have similar markers. Provide hints to disambiguate:
// File could be MP3 or AAC in MP4let mut hint = Hint::new();hint.with_extension("m4a"); // Favor MP4 containerlet probed = probe.format(&hint, mss, &fmt_opts, &meta_opts)?;
Large Metadata Blocks
If metadata is very large, the probe might not reach the format marker:
// This is a Symphonia limitation// Consider stripping metadata if detection fails
use symphonia::core::errors::Error;use symphonia::core::probe::Hint;fn open_audio(path: &Path) -> Result<Box<dyn FormatReader>, Error> { let file = File::open(path)?; let mss = MediaSourceStream::new(Box::new(file), Default::default()); // Try with extension hint let mut hint = Hint::new(); if let Some(ext) = path.extension().and_then(|e| e.to_str()) { hint.with_extension(ext); } let probe = symphonia::default::get_probe(); let fmt_opts = FormatOptions::default(); let meta_opts = MetadataOptions::default(); match probe.format(&hint, mss, &fmt_opts, &meta_opts) { Ok(probed) => Ok(probed.format), Err(Error::Unsupported(_)) => { // Retry without hint let file = File::open(path)?; let mss = MediaSourceStream::new(Box::new(file), Default::default()); let probed = probe.format(&Hint::new(), mss, &fmt_opts, &meta_opts)?; Ok(probed.format) } Err(e) => Err(e), }}
use symphonia::core::probe::{Probe, Descriptor, Instantiate};use symphonia::core::formats::{FormatReader, FormatOptions};use symphonia::core::io::MediaSourceStream;// Create a custom probelet mut probe = Probe::default();// Register all default formatssymphonia::default::register_enabled_formats(&mut probe);// Register your custom format// (You need to implement QueryDescriptor for your format)use my_format::MyFormatReader;probe.register_all::<MyFormatReader>();// Use custom probelet probed = probe.format(&hint, mss, &fmt_opts, &meta_opts)?;
use std::path::Path;use std::fs::File;use symphonia::core::io::MediaSourceStream;use symphonia::core::probe::Hint;use symphonia::core::formats::FormatOptions;use symphonia::core::meta::MetadataOptions;fn main() -> Result<(), Box<dyn std::error::Error>> { let path = Path::new("audio.mp3"); let file = File::open(path)?; let mss = MediaSourceStream::new(Box::new(file), Default::default()); // Create hint from file extension let mut hint = Hint::new(); if let Some(ext) = path.extension() { if let Some(ext_str) = ext.to_str() { hint.with_extension(ext_str); println!("Hint: extension = {}", ext_str); } } // Probe the format let probe = symphonia::default::get_probe(); let fmt_opts = FormatOptions::default(); let meta_opts = MetadataOptions::default(); println!("Probing format..."); let probed = probe.format(&hint, mss, &fmt_opts, &meta_opts)?; // Display detected format info let format = probed.format; let default_track = format.default_track() .expect("no tracks found"); println!("Format detected!"); println!("Tracks: {}", format.tracks().len()); println!("Default track ID: {}", default_track.id); println!("Codec: {:?}", default_track.codec_params.codec); if let Some(sample_rate) = default_track.codec_params.sample_rate { println!("Sample rate: {} Hz", sample_rate); } if let Some(channels) = default_track.codec_params.channels { println!("Channels: {}", channels.count()); } Ok(())}