mirror of
https://github.com/l1npengtul/nokhwa.git
synced 2026-07-19 15:58:53 +00:00
update docs, rename requested format type to be more descriptive and autocomplete friendly
This commit is contained in:
@@ -8,15 +8,30 @@ A Simple-to-use, cross-platform Rust Webcam Capture Library
|
||||
Nokhwa can be added to your crate by adding it to your `Cargo.toml`:
|
||||
```toml
|
||||
[dependencies.nokhwa]
|
||||
# TODO: replace the "*" with the latest version of `nokhwa`
|
||||
version = "*"
|
||||
# TODO: add some features
|
||||
features = [""]
|
||||
version = "0.10.0-rc2"
|
||||
# Use the native inputs
|
||||
features = ["input-native", "output-wgpu"]
|
||||
```
|
||||
|
||||
Most likely, you will only use functionality provided by the `Camera` struct. If you need lower-level access, you may instead opt to use the raw capture backends found at `nokhwa::backends::capture::*`.
|
||||
|
||||
## Example
|
||||
```rust
|
||||
// first camera in system
|
||||
let index = CameraIndex::index(0);
|
||||
// request the absolute highest resolution CameraFormat that can be decoded to RGB.
|
||||
let requested = RequestedFormat::<RgbFormat>::new(RequestedFormatType::AbsoluteHighestFrameRate);
|
||||
// make the camera
|
||||
let mut camera = Camera::new(index, requested).unwrap();
|
||||
|
||||
// get a frame
|
||||
let frame = camera.frame().unwrap();
|
||||
println!("Captured Single Frame of {}", frame.buffer().len());
|
||||
// decode into an ImageBuffer
|
||||
let decoded = frame.decode_image::<RgbFormat>().unwrap();
|
||||
println!("Decoded Frame of {}", decoded.len());
|
||||
```
|
||||
|
||||
A command line app made with `nokhwa` can be found in the `examples` folder.
|
||||
|
||||
## API Support
|
||||
@@ -27,22 +42,18 @@ The table below lists current Nokhwa API support.
|
||||
- The `Query-Device` column signifies reading device capabilities
|
||||
- The `Platform` column signifies what Platform this is availible on.
|
||||
|
||||
| Backend | Input | Query | Query-Device | Platform |
|
||||
|-----------------------------------------|--------------------|-------------------|--------------------|---------------------|
|
||||
| Video4Linux(`input-v4l`) | ✅ | ✅ | ✅ | Linux |
|
||||
| MSMF(`input-msmf`) | ✅ | ✅ | ✅ | Windows |
|
||||
| AVFoundation(`input-avfoundation`)^^ | ✅ | ✅ | ✅ | Mac |
|
||||
| libuvc(`input-uvc`) (**DEPRECATED**)^^^ | ❌ | ✅ | ❌ | Linux, Windows, Mac |
|
||||
| OpenCV(`input-opencv`)^ | ✅ | ❌ | ❌ | Linux, Windows, Mac |
|
||||
| GStreamer(`input-gst`)(**DEPRECATED**) | ✅ | ✅ | ✅ | Linux, Windows, Mac |
|
||||
| JS/WASM(`input-wasm`) | ✅ | ✅ | ✅ | Browser(Web) |
|
||||
| Backend | Input | Query | Query-Device | Platform |
|
||||
|-----------------------------------------|-------------------|--------------------|-------------------|--------------------|
|
||||
| Video4Linux(`input-native`) | ✅ | ✅ | ✅ | Linux |
|
||||
| MSMF(`input-native`) | ✅ | ✅ | ✅ | Windows |
|
||||
| AVFoundation(`input-native`) | ✅ | ✅ | ✅ | Mac |
|
||||
| OpenCV(`input-opencv`)^ | ✅ | ❌ | ❌ | Linux, Windows, Mac |
|
||||
| WASM(`input-wasm`) | ✅ | ✅ | ✅ | Browser(Web) |
|
||||
|
||||
✅: Working, 🔮 : Experimental, ❌ : Not Supported, 🚧: Planned/WIP
|
||||
|
||||
^ = May be bugged. Also supports IP Cameras.
|
||||
|
||||
^^ = No FPS setting support.
|
||||
|
||||
^^^ = `input-uvc` is disabled for now as there are lifetime/soundness holes. You can still query, however.
|
||||
## Feature
|
||||
The default feature includes nothing. Anything starting with `input-*` is a feature that enables the specific backend.
|
||||
|
||||
@@ -157,12 +157,12 @@ fn nokhwa_main() {
|
||||
} => {
|
||||
let requested = match requested {
|
||||
Some(req) => match req.format_type.as_str() {
|
||||
"HighestResolutionAbs" => {
|
||||
RequestedFormat::new::<RgbFormat>(RequestedFormatType::HighestResolutionAbs)
|
||||
}
|
||||
"HighestFrameRateAbs" => {
|
||||
RequestedFormat::new::<RgbFormat>(RequestedFormatType::HighestFrameRateAbs)
|
||||
}
|
||||
"HighestResolutionAbs" => RequestedFormat::new::<RgbFormat>(
|
||||
RequestedFormatType::AbsoluteHighestResolution,
|
||||
),
|
||||
"HighestFrameRateAbs" => RequestedFormat::new::<RgbFormat>(
|
||||
RequestedFormatType::AbsoluteHighestFrameRate,
|
||||
),
|
||||
"HighestResolution" => {
|
||||
let values = req.format_option.unwrap().split(",").collect::<Vec<&str>>();
|
||||
let x = values[0].parse::<u32>().unwrap();
|
||||
@@ -262,12 +262,12 @@ fn nokhwa_main() {
|
||||
};
|
||||
let requested = match requested {
|
||||
Some(req) => match req.format_type.as_str() {
|
||||
"HighestResolutionAbs" => {
|
||||
RequestedFormat::new::<RgbFormat>(RequestedFormatType::HighestResolutionAbs)
|
||||
}
|
||||
"HighestFrameRateAbs" => {
|
||||
RequestedFormat::new::<RgbFormat>(RequestedFormatType::HighestFrameRateAbs)
|
||||
}
|
||||
"HighestResolutionAbs" => RequestedFormat::new::<RgbFormat>(
|
||||
RequestedFormatType::AbsoluteHighestResolution,
|
||||
),
|
||||
"HighestFrameRateAbs" => RequestedFormat::new::<RgbFormat>(
|
||||
RequestedFormatType::AbsoluteHighestFrameRate,
|
||||
),
|
||||
"HighestResolution" => {
|
||||
let values = req.format_option.unwrap().split(",").collect::<Vec<&str>>();
|
||||
let x = values[0].parse::<u32>().unwrap();
|
||||
|
||||
@@ -9,8 +9,8 @@ use std::{
|
||||
};
|
||||
|
||||
/// Tells the init function what camera format to pick.
|
||||
/// - `HighestResolutionAbs`: Pick the highest [`Resolution`], then pick the highest frame rate of those provided.
|
||||
/// - `HighestFrameRateAbs`: Pick the highest frame rate, then the highest [`Resolution`].
|
||||
/// - `AbsoluteHighestResolution`: Pick the highest [`Resolution`], then pick the highest frame rate of those provided.
|
||||
/// - `AbsoluteHighestFrameRate`: Pick the highest frame rate, then the highest [`Resolution`].
|
||||
/// - `HighestResolution(Option<u32>)`: Pick the highest [`Resolution`] for the given framerate (the `Option<u32>`). If its `None`, it will pick the highest possible [`Resolution`]
|
||||
/// - `HighestFrameRate(Option<Resolution>)`: Pick the highest frame rate for the given [`Resolution`] (the `Option<Resolution>`). If it is `None`, it will pick the highest possinle framerate.
|
||||
/// - `Exact`: Pick the exact [`CameraFormat`] provided.
|
||||
@@ -19,8 +19,8 @@ use std::{
|
||||
#[derive(Copy, Clone, Debug, Hash, Ord, PartialOrd, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
|
||||
pub enum RequestedFormatType {
|
||||
HighestResolutionAbs,
|
||||
HighestFrameRateAbs,
|
||||
AbsoluteHighestResolution,
|
||||
AbsoluteHighestFrameRate,
|
||||
HighestResolution(Resolution),
|
||||
HighestFrameRate(u32),
|
||||
Exact(CameraFormat),
|
||||
@@ -84,7 +84,7 @@ impl RequestedFormat<'_> {
|
||||
#[allow(clippy::too_many_lines)]
|
||||
pub fn fulfill(&self, all_formats: &[CameraFormat]) -> Option<CameraFormat> {
|
||||
match self.requested_format {
|
||||
RequestedFormatType::HighestResolutionAbs => {
|
||||
RequestedFormatType::AbsoluteHighestResolution => {
|
||||
let mut formats = all_formats.to_vec();
|
||||
formats.sort_by_key(CameraFormat::resolution);
|
||||
let resolution = *formats.iter().last()?;
|
||||
@@ -98,7 +98,7 @@ impl RequestedFormat<'_> {
|
||||
format_resolutions.sort_by_key(CameraFormat::frame_rate);
|
||||
format_resolutions.last().copied()
|
||||
}
|
||||
RequestedFormatType::HighestFrameRateAbs => {
|
||||
RequestedFormatType::AbsoluteHighestFrameRate => {
|
||||
let mut formats = all_formats.to_vec();
|
||||
formats.sort_by_key(CameraFormat::resolution);
|
||||
let frame_rate = *formats.iter().last()?;
|
||||
|
||||
+1
-1
@@ -48,7 +48,7 @@ type HeldCallbackType = Arc<Mutex<Box<dyn FnMut(Buffer) + Send + 'static>>>;
|
||||
/// complete before a new frame is available. If you need to do heavy image processing, it may be
|
||||
/// beneficial to directly pipe the data to a new thread to process it there.
|
||||
///
|
||||
/// Note that this does not have `WGPU` capabilities. However, it should be easy to implement.
|
||||
/// Note that this does not have `WGPU` capabilities. This should be implemented in your callback.
|
||||
/// # SAFETY
|
||||
/// The `Mutex` guarantees exclusive access to the underlying camera struct. They should be safe to
|
||||
/// impl `Send` on.
|
||||
|
||||
Reference in New Issue
Block a user