{"id":28953591,"url":"https://github.com/dspearson/oggmux","last_synced_at":"2026-02-22T01:38:58.788Z","repository":{"id":294983643,"uuid":"969600464","full_name":"dspearson/oggmux","owner":"dspearson","description":null,"archived":false,"fork":false,"pushed_at":"2025-04-23T16:32:49.000Z","size":109,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-08T21:47:45.376Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"isc","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dspearson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-04-20T14:20:46.000Z","updated_at":"2025-04-20T14:20:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"892860aa-e910-4ef7-a136-5f75b068daa7","html_url":"https://github.com/dspearson/oggmux","commit_stats":null,"previous_names":["dspearson/oggmux"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/dspearson/oggmux","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dspearson%2Foggmux","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dspearson%2Foggmux/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dspearson%2Foggmux/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dspearson%2Foggmux/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dspearson","download_url":"https://codeload.github.com/dspearson/oggmux/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dspearson%2Foggmux/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29703227,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T23:35:04.139Z","status":"ssl_error","status_checked_at":"2026-02-21T23:35:03.832Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-06-23T18:09:18.778Z","updated_at":"2026-02-22T01:38:58.783Z","avatar_url":"https://github.com/dspearson.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# OggMux\n\nA Rust library for muxing Ogg streams with clean silence gaps, suitable for streaming applications like Icecast.\n\n## Features\n\n- **Continuous streaming**: Automatically inserts silence when audio input is not available\n- **Clean transitions**: Manages transitions between real audio data and silence\n- **Time-accurate**: Maintains proper timing across stream transitions\n- **Buffering**: Configurable buffering to handle network jitter\n- **Async-first**: Built with Tokio for high-performance asynchronous operation\n- **Robust error handling**: Uses anyhow for rich error context and graceful recovery\n- **Helper utilities**: Functions for calculating optimal buffer sizes based on bitrate and latency requirements\n- **Stream metrics**: Collection and monitoring of stream health statistics\n\n### Basic Example\n\n```rust\nuse oggmux::{OggMux, BufferConfig, VorbisConfig, VorbisBitrateMode};\nuse bytes::Bytes;\nuse tokio::time::sleep;\nuse std::time::Duration;\n\n#[tokio::main]\nasync fn main() -\u003e anyhow::Result\u003c()\u003e {\n    // Create a new OggMux with custom configuration\n    let mux = OggMux::new()\n        .with_buffer_config(BufferConfig {\n            buffered_seconds: 10.0,\n            channel_capacity: 4096,\n        })\n        .with_vorbis_config(VorbisConfig {\n            sample_rate: 44100,\n            bitrate: VorbisBitrateMode::CBR(320),\n        });\n\n    // Spawn the muxer and get the channels\n    let (input_tx, mut output_rx, shutdown_tx, handle) = mux.spawn();\n\n    // Feed some data (e.g., from a file or network stream)\n    let ogg_data = Bytes::from_static(\u0026[/* Ogg data here */]);\n    let _ = input_tx.send(ogg_data).await;\n\n    // Read the processed output (e.g., send to Icecast)\n    tokio::spawn(async move {\n        while let Some(output) = output_rx.recv().await {\n            // Send output to your streaming destination\n            println!(\"Got {} bytes of muxed output\", output.len());\n        }\n    });\n\n    // ... do work ...\n\n    // Gracefully shut down when done\n    let _ = shutdown_tx.send(()).await;\n    handle.await??;  // Wait for clean exit and check for errors\n\n    Ok(())\n}\n```\n\n## Configuration\n\n### Buffer Configuration\n\n```rust\nBufferConfig {\n    buffered_seconds: 10.0,    // Target amount of audio to keep buffered\n    channel_capacity: 65536,   // Maximum number of chunks buffered in channel\n}\n```\n\n### Vorbis Configuration\n\nYou can configure the vorbis stream in two ways:\n\n#### Constant Bitrate (CBR)\n\n```rust\nVorbisConfig {\n    sample_rate: 44100,                   // Sample rate in Hz\n    bitrate: VorbisBitrateMode::CBR(320), // 320 kbps constant bitrate\n}\n```\n\n#### Variable Bitrate (VBR)\n\n```rust\nVorbisConfig {\n    sample_rate: 44100,                        // Sample rate in Hz\n    bitrate: VorbisBitrateMode::VBRQuality(6), // Quality level 6 VBR\n}\n```\n\n## How It Works\n\nOggMux maintains a continuous flow of Ogg data by:\n\n1. Processing incoming audio data when available\n2. Inserting silence data when input is empty\n3. Managing Ogg page boundaries and granule positions\n4. Ensuring proper time synchronisation across stream transitions\n\nThis approach is ideal for applications where a continuous stream must be maintained despite irregular input data, such as live streaming or internet radio.\n\n## Requirements\n\n- Rust 2024 edition or later\n- Tokio runtime\n\n## Utility Functions\n\nOggMux provides helper functions for calculating optimal buffer sizes:\n\n```rust\nuse oggmux::{calculate_buffer_size, calculate_buffered_seconds};\n\n// Calculate ideal buffer size based on bitrate and target latency\nlet buffer_size = calculate_buffer_size(192, 500); // 192kbps, 500ms latency -\u003e 16384 bytes\n\n// Calculate how many seconds of audio a buffer can hold\nlet seconds = calculate_buffered_seconds(192, 16384); // ~0.68 seconds at 192kbps\n```\n\nThese utilities help you configure your streaming application for optimal performance.\n\n## Stream Metrics\n\nOggMux can collect metrics about the streaming process, which is helpful for monitoring and debugging:\n\n```rust\nuse oggmux::{OggMux, MetricsCollector};\n\n// Enable metrics collection\nlet mux = OggMux::new().with_metrics();\n\n// Get the metrics collector before spawning\nlet metrics = mux.metrics();\n\n// Spawn the muxer\nlet (input_tx, output_rx, shutdown_tx, handle) = mux.spawn();\n\n// Use the metrics collector\nif let Some(metrics) = metrics {\n    // Later, retrieve metrics:\n    tokio::spawn(async move {\n        loop {\n            tokio::time::sleep(std::time::Duration::from_secs(5)).await;\n            \n            // Get a snapshot of current metrics\n            let snapshot = metrics.snapshot().await;\n            \n            println!(\"Stream stats:\");\n            println!(\"  Bytes processed: {}\", snapshot.bytes_processed);\n            println!(\"  Silence insertions: {}\", snapshot.silence_insertions);\n            println!(\"  Silence percentage: {:.1}%\", snapshot.silence_percentage());\n            println!(\"  Buffer utilization: {:.1}%\", snapshot.buffer_utilization.last);\n            println!(\"  Processing latency: {:.2}ms avg, {:.2}ms max\", \n                     snapshot.processing_latency_ms.avg,\n                     snapshot.processing_latency_ms.max);\n        }\n    });\n}\n```\n\nAvailable metrics include:\n- Bytes processed and silence inserted\n- Number of silence insertions and real streams\n- Buffer utilization percentage\n- Processing latency statistics\n- Uptime and stream health indicators\n\n## Limitations\n\n- Currently only supports Ogg Vorbis format\n- Silence data must have the same format as the main audio stream\n- Best suited for streaming applications rather than file manipulation\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdspearson%2Foggmux","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdspearson%2Foggmux","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdspearson%2Foggmux/lists"}