Files
pmomusic/pmoaudio-ext/Cargo.toml
Claude d4508e603f Implement complete OGG-FLAC streaming with proper container wrapping
This commit implements full OGG container support for FLAC streaming,
wrapping FLAC frames in proper OGG pages with CRC32 validation.

## Changes

### pmoaudio-ext/src/sinks/streaming_ogg_flac_sink.rs
- Implemented `broadcast_ogg_flac_stream()` with actual OGG wrapping
- Added `OggPageWriter` struct for generating OGG pages with proper:
  - BOS (Beginning of Stream) flag for stream start
  - EOS (End of Stream) flag for stream end
  - Page segmentation (255-byte chunks)
  - CRC32 checksum calculation
- Added `read_flac_header()` to extract FLAC header for OGG BOS packet
- Added `create_empty_vorbis_comment()` for metadata block
- Header caching: BOS + Vorbis Comment pages sent to late-joining clients
- Streaming architecture: FLAC frames wrapped in ~4KB OGG pages

### pmoparadise/examples/stream_block.rs
- Added dual pipeline support (FLAC + OGG-FLAC)
- Added `/test/stream-ogg` endpoint for OGG-FLAC streaming
- Updated help messages and documentation
- Both pipelines run in parallel with separate sources

### pmoaudio-ext/Cargo.toml
- Added `rand = "0.8"` dependency for OGG stream serial generation

## Architecture

```
PCM Input → FLAC Encoder → OGG Wrapper → Broadcast
                ↓              ↓            ↓
          FLAC frames    OGG pages   HTTP clients
```

## OGG-FLAC Format

1. BOS page: Contains FLAC identification ("fLaC" + STREAMINFO)
2. Comment page: Contains Vorbis Comment block (metadata)
3. Data pages: Contain FLAC audio frames (~4KB per page)
4. EOS page: Marks end of logical bitstream

## Testing

Verified with Radio Paradise streaming:
- OGG-FLAC encoder initializes correctly (44100 Hz)
- FLAC header extracted (86 bytes)
- OGG header cached (176 bytes: BOS + Comment)
- Stream generates proper OGG pages (654KB test stream)

## Endpoints

- `/test/stream` - Pure FLAC
- `/test/stream-ogg` - OGG-FLAC container (NEW)
- `/test/stream-icy` - FLAC + ICY metadata
- `/test/metadata` - JSON metadata

## TODO (Deferred)

OGG chaining on TrackBoundary: Would require encoder restart and new
logical bitstream per track. Currently metadata is served via
`/test/metadata` endpoint for real-time updates.
2025-11-12 00:26:00 +00:00

39 lines
1.1 KiB
TOML

[package]
name = "pmoaudio-ext"
version = "0.1.0"
edition = "2021"
[dependencies]
# Core audio types
pmoaudio = { path = "../pmoaudio" }
pmocovers = { path = "../pmocovers"}
# Optional dependencies for cache-sink feature
pmoaudiocache = { path = "../pmoaudiocache", optional = true }
pmoflac = { path = "../pmoflac", optional = true }
pmometadata = { path = "../pmometadata", optional = true }
# Optional dependencies for playlist integration
pmoplaylist = { path = "../pmoplaylist", optional = true }
pmocache = { path = "../pmocache", optional = true }
# Async runtime
tokio = { version = "1.0", features = ["full"] }
tokio-util = { version = "0.7" }
async-trait = "0.1"
# Utilities
tracing = "0.1"
rand = "0.8"
# HTTP streaming dependencies
bytes = { version = "1.0", optional = true }
serde = { version = "1.0", features = ["derive"], optional = true }
[features]
default = []
cache-sink = ["dep:pmoaudiocache", "dep:pmoflac", "dep:pmometadata"]
playlist = ["cache-sink", "dep:pmoplaylist", "dep:pmocache"]
http-stream = ["dep:pmoflac", "dep:pmometadata", "dep:bytes", "dep:serde"]
all = ["cache-sink", "playlist", "http-stream"]