Packages

Pure-Rust Opus codec for Elixir via Rustler

Current section

Files

Jump to
rusty_opus README.md
Raw

README.md

# RustyOpus
[![Hex.pm](https://img.shields.io/hexpm/v/rusty_opus.svg)](https://hex.pm/packages/rusty_opus)
[![HexDocs](https://img.shields.io/badge/HexDocs-API%20reference-6e4a7e.svg)](https://hexdocs.pm/rusty_opus)
[![CI](https://github.com/mindreframer/rusty_opus/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/mindreframer/rusty_opus/actions/workflows/ci.yml)
[![Precompiled NIFs](https://github.com/mindreframer/rusty_opus/actions/workflows/release.yml/badge.svg?branch=main)](https://github.com/mindreframer/rusty_opus/actions/workflows/release.yml)
[![License: Apache-2.0](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](https://github.com/mindreframer/rusty_opus/blob/main/LICENSE)
Pure-Rust [Opus](https://opus-codec.org/) for Elixir. No C `libopus`, no ffmpeg, no
external process — shrink real Ogg Opus blobs (or work with raw packets/PCM) in one BEAM
process.
**Headline:** take an Ogg Opus file/blob and make it smaller with a numeric bitrate
(defaults: VoIP, complexity 10, VBR, 20 ms — FFmpeg speech ladder analogues):
```elixir
{:ok, smaller} = RustyOpus.reencode(ogg_blob, bitrate: 20_000)
```
That is the whole call. Useful bitrate ladder values:
`8_000`, `12_000`, `16_000`, `20_000`, `24_000`, `32_000`.
## Quick start
```elixir
# Ogg Opus blob → smaller Ogg Opus blob (default path for files)
{:ok, smaller} = RustyOpus.reencode(ogg_blob, bitrate: 20_000)
# Raw packets / PCM (no container)
{:ok, packets} = RustyOpus.encode(pcm, 16_000, 1, bitrate: 24_000)
{:ok, pcm} = RustyOpus.decode(packets, 16_000, 1)
```
## Data contract
- **Ogg Opus** — RFC 7845 binaries (`audio/ogg` / `.ogg`) for `reencode/2`.
- **PCM** — little-endian IEEE-754 `f32`, interleaved for stereo.
- **Opus packets** — raw binaries (no container).
No WebM/MP4. Never launches an external process. See the [codec guide](docs/codec.md).
## Features
- `RustyOpus.reencode/2` — Ogg Opus blob → lower bitrate Ogg Opus blob (`opus-rs` + thin Ogg)
- `RustyOpus.encode/4`, `decode/4`, `transcode/5` — whole-stream raw packet/PCM path
- `RustyOpus.Encoder` / `Decoder` — per-frame control
- Dirty-scheduled codec work; panic containment at the NIF boundary
- Checksum-verified precompiled NIFs with source-build fallback
## Supported OS
Precompiled NIFs are published for:
- Apple Silicon macOS (`aarch64-apple-darwin`)
- Intel macOS (`x86_64-apple-darwin`)
- ARM64 Linux glibc (`aarch64-unknown-linux-gnu`)
- ARM64 Linux musl / Alpine (`aarch64-unknown-linux-musl`)
- x86-64 Linux glibc (`x86_64-unknown-linux-gnu`)
- x86-64 Linux musl / Alpine (`x86_64-unknown-linux-musl`)
Other targets can build from source with `RUSTY_OPUS_BUILD=1` and Rust 1.89.0.
## Technology
| Elixir module | Native crate | Rust packages |
| --- | --- | --- |
| `RustyOpus` | `native/rusty_opus_native` | `opus-rs 0.1.29` |
## Development
```sh
bin/qa_check.sh
```
Committed fixtures include an Ogg Opus speech blob for `reencode/2` tests.
Tests need neither a live database nor ffmpeg.
## Release
1. Bump the version in `mix.exs` and `native/rusty_opus_native/Cargo.toml`.
2. Run `bin/qa_check.sh` and push the green version commit.
3. Tag `v0.3.3`; the release workflow builds and smoke-tests every precompiled NIF.
4. Publish the Hex package and GitHub release (maintainer step).
## License
RustyOpus is licensed under the [Apache License 2.0](LICENSE). Bundled codec:
`opus-rs` (BSD-3-Clause) — see [NOTICE](NOTICE) and [provenance](docs/provenance.md).