symphonia-0.5.2/.cargo_vcs_info.json0000644000000001470000000000100130510ustar { "git": { "sha1": "412f44daab39920beeb81d78b0e4271b263d33e9" }, "path_in_vcs": "symphonia" }symphonia-0.5.2/Cargo.lock0000644000000133140000000000100110240ustar # This file is automatically @generated by Cargo. # It is not intended for manual editing. version = 3 [[package]] name = "arrayvec" version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8da52d66c7071e2e3fa2a1e5c6d088fec47b593032b254f5e980de8ea54454d6" [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "bytemuck" version = "1.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aaa3a8d9a1ca92e282c96a32d6511b695d7d994d1d102ba85d279f9b2756947f" [[package]] name = "cfg-if" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "encoding_rs" version = "0.8.31" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9852635589dc9f9ea1b6fe9f05b50ef208c85c834a562f0c6abb1c475736ec2b" dependencies = [ "cfg-if", ] [[package]] name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "log" version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" dependencies = [ "cfg-if", ] [[package]] name = "symphonia" version = "0.5.2" dependencies = [ "lazy_static", "symphonia-bundle-flac", "symphonia-bundle-mp3", "symphonia-codec-aac", "symphonia-codec-adpcm", "symphonia-codec-alac", "symphonia-codec-pcm", "symphonia-codec-vorbis", "symphonia-core", "symphonia-format-isomp4", "symphonia-format-mkv", "symphonia-format-ogg", "symphonia-format-wav", "symphonia-metadata", ] [[package]] name = "symphonia-bundle-flac" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3dc2deed3204967871ba60f913378f95820cb47a2fe9b2eef5a9eedb417dfdc8" dependencies = [ "log", "symphonia-core", "symphonia-metadata", "symphonia-utils-xiph", ] [[package]] name = "symphonia-bundle-mp3" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55a0846e7a2c9a8081ff799fc83a975170417ad2a143f644a77ec2e3e82a2b73" dependencies = [ "bitflags", "lazy_static", "log", "symphonia-core", "symphonia-metadata", ] [[package]] name = "symphonia-codec-aac" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fcdd4a10695ca0528572360ec020586320357350eb62791693667e7de8c871a" dependencies = [ "lazy_static", "log", "symphonia-core", ] [[package]] name = "symphonia-codec-adpcm" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2a5cfb8d4405e26eb9593157dc45b05e102b8d774b38ed2a95946d6bb9e26e3e" dependencies = [ "log", "symphonia-core", ] [[package]] name = "symphonia-codec-alac" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c49e1b209318bcefa7ff452bd85f1f593210943a7d9786b7d4250e8991a7449c" dependencies = [ "log", "symphonia-core", ] [[package]] name = "symphonia-codec-pcm" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8cb9a9f0b9991cccf3217b74644af412d5d082a4815e5e2943f26e0ecabdf3c9" dependencies = [ "log", "symphonia-core", ] [[package]] name = "symphonia-codec-vorbis" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dfed6f7b6bfa21d7cef1acefc8eae5db80df1608a1aca91871b07cbd28d7b74" dependencies = [ "log", "symphonia-core", "symphonia-utils-xiph", ] [[package]] name = "symphonia-core" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6b9567e2d8a5f866b2f94f5d366d811e0c6826babcff6d37de9e1a6690d38869" dependencies = [ "arrayvec", "bitflags", "bytemuck", "lazy_static", "log", ] [[package]] name = "symphonia-format-isomp4" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1818f6f54b4eaba5ec004a8dbcca637c57e617eb1ff4c9addbd3fc065eba437" dependencies = [ "encoding_rs", "log", "symphonia-core", "symphonia-metadata", "symphonia-utils-xiph", ] [[package]] name = "symphonia-format-mkv" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bd22f2def8c8f078495ad66111648bfc7d5222ee33774f2077cb665588f3119" dependencies = [ "lazy_static", "log", "symphonia-core", "symphonia-metadata", "symphonia-utils-xiph", ] [[package]] name = "symphonia-format-ogg" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "474df6e86b871dcb56913130bada1440245f483057c4a2d8a2981455494c4439" dependencies = [ "log", "symphonia-core", "symphonia-metadata", "symphonia-utils-xiph", ] [[package]] name = "symphonia-format-wav" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06679bd5646b3037300f88891dfc8a6e1cc4e1133206cc17a98e5d7c22f88296" dependencies = [ "log", "symphonia-core", "symphonia-metadata", ] [[package]] name = "symphonia-metadata" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acd35c263223ef6161000be79b124a75de3e065eea563bf3ef169b3e94c7bb2e" dependencies = [ "encoding_rs", "lazy_static", "log", "symphonia-core", ] [[package]] name = "symphonia-utils-xiph" version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ce340a6c33ac06cb42de01220308ec056e8a2a3d5cc664aaf34567392557136b" dependencies = [ "symphonia-core", "symphonia-metadata", ] symphonia-0.5.2/Cargo.toml0000644000000054130000000000100110500ustar # THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies. # # If you are reading this file be aware that the original Cargo.toml # will likely look very different (and much more reasonable). # See Cargo.toml.orig for the original contents. [package] edition = "2018" rust-version = "1.53" name = "symphonia" version = "0.5.2" authors = ["Philip Deljanov "] description = "Pure Rust media container and audio decoding library." homepage = "https://github.com/pdeljanov/Symphonia" readme = "README.md" keywords = [ "audio", "codec", "decoder", "multimedia", "media", ] categories = [ "multimedia", "multimedia::audio", "multimedia::encoding", ] license = "MPL-2.0" repository = "https://github.com/pdeljanov/Symphonia" [package.metadata.docs.rs] all-features = true [dependencies.lazy_static] version = "1.4.0" [dependencies.symphonia-bundle-flac] version = "0.5.2" optional = true [dependencies.symphonia-bundle-mp3] version = "0.5.2" optional = true default-features = false [dependencies.symphonia-codec-aac] version = "0.5.2" optional = true [dependencies.symphonia-codec-adpcm] version = "0.5.2" optional = true [dependencies.symphonia-codec-alac] version = "0.5.2" optional = true [dependencies.symphonia-codec-pcm] version = "0.5.2" optional = true [dependencies.symphonia-codec-vorbis] version = "0.5.2" optional = true [dependencies.symphonia-core] version = "0.5.2" [dependencies.symphonia-format-isomp4] version = "0.5.2" optional = true [dependencies.symphonia-format-mkv] version = "0.5.2" optional = true [dependencies.symphonia-format-ogg] version = "0.5.2" optional = true [dependencies.symphonia-format-wav] version = "0.5.2" optional = true [dependencies.symphonia-metadata] version = "0.5.2" [features] aac = ["symphonia-codec-aac"] adpcm = ["symphonia-codec-adpcm"] alac = ["symphonia-codec-alac"] all = [ "all-codecs", "all-formats", ] all-codecs = [ "aac", "adpcm", "alac", "flac", "mp1", "mp2", "mp3", "pcm", "vorbis", ] all-formats = [ "isomp4", "mkv", "ogg", "wav", ] default = [ "adpcm", "flac", "mkv", "ogg", "pcm", "vorbis", "wav", ] flac = ["symphonia-bundle-flac"] isomp4 = ["symphonia-format-isomp4"] mkv = ["symphonia-format-mkv"] mp1 = ["symphonia-bundle-mp3/mp1"] mp2 = ["symphonia-bundle-mp3/mp2"] mp3 = ["symphonia-bundle-mp3/mp3"] mpa = [ "mp1", "mp2", "mp3", ] ogg = ["symphonia-format-ogg"] pcm = ["symphonia-codec-pcm"] vorbis = ["symphonia-codec-vorbis"] wav = ["symphonia-format-wav"] symphonia-0.5.2/Cargo.toml.orig000064400000000000000000000061641046102023000145350ustar 00000000000000[package] name = "symphonia" version = "0.5.2" description = "Pure Rust media container and audio decoding library." homepage = "https://github.com/pdeljanov/Symphonia" repository = "https://github.com/pdeljanov/Symphonia" authors = ["Philip Deljanov "] license = "MPL-2.0" readme = "README.md" categories = ["multimedia", "multimedia::audio", "multimedia::encoding"] keywords = ["audio", "codec", "decoder", "multimedia", "media"] edition = "2018" rust-version = "1.53" [features] # Only royalty-free open standard codecs and formats are enabled by default. # TODO: Remove all defaults for v0.6.0. Features should be additive. default = ["adpcm", "flac", "mkv", "ogg", "pcm", "vorbis", "wav"] # Enable specific codecs and formats. # TODO: Use "dep:" after MSRV is raised to >= 1.60. aac = ["symphonia-codec-aac"] adpcm = ["symphonia-codec-adpcm"] alac = ["symphonia-codec-alac"] flac = ["symphonia-bundle-flac"] isomp4 = ["symphonia-format-isomp4"] mkv = ["symphonia-format-mkv"] mp1 = ["symphonia-bundle-mp3/mp1"] mp2 = ["symphonia-bundle-mp3/mp2"] mp3 = ["symphonia-bundle-mp3/mp3"] ogg = ["symphonia-format-ogg"] pcm = ["symphonia-codec-pcm"] vorbis = ["symphonia-codec-vorbis"] wav = ["symphonia-format-wav"] # MPEG audio codecs. mpa = ["mp1", "mp2", "mp3"] # Enable all supported codecs. all-codecs = [ "aac", "adpcm", "alac", "flac", "mp1", "mp2", "mp3", "pcm", "vorbis", ] # Enable all supported formats. all-formats = [ "isomp4", "mkv", "ogg", "wav" ] # Enable all supported codecs and formats. all = [ "all-codecs", "all-formats", ] [dependencies] lazy_static = "1.4.0" [dependencies.symphonia-core] version = "0.5.2" path = "../symphonia-core" [dependencies.symphonia-metadata] version = "0.5.2" path = "../symphonia-metadata" [dependencies.symphonia-bundle-flac] version = "0.5.2" path = "../symphonia-bundle-flac" optional = true [dependencies.symphonia-bundle-mp3] version = "0.5.2" path = "../symphonia-bundle-mp3" optional = true # Standalone crate enables all MP1, MP2, and MP3 decoders by default. default-features = false [dependencies.symphonia-codec-aac] version = "0.5.2" path = "../symphonia-codec-aac" optional = true [dependencies.symphonia-codec-adpcm] version = "0.5.2" path = "../symphonia-codec-adpcm" optional = true [dependencies.symphonia-codec-alac] version = "0.5.2" path = "../symphonia-codec-alac" optional = true [dependencies.symphonia-codec-pcm] version = "0.5.2" path = "../symphonia-codec-pcm" optional = true [dependencies.symphonia-codec-vorbis] version = "0.5.2" path = "../symphonia-codec-vorbis" optional = true [dependencies.symphonia-format-wav] version = "0.5.2" path = "../symphonia-format-wav" optional = true [dependencies.symphonia-format-ogg] version = "0.5.2" path = "../symphonia-format-ogg" optional = true [dependencies.symphonia-format-isomp4] version = "0.5.2" path = "../symphonia-format-isomp4" optional = true [dependencies.symphonia-format-mkv] version = "0.5.2" path = "../symphonia-format-mkv" optional = true # Show documentation with all features enabled on docs.rs [package.metadata.docs.rs] all-features = truesymphonia-0.5.2/README.md000064400000000000000000000217771046102023000131340ustar 00000000000000

Symphonia

Crate Info API Docs Rustc Version 1.53.0+

Symphonia is a pure Rust audio decoding and media demuxing library supporting AAC, ADPCM, ALAC, FLAC, MKV, MP1, MP2, MP3, MP4, OGG, Vorbis, WAV, and WebM.

Getting Started · Documentation · Examples · Benchmarks

--- ## Features * Decode support for the most popular audio codecs with support for gapless playback * Demux the most common media container formats * Read most metadata and tagging formats * Automatic format and decoder detection * Basic audio primitives for manipulating audio data efficiently * 100% safe Rust * Minimal dependencies * Fast with no compromises in performance! Additionally, planned features include: * Providing a C API for integration into other languages * Providing a WASM API for web usage ## Current Support Support for individual audio codecs and media formats are provided by separate crates. By default, Symphonia only enables support royalty-free open standard codecs and formats, but others may be enabled using feature flags. > **Tip:** All formats and codecs can be enabled with the `all` feature flag. ### Status The following status classifications are used to determine the state of development for each format or codec. | Status | Meaning | |-----------|--------------------------------------------------------------------------------------------------------------------------| | Good | Many media streams play. Some streams may panic, error, or produce audible glitches. Some features may not be supported. | | Great | Most media streams play. Inaudible glitches may be present. Most common features are supported. | | Excellent | All media streams play. No audible or inaudible glitches. All required features are supported. | A status of *Great* indicates that major development is complete and that the feature is in a state that would be acceptable for most applications to use. A status of *Excellent* is only assigned after the feature passes all compliance tests. If no compliance tests are readily available, then a status of *Excellent* will be assigned if Symphonia's output matches that of a reference implementation, or `ffmpeg`, over a large test corpus. ### Formats (Demuxers) | Format | Status | Gapless* | Feature Flag | Default | Crate | |----------|-----------|----------|--------------|---------|-----------------------------| | ISO/MP4 | Great | No | `isomp4` | No | [`symphonia-format-isomp4`] | | MKV/WebM | Good | No | `mkv` | Yes | [`symphonia-format-mkv`] | | OGG | Great | Yes | `ogg` | Yes | [`symphonia-format-ogg`] | | Wave | Excellent | Yes | `wav` | Yes | [`symphonia-format-wav`] | \* Gapless playback requires support from both the demuxer and decoder. [`symphonia-format-isomp4`]: https://docs.rs/symphonia-format-isomp4 [`symphonia-format-ogg`]: https://docs.rs/symphonia-format-ogg [`symphonia-format-wav`]: https://docs.rs/symphonia-format-wav [`symphonia-format-mkv`]: https://docs.rs/symphonia-format-mkv > **Tip:** All formats can be enabled with the `all-formats` feature flag. ### Codecs (Decoders) | Codec | Status | Gapless | Feature Flag | Default | Crate | |------------------------------|-----------|---------|--------------|---------|----------------------------| | AAC-LC | Great | No | `aac` | No | [`symphonia-codec-aac`] | | ADPCM | Good | Yes | `adpcm` | Yes | [`symphonia-codec-adpcm`] | | ALAC | Great | Yes | `alac` | No | [`symphonia-codec-alac`] | | FLAC | Excellent | Yes | `flac` | Yes | [`symphonia-bundle-flac`] | | MP1 | Great | No | `mp1`, `mpa` | No | [`symphonia-bundle-mp3`] | | MP2 | Great | No | `mp2`, `mpa` | No | [`symphonia-bundle-mp3`] | | MP3 | Excellent | Yes | `mp3`, `mpa` | No | [`symphonia-bundle-mp3`] | | PCM | Excellent | Yes | `pcm` | Yes | [`symphonia-codec-pcm`] | | Vorbis | Excellent | Yes | `vorbis` | Yes | [`symphonia-codec-vorbis`] | A `symphonia-bundle-*` package is a combination of a decoder and a native demuxer. [`symphonia-codec-aac`]: https://docs.rs/symphonia-codec-aac [`symphonia-codec-adpcm`]: https://docs.rs/symphonia-codec-adpcm [`symphonia-codec-alac`]: https://docs.rs/symphonia-codec-alac [`symphonia-bundle-flac`]: https://docs.rs/symphonia-bundle-flac [`symphonia-bundle-mp3`]: https://docs.rs/symphonia-bundle-mp3 [`symphonia-codec-pcm`]: https://docs.rs/symphonia-codec-pcm [`symphonia-codec-vorbis`]: https://docs.rs/symphonia-codec-vorbis > **Tip:** All codecs can be enabled with the `all-codecs` feature flag. Similarly, all MPEG audio codecs can be enabled with the `mpa` feature flag. ### Tags (Readers) All metadata readers are provided by the `symphonia-metadata` crate. | Format | Status | |-----------------------|-----------| | ID3v1 | Great | | ID3v2 | Great | | ISO/MP4 | Great | | RIFF | Great | | Vorbis comment (FLAC) | Perfect | | Vorbis comment (OGG) | Perfect | ## Quality In addition to the safety guarantees afforded by Rust, Symphonia aims to: * Decode media as correctly as the leading free-and-open-source software decoders * Prevent denial-of-service attacks * Be fuzz-tested * Provide a powerful, consistent, and easy to use API ## Performance Symphonia aims to be comparable to, or faster than, popular open-source C-based implementations. Currently, Symphonia's decoders are generally +/-15% the performance of FFMpeg. However, the exact range will depend strongly on the codec, which features of the codec are being leveraged in the encoding, the Rust compiler version, and the CPU architecture being compiled for. See the [benchmarks](https://github.com/pdeljanov/Symphonia/blob/master/BENCHMARKS.md) for more information. ## Examples Basic usage examples may be found [`here`](https://github.com/pdeljanov/Symphonia/tree/master/symphonia/examples). For a more complete application, see [`symphonia-play`](https://github.com/pdeljanov/Symphonia/tree/master/symphonia-play), a simple music player. ## Tools Symphonia provides the following tools for debugging purposes: * [`symphonia-play`](https://github.com/pdeljanov/Symphonia/tree/master/symphonia-play) for probing, decoding, validating, and playing back media streams. * [`symphonia-check`](https://github.com/pdeljanov/Symphonia/tree/master/symphonia-check) for validating Symphonia's decoded output against various decoders. ## Author The primary author is Philip Deljanov. ## Special Thanks * Kostya Shishkov (AAC-LC decoder contribution, see `symphonia-codec-aac`) ## License Symphonia is provided under the MPL v2.0 license. Please refer to the LICENSE file for more details. ## Contributing Symphonia is an open-source project and contributions are very welcome! If you would like to make a large contribution, please raise an issue ahead of time to make sure your efforts fit into the project goals, and that there's no duplication of effort. Please be aware that all contributions must also be licensed under the MPL v2.0 license to be accepted. When submitting a pull request, be sure you have included yourself in the CONTRIBUTORS file! symphonia-0.5.2/examples/README.md000064400000000000000000000006061046102023000147360ustar 00000000000000# Symphonia Examples | Example | Description | |------------------------|----------------------------------------------------------------| | `basic-interleaved.rs` | Decode a file and interleave the decoded samples for playback. | | `getting-started.rs` | The example from GETTING_STARTED.md. | symphonia-0.5.2/examples/basic-interleaved.rs000064400000000000000000000077461046102023000174220ustar 00000000000000use std::env; use std::fs::File; use std::path::Path; use symphonia::core::audio::SampleBuffer; use symphonia::core::codecs::DecoderOptions; use symphonia::core::errors::Error; use symphonia::core::formats::FormatOptions; use symphonia::core::io::MediaSourceStream; use symphonia::core::meta::MetadataOptions; use symphonia::core::probe::Hint; fn main() { // Get command line arguments. let args: Vec = env::args().collect(); // Create a media source. Note that the MediaSource trait is automatically implemented for File, // among other types. let file = Box::new(File::open(Path::new(&args[1])).unwrap()); // Create the media source stream using the boxed media source from above. let mss = MediaSourceStream::new(file, Default::default()); // Create a hint to help the format registry guess what format reader is appropriate. In this // example we'll leave it empty. let hint = Hint::new(); // Use the default options when reading and decoding. let format_opts: FormatOptions = Default::default(); let metadata_opts: MetadataOptions = Default::default(); let decoder_opts: DecoderOptions = Default::default(); // Probe the media source stream for a format. let probed = symphonia::default::get_probe().format(&hint, mss, &format_opts, &metadata_opts).unwrap(); // Get the format reader yielded by the probe operation. let mut format = probed.format; // Get the default track. let track = format.default_track().unwrap(); // Create a decoder for the track. let mut decoder = symphonia::default::get_codecs().make(&track.codec_params, &decoder_opts).unwrap(); // Store the track identifier, we'll use it to filter packets. let track_id = track.id; let mut sample_count = 0; let mut sample_buf = None; loop { // Get the next packet from the format reader. let packet = format.next_packet().unwrap(); // If the packet does not belong to the selected track, skip it. if packet.track_id() != track_id { continue; } // Decode the packet into audio samples, ignoring any decode errors. match decoder.decode(&packet) { Ok(audio_buf) => { // The decoded audio samples may now be accessed via the audio buffer if per-channel // slices of samples in their native decoded format is desired. Use-cases where // the samples need to be accessed in an interleaved order or converted into // another sample format, or a byte buffer is required, are covered by copying the // audio buffer into a sample buffer or raw sample buffer, respectively. In the // example below, we will copy the audio buffer into a sample buffer in an // interleaved order while also converting to a f32 sample format. // If this is the *first* decoded packet, create a sample buffer matching the // decoded audio buffer format. if sample_buf.is_none() { // Get the audio buffer specification. let spec = *audio_buf.spec(); // Get the capacity of the decoded buffer. Note: This is capacity, not length! let duration = audio_buf.capacity() as u64; // Create the f32 sample buffer. sample_buf = Some(SampleBuffer::::new(duration, spec)); } // Copy the decoded audio buffer into the sample buffer in an interleaved format. if let Some(buf) = &mut sample_buf { buf.copy_interleaved_ref(audio_buf); // The samples may now be access via the `samples()` function. sample_count += buf.samples().len(); print!("\rDecoded {} samples", sample_count); } } Err(Error::DecodeError(_)) => (), Err(_) => break, } } } symphonia-0.5.2/examples/getting-started.rs000064400000000000000000000072321046102023000171340ustar 00000000000000use symphonia::core::codecs::{DecoderOptions, CODEC_TYPE_NULL}; use symphonia::core::errors::Error; use symphonia::core::formats::FormatOptions; use symphonia::core::io::MediaSourceStream; use symphonia::core::meta::MetadataOptions; use symphonia::core::probe::Hint; fn main() { // Get the first command line argument. let args: Vec = std::env::args().collect(); let path = args.get(1).expect("file path not provided"); // Open the media source. let src = std::fs::File::open(path).expect("failed to open media"); // Create the media source stream. let mss = MediaSourceStream::new(Box::new(src), Default::default()); // Create a probe hint using the file's extension. [Optional] let mut hint = Hint::new(); hint.with_extension("mp3"); // Use the default options for metadata and format readers. let meta_opts: MetadataOptions = Default::default(); let fmt_opts: FormatOptions = Default::default(); // Probe the media source. let probed = symphonia::default::get_probe() .format(&hint, mss, &fmt_opts, &meta_opts) .expect("unsupported format"); // Get the instantiated format reader. let mut format = probed.format; // Find the first audio track with a known (decodeable) codec. let track = format .tracks() .iter() .find(|t| t.codec_params.codec != CODEC_TYPE_NULL) .expect("no supported audio tracks"); // Use the default options for the decoder. let dec_opts: DecoderOptions = Default::default(); // Create a decoder for the track. let mut decoder = symphonia::default::get_codecs() .make(&track.codec_params, &dec_opts) .expect("unsupported codec"); // Store the track identifier, it will be used to filter packets. let track_id = track.id; // The decode loop. loop { // Get the next packet from the media format. let packet = match format.next_packet() { Ok(packet) => packet, Err(Error::ResetRequired) => { // The track list has been changed. Re-examine it and create a new set of decoders, // then restart the decode loop. This is an advanced feature and it is not // unreasonable to consider this "the end." As of v0.5.0, the only usage of this is // for chained OGG physical streams. unimplemented!(); } Err(err) => { // A unrecoverable error occured, halt decoding. panic!("{}", err); } }; // Consume any new metadata that has been read since the last packet. while !format.metadata().is_latest() { // Pop the old head of the metadata queue. format.metadata().pop(); // Consume the new metadata at the head of the metadata queue. } // If the packet does not belong to the selected track, skip over it. if packet.track_id() != track_id { continue; } // Decode the packet into audio samples. match decoder.decode(&packet) { Ok(_decoded) => { // Consume the decoded audio samples (see below). } Err(Error::IoError(_)) => { // The packet failed to decode due to an IO error, skip the packet. continue; } Err(Error::DecodeError(_)) => { // The packet failed to decode due to invalid data, skip the packet. continue; } Err(err) => { // An unrecoverable error occured, halt decoding. panic!("{}", err); } } } } symphonia-0.5.2/src/lib.rs000064400000000000000000000264651046102023000135570ustar 00000000000000// Symphonia // Copyright (c) 2019-2022 The Project Symphonia Developers. // // This Source Code Form is subject to the terms of the Mozilla Public // License, v. 2.0. If a copy of the MPL was not distributed with this // file, You can obtain one at https://mozilla.org/MPL/2.0/. #![warn(rust_2018_idioms)] #![forbid(unsafe_code)] //! # Project Symphonia //! //! Symphonia is a 100% pure Rust audio decoding and multimedia format demuxing framework. //! //! # Support //! //! Supported formats, codecs, and metadata tags are listed below. By default Symphonia only enables //! royalty-free open standard media formats and codecs. Other formats and codecs must be enabled //! using feature flags. //! //! **Tip:** All formats and codecs can be enabled with the `all` feature flag. //! //! ## Formats //! //! The following container formats are supported. //! //! | Format | Feature Flag | Gapless* | Default | //! |----------|--------------|----------|---------| //! | ISO/MP4 | `isomp4` | No | No | //! | MKV/WebM | `mkv` | No | Yes | //! | OGG | `ogg` | Yes | Yes | //! | Wave | `wav` | Yes | Yes | //! //! \* Gapless playback requires support from both the demuxer and decoder. //! //! **Tip:** All formats can be enabled with the `all-codecs` feature flag. //! //! ## Codecs //! //! The following codecs are supported. //! //! | Codec | Feature Flag | Gapless | Default | //! |----------|--------------|---------|---------| //! | AAC-LC | `aac` | No | No | //! | ADPCM | `adpcm` | Yes | Yes | //! | ALAC | `alac` | Yes | No | //! | FLAC | `flac` | Yes | Yes | //! | MP1 | `mp1`, `mpa` | No | No | //! | MP2 | `mp2`, `mpa` | No | No | //! | MP3 | `mp3`, `mpa` | Yes | No | //! | PCM | `pcm` | Yes | Yes | //! | Vorbis | `vorbis` | Yes | Yes | //! //! **Tip:** All codecs can be enabled with the `all-codecs` feature flag. Similarly, all MPEG //! audio codecs can be enabled with the `mpa` feature flag. //! //! ## Metadata //! //! The following metadata tagging formats are supported. These are always enabled. //! //! * ID3v1 //! * ID3v2 //! * ISO/MP4 //! * RIFF //! * Vorbis Comment (in OGG & FLAC) //! //! # Usage //! //! The following steps describe a basic usage of Symphonia: //! //! 1. Instantiate a [`CodecRegistry`][core::codecs::CodecRegistry] and register all the codecs //! that are of interest. Alternatively, you may use [`default::get_codecs`] to get the default //! registry with all the enabled codecs pre-registered. The registry will be used to //! instantiate a [`Decoder`][core::codecs::Decoder] later. //! 2. Instantiate a [`Probe`][core::probe::Probe] and register all the formats that are of //! interest. Alternatively, you may use [`default::get_probe`] to get a default format probe //! with all the enabled formats pre-registered. The probe will be used to automatically detect //! the media format and instantiate a compatible [`FormatReader`][core::formats::FormatReader]. //! 3. Make sure the [`MediaSource`][core::io::MediaSource] trait is implemented for whatever //! source you are using. This trait is already implemented for `std::fs::File` and //! `std::io::Cursor`. //! 4. Instantiate a [`MediaSourceStream`][core::io::MediaSourceStream] with the `MediaSource` //! above. //! 5. Using the `Probe`, call [`format`][core::probe::Probe::format] and pass it the //! `MediaSourceStream`. //! 6. If the probe successfully detects a compatible format, a `FormatReader` will be returned. //! This is an instance of a demuxer that can read and demux the provided source into //! [`Packet`][core::formats::Packet]s. //! 7. At this point it is possible to interrogate the `FormatReader` for general information about //! the media and metadata. Examine the [`Track`][core::formats::Track] listing using //! [`tracks`][core::formats::FormatReader::tracks] and select one or more tracks of interest to //! decode. //! 8. To instantiate a `Decoder` for a selected `Track`, call the `CodecRegistry`'s //! [`make`][core::codecs::CodecRegistry::make] function and pass it //! the [`CodecParameters`][core::codecs::CodecParameters] for that track. This step is repeated //! once per selected track. //! 9. To decode a track, obtain a packet from the `FormatReader` by //! calling [`next_packet`][`core::formats::FormatReader::next_packet`] and then pass the //! `Packet` to the `Decoder` for that track. The [`decode`][core::codecs::Decoder::decode] //! function will read a packet and return an [`AudioBufferRef`][core::audio::AudioBufferRef] //! (an "any-type" [`AudioBuffer`][core::audio::AudioBuffer]). //! 10. The `AudioBufferRef` may be used to access the decoded audio samples directly, or it can be //! copied into a [`SampleBuffer`][core::audio::SampleBuffer] or //! [`RawSampleBuffer`][core::audio::RawSampleBuffer] to export the audio out of Symphonia. //! 11. Repeat step 9 and 10 until the end-of-stream error is returned. //! //! An example implementation of a simple audio player (symphonia-play) can be found in the //! Project Symphonia git repository. //! //! # Gapless Playback //! //! Gapless playback is disabled by default. To enable gapless playback, set //! [`FormatOptions::enable_gapless`][core::formats::FormatOptions::enable_gapless] to `true`. //! //! # Adding new formats and codecs //! //! Simply implement the [`Decoder`][core::codecs::Decoder] trait for a decoder or the //! [`FormatReader`][core::formats::FormatReader] trait for a demuxer trait and register with //! the appropriate registry or probe! pub mod default { //! The `default` module provides convenience functions and registries to get an implementer //! up-and-running as quickly as possible, and to reduce boiler-plate. Using the `default` //! module is completely optional and incurs no overhead unless actually used. pub mod codecs { //! The `codecs` module re-exports all enabled Symphonia decoders. #[cfg(feature = "flac")] pub use symphonia_bundle_flac::FlacDecoder; #[cfg(any(feature = "mp1", feature = "mp2", feature = "mp3"))] pub use symphonia_bundle_mp3::MpaDecoder; #[cfg(feature = "aac")] pub use symphonia_codec_aac::AacDecoder; #[cfg(feature = "adpcm")] pub use symphonia_codec_adpcm::AdpcmDecoder; #[cfg(feature = "alac")] pub use symphonia_codec_alac::AlacDecoder; #[cfg(feature = "pcm")] pub use symphonia_codec_pcm::PcmDecoder; #[cfg(feature = "vorbis")] pub use symphonia_codec_vorbis::VorbisDecoder; #[deprecated = "use `default::codecs::MpaDecoder` instead"] #[cfg(any(feature = "mp1", feature = "mp2", feature = "mp3"))] pub type Mp3Decoder = MpaDecoder; } pub mod formats { //! The `formats` module re-exports all enabled Symphonia format readers. #[cfg(feature = "flac")] pub use symphonia_bundle_flac::FlacReader; #[cfg(any(feature = "mp1", feature = "mp2", feature = "mp3"))] pub use symphonia_bundle_mp3::MpaReader; #[cfg(feature = "aac")] pub use symphonia_codec_aac::AdtsReader; #[cfg(feature = "isomp4")] pub use symphonia_format_isomp4::IsoMp4Reader; #[cfg(feature = "mkv")] pub use symphonia_format_mkv::MkvReader; #[cfg(feature = "ogg")] pub use symphonia_format_ogg::OggReader; #[cfg(feature = "wav")] pub use symphonia_format_wav::WavReader; #[deprecated = "use `default::formats::MpaReader` instead"] #[cfg(any(feature = "mp1", feature = "mp2", feature = "mp3"))] pub type Mp3Reader = MpaReader; } use lazy_static::lazy_static; use symphonia_core::codecs::CodecRegistry; use symphonia_core::probe::Probe; lazy_static! { static ref CODEC_REGISTRY: CodecRegistry = { let mut registry = CodecRegistry::new(); register_enabled_codecs(&mut registry); registry }; } lazy_static! { static ref PROBE: Probe = { let mut probe: Probe = Default::default(); register_enabled_formats(&mut probe); probe }; } /// Gets the default `CodecRegistry`. This registry pre-registers all the codecs selected by the /// `feature` flags in the includer's `Cargo.toml`. If `features` is not set, the default set of /// Symphonia codecs is registered. /// /// This function is lazy and does not instantiate the `CodecRegistry` until the first call to /// this function. pub fn get_codecs() -> &'static CodecRegistry { &CODEC_REGISTRY } /// Gets the default `Probe`. This registry pre-registers all the formats selected by the /// `feature` flags in the includer's `Cargo.toml`. If `features` is not set, the default set of /// Symphonia formats is registered. /// /// This function is lazy and does not instantiate the `Probe` until the first call to this /// function. pub fn get_probe() -> &'static Probe { &PROBE } /// Registers all the codecs selected by the `feature` flags in the includer's `Cargo.toml` on /// the provided `CodecRegistry`. If `features` is not set, the default set of Symphonia codecs /// is registered. /// /// Use this function to easily populate a custom registry with all enabled codecs. pub fn register_enabled_codecs(registry: &mut CodecRegistry) { #[cfg(feature = "aac")] registry.register_all::(); #[cfg(feature = "adpcm")] registry.register_all::(); #[cfg(feature = "alac")] registry.register_all::(); #[cfg(feature = "flac")] registry.register_all::(); #[cfg(any(feature = "mp1", feature = "mp2", feature = "mp3"))] registry.register_all::(); #[cfg(feature = "pcm")] registry.register_all::(); #[cfg(feature = "vorbis")] registry.register_all::(); } /// Registers all the formats selected by the `feature` flags in the includer's `Cargo.toml` on /// the provided `Probe`. If `features` is not set, the default set of Symphonia formats is /// registered. /// /// Use this function to easily populate a custom probe with all enabled formats. pub fn register_enabled_formats(probe: &mut Probe) { use symphonia_metadata::id3v2::Id3v2Reader; // Formats #[cfg(feature = "aac")] probe.register_all::(); #[cfg(feature = "flac")] probe.register_all::(); #[cfg(feature = "isomp4")] probe.register_all::(); #[cfg(any(feature = "mp1", feature = "mp2", feature = "mp3"))] probe.register_all::(); #[cfg(feature = "wav")] probe.register_all::(); #[cfg(feature = "ogg")] probe.register_all::(); #[cfg(feature = "mkv")] probe.register_all::(); // Metadata probe.register_all::(); } } pub use symphonia_core as core;