Skip to content

Commit 4aa22e8

Browse files
authored
Merge pull request #851 from aschey/feat/registry
feat: opus support via libopus and allow registering additional codecs
2 parents e89e685 + 789bd1a commit 4aa22e8

11 files changed

Lines changed: 231 additions & 22 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ jobs:
1818
fail-fast: false
1919
matrix:
2020
os: [macos-latest, windows-latest, ubuntu-latest]
21-
toolchain: ["1.87"]
21+
toolchain: ["1.89"]
2222
include:
2323
- os: macos-latest
2424
MACOS: true

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1919
- Audio output fallback picked null device leading to no output.
2020
- Mixer did not actually add sources sometimes.
2121

22+
### Added
23+
24+
- Added Opus support via `symphonia-adapter-libopus`.
25+
- Third-party Symphonia codecs can be registered with `DecoderBuilder::with_symphonia_decoder`.
26+
2227
## Version [0.22.1] (2026-02-22)
2328

2429
### Fixed

Cargo.lock

Lines changed: 99 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ repository = "https://github.com/RustAudio/rodio"
88
documentation = "https://docs.rs/rodio"
99
exclude = ["assets/**", "tests/**"]
1010
edition = "2021"
11-
rust-version = "1.87"
11+
rust-version = "1.89"
1212

1313
[features]
1414
# Default feature set provides audio playback and common format support
@@ -50,6 +50,11 @@ noise = ["rand", "rand_distr"]
5050
# Enable WebAssembly support for web browsers
5151
wasm-bindgen = ["cpal/wasm-bindgen"]
5252

53+
# Base symphonia feature (doesn't enable any codecs)
54+
# A feature with this name is created implicitly due to other features that reference `symphonia/xxx`
55+
# but we need to make it explicit here so other features can reference it.
56+
symphonia = ["dep:symphonia"]
57+
5358
# To decode an audio source with Rodio, you need to enable the appropriate features for *both* the
5459
# demuxer and the decoder.
5560
#
@@ -96,6 +101,9 @@ symphonia-wav = ["symphonia/wav"]
96101
# Enable SIMD optimisations for Symphonia
97102
symphonia-simd = ["symphonia/opt-simd"]
98103

104+
# libopus adapter for Symphonia
105+
symphonia-libopus = ["symphonia", "dep:symphonia-adapter-libopus"]
106+
99107
# Alternative decoders and demuxers
100108
claxon = ["dep:claxon"] # FLAC
101109
hound = ["dep:hound"] # WAV
@@ -126,13 +134,16 @@ atomic_float = { version = "1.1.0", optional = true }
126134
rtrb = { version = "0.3.2", optional = true }
127135
num-rational = "0.4.2"
128136

137+
symphonia-adapter-libopus = { version = "0.2", optional = true }
138+
129139
[dev-dependencies]
130140
quickcheck = "1"
131141
rstest = "0.26"
132142
rstest_reuse = "0.7"
133143
approx = "0.5.1"
134144
divan = "0.1.14"
135145
inquire = "0.9.3"
146+
symphonia-adapter-fdk-aac = "0.1"
136147

137148
[[bench]]
138149
name = "effects"
@@ -230,6 +241,10 @@ required-features = ["playback", "vorbis"]
230241
name = "music_wav"
231242
required-features = ["playback", "wav"]
232243

244+
[[example]]
245+
name = "music_opus"
246+
required-features = ["playback", "symphonia-libopus"]
247+
233248
[[example]]
234249
name = "noise_generator"
235250
required-features = ["playback", "noise"]
@@ -253,3 +268,7 @@ required-features = ["playback", "vorbis"]
253268
[[example]]
254269
name = "stereo"
255270
required-features = ["playback", "vorbis"]
271+
272+
[[example]]
273+
name = "third_party_codec"
274+
required-features = ["playback", "symphonia", "symphonia-isomp4"]

assets/music.opus

136 KB
Binary file not shown.

examples/music_opus.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
use std::error::Error;
2+
3+
fn main() -> Result<(), Box<dyn Error>> {
4+
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
5+
let player = rodio::Player::connect_new(stream_handle.mixer());
6+
7+
let file = std::fs::File::open("assets/music.opus")?;
8+
player.append(rodio::Decoder::try_from(file)?);
9+
10+
player.sleep_until_end();
11+
12+
Ok(())
13+
}

examples/third_party_codec.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
use rodio::decoder::DecoderBuilder;
2+
use std::error::Error;
3+
use symphonia_adapter_fdk_aac::AacDecoder;
4+
5+
fn main() -> Result<(), Box<dyn Error>> {
6+
let stream_handle = rodio::DeviceSinkBuilder::open_default_sink()?;
7+
let sink = rodio::Player::connect_new(stream_handle.mixer());
8+
9+
let file = std::fs::File::open("assets/music.m4a")?;
10+
let len = file.metadata()?.len();
11+
let decoder = DecoderBuilder::new()
12+
.with_data(file)
13+
// Note: the length must be known for Symphonia to properly detect the format for this file
14+
// This limitation will be removed in Symphonia 0.6
15+
.with_byte_len(len)
16+
.with_symphonia_decoder::<AacDecoder>()
17+
.build()?;
18+
sink.append(decoder);
19+
20+
sink.sleep_until_end();
21+
22+
Ok(())
23+
}

flake.nix

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
inputs: inputs.utils.lib.eachDefaultSystem (
99
system: let
1010
pkgs = inputs.nixpkgs.legacyPackages.${system}.extend inputs.rust-overlay.overlays.default;
11-
rust = pkgs.rust-bin.stable."1.87.0".default.override {
11+
rust = pkgs.rust-bin.stable."1.89.0".default.override {
1212
extensions = [ "rust-src" "rust-analyzer" ];
1313
};
1414
in {

0 commit comments

Comments
 (0)