Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Audio & Video

The blinc_media crate provides cross-platform audio/video with royalty-free codecs. Media widgets in blinc_layout (behind the media feature) provide player UIs.

Audio Playback

#![allow(unused)]
fn main() {
use blinc_media::{AudioPlayer, AudioSource};

let player = AudioPlayer::new();
player.play(AudioSource::file("music.ogg"));
player.set_volume(0.8);
player.pause();
player.seek(30_000); // seek to 30s
player.resume();

println!("Position: {}ms", player.position_ms());
}

Desktop: Vorbis, WAV, FLAC via rodio. Mobile: platform codecs via native bridge.

Video Playback

#![allow(unused)]
fn main() {
use blinc_media::{VideoPlayer, VideoDecoder};

let mut decoder = VideoDecoder::new();
let player = VideoPlayer::new();

// Decode H.264 NAL units → RGBA frames
if let Some(frame) = decoder.decode_nal(h264_packet) {
    player.push_frame(frame);
}

player.play();
player.seek(10_000);
}

Desktop: OpenH264 (royalty-free). Mobile: platform decoders via native bridge.

Player Trait

Both players implement the shared Player trait:

#![allow(unused)]
fn main() {
use blinc_media::Player;

fn show_status(p: &dyn Player) {
    println!("{} / {} | vol: {}", p.position_ms(), p.duration_ms(), p.volume());
}
}
MethodDescription
play() / pause() / stop()Playback controls
seek(ms)Seek to position
position_ms() / duration_ms()Time tracking
volume() / set_volume(f32)Volume (0.0–1.0)
is_playing() / is_live()State queries

Audio Widget

#![allow(unused)]
fn main() {
use std::rc::Rc;
use blinc_layout::widgets::media::audio_player;

let player = Rc::new(AudioPlayer::new());

// Basic controls
audio_player(Rc::clone(&player)).w_full().into_div()

// With waveform
audio_player(Rc::clone(&player))
    .waveform_data(&samples)
    .w_full()
    .into_div()
}

Video Widget

#![allow(unused)]
fn main() {
use std::rc::Rc;
use blinc_layout::widgets::media::video_player;

let player = Rc::new(VideoPlayer::new());

video_player(Rc::clone(&player))
    .show_dimensions()
    .w_full()
    .h(400.0)
    .into_div()
}

Waveform

Standalone amplitude visualization:

#![allow(unused)]
fn main() {
use blinc_layout::widgets::media::waveform;

waveform(buckets)
    .progress(0.5)
    .played_color(Color::BLUE)
    .unplayed_color(Color::GRAY)
    .w_full().h(60.0)
    .into_div()
}

Shared Controls

MediaControls is generic over Player:

#![allow(unused)]
fn main() {
use blinc_layout::widgets::media::MediaControls;

MediaControls::new(player_rc).class("my-controls").into_div()
}

Layout: [ ▶ ] [ 1:23 / 3:45 ] [ ══seek══ ] [ 80% ]

Live streams: [ ▶ ] [ LIVE ] [ ════════════ ]

Camera & Recording

#![allow(unused)]
fn main() {
use blinc_media::rtc::{CameraStream, CameraConfig, AudioRecorder};

let camera = CameraStream::open(CameraConfig::default());
let frame = camera.latest_frame(); // RGBA Frame

let recorder = AudioRecorder::open(Default::default());
let samples = recorder.latest_samples(); // AudioSamples

drop(camera);   // stops capture
drop(recorder);  // stops recording
}

Frame Utilities

#![allow(unused)]
fn main() {
use blinc_media::{Frame, AudioSamples};

// Video
let small = Frame::from_rgba(data, 640, 480).scale(320, 240);
let gray = small.to_gray();

// Audio
let mono = AudioSamples::from_f32(&pcm, 2, 44100).to_mono();
let resampled = mono.resample(48000);
}

CSS Classes

ClassElement
.blinc-audio-playerAudio container
.blinc-video-playerVideo container
.blinc-audio-waveformWaveform canvas
.blinc-media-controlsControls row
.blinc-media-play-btnPlay/pause
.blinc-media-timeTime display
.blinc-media-live-badgeLIVE indicator
.blinc-media-seek-trackSeek bar
.blinc-media-seek-fillSeek progress
.blinc-media-volumeVolume

Licensing

Desktop uses royalty-free codecs only — no ffmpeg, no patent fees:

CodecLicense
Vorbis, WAV, FLACBSD / Public domain
OpenH264BSD, Cisco covers patents

Mobile uses OS-provided codecs (licensing handled by the OS).