#capture #camera #webcam


Safe and ergonomic wrapper around libuvc, allowing capture of webcam streams

4 releases

✓ Uses Rust 2018 edition

0.1.3 Aug 10, 2019
0.1.2 Apr 26, 2019
0.1.1 Sep 11, 2018
0.1.0 Aug 12, 2018

#20 in Video

39 downloads per month

MIT license

962 lines

Safe rust wrapper around libuvc

crates.io license

This library gives access to the webcam, and allows one to capture the video stream. An example of how to use this library can be found in the examples directory.

An error such as Access might be due to the program not having read/write access to the usb device. This can be fixed up with chmod on the dev device.

chmod 0666 /dev/bus/usb/{BUS}/{DEVICE}

where BUS and DEVICE can be found with lsusb or by running the mirror example.


Documentation can be created with cargo doc


To use this crate, the libuvc native dependency must be installed.


Safe wrapper around libuvc

This crate gives access to webcams connected to the computer, allowing one to stream and capture video.

How to use this crate

use std::sync::atomic::{AtomicUsize, Ordering};
use std::sync::Arc;
use std::time::Duration;

fn main() {
// Get a libuvc context
let ctx = uvc::Context::new().expect("Could not get context");

// Get a default device
let dev = ctx
.find_device(None, None, None)
.expect("Could not find device");

// Or create an iterator over all available devices
let mut _devices = ctx.devices().expect("Could not enumerate devices");

// The device must be opened to create a handle to the device
let devh = dev.open().expect("Could not open device");

// Most webcams support this format
let format = uvc::StreamFormat {
width: 640,
height: 480,
fps: 30,
format: uvc::FrameFormat::YUYV,

// Get the necessary stream information
let mut streamh = devh
.expect("Could not open a stream with this format");

// This is a counter, increasing by one for every frame
// This data must be 'static + Send + Sync to be used in
// the callback used in the stream
let counter = Arc::new(AtomicUsize::new(0));

// Get a stream, calling the closure as callback for every frame
let stream = streamh
|_frame, count| {
count.fetch_add(1, Ordering::SeqCst);
).expect("Could not start stream");

// Wait 10 seconds
std::thread::sleep(Duration::new(10, 0));

// Explicitly stop the stream
// The stream would also be stopped
// when going out of scope (dropped)
println!("Counter: {}", counter.load(Ordering::SeqCst));

See also mirror.rs in the examples to get an example of how to capture and display a stream


~31K SLoC