diff --git a/.run/Clippy All.run.xml b/.run/Clippy All.run.xml
new file mode 100644
index 0000000..74cbf86
--- /dev/null
+++ b/.run/Clippy All.run.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.run/Clippy Main.run.xml b/.run/Clippy Main Apple.run.xml
similarity index 86%
rename from .run/Clippy Main.run.xml
rename to .run/Clippy Main Apple.run.xml
index bd75d7a..6fc8003 100644
--- a/.run/Clippy Main.run.xml
+++ b/.run/Clippy Main Apple.run.xml
@@ -1,5 +1,5 @@
-
+
diff --git a/.run/JSCam.run.xml b/.run/JSCam.run.xml
new file mode 100644
index 0000000..c1be1b6
--- /dev/null
+++ b/.run/JSCam.run.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/Cargo.toml b/Cargo.toml
index 428a9a7..14ac369 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -31,10 +31,10 @@ input-ipcam = ["input-opencv"]
input-gst = ["gstreamer", "glib", "gstreamer-app", "gstreamer-video", "regex", "parking_lot"]
input-jscam = ["web-sys", "js-sys", "wasm-bindgen-futures", "wasm-bindgen", "wasm-rs-async-executor"]
output-wgpu = ["wgpu", "nokhwa-core/wgpu-types"]
-output-wasm = ["input-jscam"]
+#output-wasm = ["input-jscam"]
output-threaded = []
small-wasm = []
-docs-only = ["input-v4l", "input-opencv", "input-ipcam", "input-gst", "input-msmf", "input-avfoundation", "input-jscam","output-wgpu", "output-wasm", "output-threaded"]
+docs-only = ["input-v4l", "input-opencv", "input-ipcam", "input-gst", "input-msmf", "input-avfoundation", "input-jscam","output-wgpu", "output-threaded"]
docs-nolink = ["glib/dox", "gstreamer-app/dox", "gstreamer/dox", "gstreamer-video/dox", "opencv/docs-only"]
docs-features = []
test-fail-warning = []
@@ -72,11 +72,11 @@ version = "0.1.2"
optional = true
[dependencies.wgpu]
-version = "0.13"
+version = "0.14"
optional = true
[dependencies.opencv]
-version = "0.67"
+version = "0.69"
optional = true
[dependencies.rgb]
diff --git a/nokhwa-bindings-macos/Cargo.toml b/nokhwa-bindings-macos/Cargo.toml
index 9fbb26a..8da9af0 100644
--- a/nokhwa-bindings-macos/Cargo.toml
+++ b/nokhwa-bindings-macos/Cargo.toml
@@ -11,12 +11,14 @@ keywords = ["avfoundation", "macos", "capture", "webcam"]
[dependencies]
flume = "0.10"
-core-media-sys = "0.1"
-cocoa-foundation = "0.1"
-objc = { version = "0.2", features = ["exception"] }
-block = "0.1"
once_cell = "1.14"
[dependencies.nokhwa-core]
version = "0.1"
path = "../nokhwa-core"
+
+[target.'cfg(any(target_os="windows",target_os="windows"))'.dependencies]
+core-media-sys = "0.1"
+cocoa-foundation = "0.1"
+objc = { version = "0.2", features = ["exception"] }
+block = "0.1"
diff --git a/nokhwa-bindings-windows/Cargo.toml b/nokhwa-bindings-windows/Cargo.toml
index 07505ac..98e8455 100644
--- a/nokhwa-bindings-windows/Cargo.toml
+++ b/nokhwa-bindings-windows/Cargo.toml
@@ -17,6 +17,6 @@ lazy_static = "1.4.0"
version = "0.1"
path = "../nokhwa-core"
-[dependencies.windows]
-version = "0.39.0"
+[target.'cfg(any(target_os="windows",target_os="windows"))'.dependencies.windows]
+version = "0.42"
features = ["Win32_Media_MediaFoundation", "Win32_System_Com", "Win32_Foundation", "Win32_Media_DirectShow", "Win32_Media", "Win32"]
diff --git a/nokhwa-bindings-windows/src/lib.rs b/nokhwa-bindings-windows/src/lib.rs
index a70f596..962905a 100644
--- a/nokhwa-bindings-windows/src/lib.rs
+++ b/nokhwa-bindings-windows/src/lib.rs
@@ -31,6 +31,7 @@
#[macro_use]
extern crate lazy_static;
+#[cfg(all(target_os = "windows", windows))]
use std::{
borrow::{Borrow, Cow},
cmp::Ordering,
@@ -668,7 +669,7 @@ pub mod wmf {
let mut receiver: MaybeUninit = MaybeUninit::uninit();
let mut ptr_receiver = receiver.as_mut_ptr();
if let Err(why) = self.source_reader.GetServiceForStream(
- MEDIA_FOUNDATION_FIRST_VIDEO_STREAM,
+ MF_SOURCE_READER_MEDIASOURCE,
&MF_MEDIASOURCE_SERVICE,
&IMFMediaSource::IID,
std::ptr::addr_of_mut!(ptr_receiver).cast::<*mut std::ffi::c_void>(),
@@ -1227,10 +1228,12 @@ pub mod wmf {
#[allow(clippy::missing_errors_doc)]
#[allow(clippy::unused_self)]
pub mod wmf {
- use nokhwa_core::error::NokhwaError;
- use nokhwa_core::types::{
- CameraControl, CameraFormat, CameraIndex, CameraInfo, ControlValueSetter,
- KnownCameraControl,
+ use nokhwa_core::{
+ error::NokhwaError,
+ types::{
+ CameraControl, CameraFormat, CameraIndex, CameraInfo, ControlValueSetter,
+ KnownCameraControl,
+ },
};
use std::borrow::Cow;
@@ -1255,16 +1258,20 @@ pub mod wmf {
struct Empty;
pub struct MediaFoundationDevice<'a> {
- phantom: &'a Empty,
+ _phantom: &'a Empty,
+ camera: CameraIndex,
}
impl<'a> MediaFoundationDevice<'a> {
pub fn new(_index: CameraIndex) -> Result {
- Ok(MediaFoundationDevice { phantom: &Empty })
+ Ok(MediaFoundationDevice {
+ _phantom: &Empty,
+ camera: CameraIndex::Index(0),
+ })
}
pub fn index(&self) -> &CameraIndex {
- &CameraIndex::default()
+ &self.camera
}
pub fn name(&self) -> String {
diff --git a/nokhwa-core/Cargo.toml b/nokhwa-core/Cargo.toml
index 0ea8b7a..3141756 100644
--- a/nokhwa-core/Cargo.toml
+++ b/nokhwa-core/Cargo.toml
@@ -31,7 +31,7 @@ features = ["derive"]
optional = true
[dependencies.wgpu]
-version = "0.13"
+version = "0.14"
optional = true
[dependencies.mozjpeg]
diff --git a/nokhwa-core/src/lib.rs b/nokhwa-core/src/lib.rs
index d339a33..8705f41 100644
--- a/nokhwa-core/src/lib.rs
+++ b/nokhwa-core/src/lib.rs
@@ -1,8 +1,4 @@
//! Core type definitions for `nokhwa`
-
-extern crate core;
-extern crate core;
-
pub mod buffer;
pub mod error;
pub mod pixel_format;
diff --git a/nokhwa-core/src/pixel_format.rs b/nokhwa-core/src/pixel_format.rs
index 8f70b66..bb6d895 100644
--- a/nokhwa-core/src/pixel_format.rs
+++ b/nokhwa-core/src/pixel_format.rs
@@ -21,7 +21,7 @@ use image::{Luma, LumaA, Pixel, Rgb, Rgba};
use std::fmt::Debug;
/// Trait that has methods to convert raw data from the webcam to a proper raw image.
-pub trait FormatDecoder: Copy + Clone + Debug + Default + Sized + Send + Sync {
+pub trait FormatDecoder: Clone + Sized + Send + Sync {
type Output: Pixel;
const FORMATS: &'static [FrameFormat];
diff --git a/nokhwa-core/src/traits.rs b/nokhwa-core/src/traits.rs
index ee674ac..38bc533 100644
--- a/nokhwa-core/src/traits.rs
+++ b/nokhwa-core/src/traits.rs
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-use crate::types::KnownCameraControlFlag;
use crate::{
buffer::Buffer,
error::NokhwaError,
diff --git a/nokhwa-core/src/types.rs b/nokhwa-core/src/types.rs
index e6a22d2..0bdd33f 100644
--- a/nokhwa-core/src/types.rs
+++ b/nokhwa-core/src/types.rs
@@ -143,8 +143,7 @@ impl RequestedFormat {
}
RequestedFormatType::None => all_formats
.iter()
- .filter(|fmt| self.wanted_decoder.contains(&fmt.format()))
- .nth(0)
+ .find(|fmt| self.wanted_decoder.contains(&fmt.format()))
.copied(),
}
}
@@ -766,7 +765,7 @@ impl ControlValueDescription {
#[must_use]
pub fn verify_setter(&self, setter: &ControlValueSetter) -> bool {
match self {
- ControlValueDescription::None => return setter.as_none().is_some(),
+ ControlValueDescription::None => setter.as_none().is_some(),
ControlValueDescription::Integer {
value,
default,
@@ -1395,7 +1394,7 @@ pub fn mjpeg_to_rgb(data: &[u8], rgba: bool) -> Result, NokhwaError> {
}
#[cfg(not(all(feature = "mjpeg", not(target_arch = "wasm"))))]
-pub fn mjpeg_to_rgb(data: &[u8], rgba: bool) -> Result, NokhwaError> {
+pub fn mjpeg_to_rgb(_data: &[u8], _rgba: bool) -> Result, NokhwaError> {
Err(NokhwaError::NotImplementedError(
"Not available on WASM".to_string(),
))
@@ -1458,7 +1457,7 @@ pub fn buf_mjpeg_to_rgb(data: &[u8], dest: &mut [u8], rgba: bool) -> Result<(),
}
#[cfg(not(all(feature = "mjpeg", not(target_arch = "wasm"))))]
-pub fn buf_mjpeg_to_rgb(data: &[u8], dest: &mut [u8], rgba: bool) -> Result<(), NokhwaError> {
+pub fn buf_mjpeg_to_rgb(_data: &[u8], _dest: &mut [u8], _rgba: bool) -> Result<(), NokhwaError> {
Err(NokhwaError::NotImplementedError(
"Not available on WASM".to_string(),
))
diff --git a/src/backends/capture/avfoundation.rs b/src/backends/capture/avfoundation.rs
index 0dcefd8..9e2e88e 100644
--- a/src/backends/capture/avfoundation.rs
+++ b/src/backends/capture/avfoundation.rs
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-
+#[cfg(target_os = "macos")]
use nokhwa_bindings_macos::{
AVCaptureDevice, AVCaptureDeviceInput, AVCaptureSession, AVCaptureVideoCallback,
AVCaptureVideoDataOutput,
@@ -27,11 +27,10 @@ use nokhwa_core::{
FrameFormat, KnownCameraControl, RequestedFormat, Resolution,
},
};
-use std::collections::BTreeMap;
-use std::ffi::CString;
+use std::{borrow::Cow, collections::HashMap};
+#[cfg(target_os = "macos")]
use std::{
- borrow::Cow,
- collections::HashMap,
+ ffi::CString,
sync::{Arc, Mutex},
};
@@ -44,6 +43,7 @@ use std::{
/// - FPS adjustment does not work.
/// - If permission has not been granted and you call `init()` it will error.
#[cfg_attr(feature = "docs-features", doc(cfg(feature = "input-avfoundation")))]
+#[cfg(target_os = "macos")]
pub struct AVFoundationCaptureDevice {
device: AVCaptureDevice,
dev_input: Option,
@@ -56,6 +56,7 @@ pub struct AVFoundationCaptureDevice {
frame_buffer_lock: Arc, FrameFormat)>>,
}
+#[cfg(target_os = "macos")]
impl AVFoundationCaptureDevice {
/// Creates a new capture device using the `AVFoundation` backend. Indexes are gives to devices by the OS, and usually numbered by order of discovery.
///
@@ -113,6 +114,7 @@ impl AVFoundationCaptureDevice {
}
}
+#[cfg(target_os = "macos")]
impl CaptureBackendTrait for AVFoundationCaptureDevice {
fn backend(&self) -> ApiBackend {
ApiBackend::AVFoundation
@@ -326,9 +328,155 @@ impl CaptureBackendTrait for AVFoundationCaptureDevice {
}
}
+#[cfg(target_os = "macos")]
impl Drop for AVFoundationCaptureDevice {
fn drop(&mut self) {
if self.stop_stream().is_err() {}
self.device.unlock();
}
}
+
+/// The backend struct that interfaces with V4L2.
+/// To see what this does, please see [`CaptureBackendTrait`].
+/// # Quirks
+/// - While working with `iOS` is allowed, it is not officially supported and may not work.
+/// - You **must** call [`nokhwa_initialize`](crate::nokhwa_initialize) **before** doing anything with `AVFoundation`.
+/// - This only works on 64 bit platforms.
+/// - FPS adjustment does not work.
+/// - If permission has not been granted and you call `init()` it will error.
+#[cfg_attr(feature = "docs-features", doc(cfg(feature = "input-avfoundation")))]
+#[cfg(not(target_os = "macos"))]
+pub struct AVFoundationCaptureDevice {}
+
+#[cfg(not(target_os = "macos"))]
+#[allow(unused_variables)]
+#[allow(unreachable_code)]
+impl AVFoundationCaptureDevice {
+ /// Creates a new capture device using the `AVFoundation` backend. Indexes are gives to devices by the OS, and usually numbered by order of discovery.
+ ///
+ /// If `camera_format` is `None`, it will be spawned with with 640x480@15 FPS, MJPEG [`CameraFormat`] default.
+ /// # Errors
+ /// This function will error if the camera is currently busy or if `AVFoundation` can't read device information, or permission was not given by the user.
+ pub fn new(index: &CameraIndex, req_fmt: RequestedFormat) -> Result {
+ todo!()
+ }
+
+ /// Creates a new capture device using the `AVFoundation` backend with desired settings.
+ ///
+ /// # Errors
+ /// This function will error if the camera is currently busy or if `AVFoundation` can't read device information, or permission was not given by the user.
+ #[deprecated(since = "0.10.0", note = "please use `new` instead.")]
+ #[allow(clippy::cast_possible_truncation)]
+ pub fn new_with(
+ index: usize,
+ width: u32,
+ height: u32,
+ fps: u32,
+ fourcc: FrameFormat,
+ ) -> Result {
+ todo!()
+ }
+}
+
+#[cfg(not(target_os = "macos"))]
+#[allow(unreachable_code)]
+impl CaptureBackendTrait for AVFoundationCaptureDevice {
+ fn backend(&self) -> ApiBackend {
+ todo!()
+ }
+
+ fn camera_info(&self) -> &CameraInfo {
+ todo!()
+ }
+
+ fn refresh_camera_format(&mut self) -> Result<(), NokhwaError> {
+ todo!()
+ }
+
+ fn camera_format(&self) -> CameraFormat {
+ todo!()
+ }
+
+ fn set_camera_format(&mut self, _: CameraFormat) -> Result<(), NokhwaError> {
+ todo!()
+ }
+
+ fn compatible_list_by_resolution(
+ &mut self,
+ _: FrameFormat,
+ ) -> Result>, NokhwaError> {
+ todo!()
+ }
+
+ fn compatible_fourcc(&mut self) -> Result, NokhwaError> {
+ todo!()
+ }
+
+ fn resolution(&self) -> Resolution {
+ todo!()
+ }
+
+ fn set_resolution(&mut self, _: Resolution) -> Result<(), NokhwaError> {
+ todo!()
+ }
+
+ fn frame_rate(&self) -> u32 {
+ todo!()
+ }
+
+ fn set_frame_rate(&mut self, _: u32) -> Result<(), NokhwaError> {
+ todo!()
+ }
+
+ fn frame_format(&self) -> FrameFormat {
+ todo!()
+ }
+
+ fn set_frame_format(&mut self, _: FrameFormat) -> Result<(), NokhwaError> {
+ todo!()
+ }
+
+ fn camera_control(&self, _: KnownCameraControl) -> Result {
+ todo!()
+ }
+
+ fn camera_controls(&self) -> Result, NokhwaError> {
+ todo!()
+ }
+
+ fn set_camera_control(
+ &mut self,
+ _: KnownCameraControl,
+ _: ControlValueSetter,
+ ) -> Result<(), NokhwaError> {
+ todo!()
+ }
+
+ fn open_stream(&mut self) -> Result<(), NokhwaError> {
+ todo!()
+ }
+
+ fn is_stream_open(&self) -> bool {
+ todo!()
+ }
+
+ fn frame(&mut self) -> Result {
+ todo!()
+ }
+
+ fn frame_raw(&mut self) -> Result, NokhwaError> {
+ todo!()
+ }
+
+ fn stop_stream(&mut self) -> Result<(), NokhwaError> {
+ todo!()
+ }
+}
+
+#[cfg(not(target_os = "macos"))]
+#[allow(unreachable_code)]
+impl Drop for AVFoundationCaptureDevice {
+ fn drop(&mut self) {
+ todo!()
+ }
+}
diff --git a/src/backends/capture/browser_backend.rs b/src/backends/capture/browser_backend.rs
index f30f94d..71950c7 100644
--- a/src/backends/capture/browser_backend.rs
+++ b/src/backends/capture/browser_backend.rs
@@ -14,13 +14,17 @@
* limitations under the License.
*/
-use crate::{
- js_camera::JSCameraResizeMode,
- js_camera::{query_js_cameras, JSCameraConstraintsBuilder},
- ApiBackend, CameraControl, CameraFormat, CameraIndex, CameraInfo, CaptureBackendTrait,
- FrameFormat, JSCamera, KnownCameraControl, NokhwaError, Resolution,
-};
+use crate::js_camera::query_js_cameras;
use image::{ImageBuffer, Rgb};
+use nokhwa_core::types::ControlValueSetter;
+use nokhwa_core::{
+ error::NokhwaError,
+ traits::CaptureBackendTrait,
+ types::{
+ ApiBackend, CameraControl, CameraFormat, CameraIndex, CameraInfo, FrameFormat,
+ KnownCameraControl, Resolution,
+ },
+};
use std::{any::Any, borrow::Cow, collections::HashMap};
/// Captures using the Browser API. This internally wraps [`JSCamera`].
@@ -147,6 +151,10 @@ impl CaptureBackendTrait for BrowserCaptureDevice {
&self.info
}
+ fn refresh_camera_format(&mut self) -> Result<(), NokhwaError> {
+ todo!()
+ }
+
fn camera_format(&self) -> CameraFormat {
CameraFormat::new(self.camera.resolution())
}
@@ -214,36 +222,20 @@ impl CaptureBackendTrait for BrowserCaptureDevice {
Ok(())
}
- fn supported_camera_controls(&self) -> Result, NokhwaError> {
- Ok(vec![])
+ fn camera_control(&self, control: KnownCameraControl) -> Result {
+ todo!()
}
- fn camera_control(&self, _: KnownCameraControl) -> Result {
- Err(NokhwaError::NotImplementedError(
- "Not Implemented".to_string(),
- ))
+ fn camera_controls(&self) -> Result, NokhwaError> {
+ todo!()
}
- fn set_camera_control(&mut self, _: CameraControl) -> Result<(), NokhwaError> {
- Err(NokhwaError::NotImplementedError(
- "Not Implemented".to_string(),
- ))
- }
-
- fn raw_supported_camera_controls(&self) -> Result>, NokhwaError> {
- Ok(vec![])
- }
-
- fn raw_camera_control(&self, _: &dyn Any) -> Result, NokhwaError> {
- Err(NokhwaError::NotImplementedError(
- "Not Implemented".to_string(),
- ))
- }
-
- fn set_raw_camera_control(&mut self, _: &dyn Any, _: &dyn Any) -> Result<(), NokhwaError> {
- Err(NokhwaError::NotImplementedError(
- "Not Implemented".to_string(),
- ))
+ fn set_camera_control(
+ &mut self,
+ id: KnownCameraControl,
+ value: ControlValueSetter,
+ ) -> Result<(), NokhwaError> {
+ todo!()
}
fn open_stream(&mut self) -> Result<(), NokhwaError> {
diff --git a/src/camera.rs b/src/camera.rs
index 3ee175e..d8f6684 100644
--- a/src/camera.rs
+++ b/src/camera.rs
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+use nokhwa_core::types::RequestedFormatType;
use nokhwa_core::{
buffer::Buffer,
error::NokhwaError,
@@ -73,7 +74,12 @@ impl Camera {
backend: ApiBackend,
) -> Result {
let camera_format = CameraFormat::new_from(width, height, fourcc, fps);
- Camera::with_backend(index, RequestedFormat::Exact(camera_format), backend)
+ let temp = vec![fourcc];
+ Camera::with_backend(
+ index,
+ RequestedFormat::with_formats(RequestedFormatType::Exact(camera_format), &temp),
+ backend,
+ )
}
/// Gets the current Camera's index.
@@ -90,7 +96,12 @@ impl Camera {
self.device.stop_stream()?;
}
let new_camera_format = self.device.camera_format();
- let new_camera = init_camera(new_idx, RequestedFormat::Exact(new_camera_format), self.api)?;
+ let temp = vec![new_camera_format.format()];
+ let new_camera = init_camera(
+ new_idx,
+ RequestedFormat::with_formats(RequestedFormatType::Exact(new_camera_format), &temp),
+ self.api,
+ )?;
self.device = new_camera;
Ok(())
}
@@ -109,9 +120,10 @@ impl Camera {
self.device.stop_stream()?;
}
let new_camera_format = self.device.camera_format();
+ let temp = vec![new_camera_format.format()];
let new_camera = init_camera(
&self.idx,
- RequestedFormat::Exact(new_camera_format),
+ RequestedFormat::with_formats(RequestedFormatType::Exact(new_camera_format), &temp),
new_backend,
)?;
self.device = new_camera;
diff --git a/src/js_camera.rs b/src/js_camera.rs
index a56c65a..31120cf 100644
--- a/src/js_camera.rs
+++ b/src/js_camera.rs
@@ -21,7 +21,6 @@
//! This assumes that you are running a modern browser on the desktop.
use image::{buffer::ConvertBuffer, ImageBuffer, Rgb, RgbImage, Rgba};
-#[cfg(feature = "output-wasm")]
use js_sys::{Array, JsString, Map, Object, Promise};
use nokhwa_core::{
error::NokhwaError,
@@ -33,11 +32,8 @@ use std::{
fmt::{Debug, Display, Formatter},
ops::Deref,
};
-#[cfg(feature = "output-wasm")]
use wasm_bindgen::{prelude::wasm_bindgen, JsCast, JsValue};
-#[cfg(feature = "output-wasm")]
use wasm_bindgen_futures::JsFuture;
-#[cfg(feature = "output-wasm")]
use web_sys::{
console::log_1, CanvasRenderingContext2d, Document, Element, HtmlCanvasElement,
HtmlVideoElement, ImageData, MediaDeviceInfo, MediaDeviceKind, MediaDevices, MediaStream,
@@ -1679,8 +1675,8 @@ impl Deref for JSCameraConstraints {
/// A wrapper around a [`MediaStream`](https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.MediaStream.html)
/// # JS-WASM
/// This is exported as `NokhwaCamera`.
-#[cfg(feature = "output-wasm")]
-#[cfg_attr(feature = "output-wasm", wasm_bindgen(js_name = NokhwaCamera))]
+#[cfg(feature = "input-jscam")]
+#[cfg_attr(feature = "input-jscam", wasm_bindgen(js_name = NokhwaCamera))]
#[cfg_attr(feature = "docs-features", doc(cfg(feature = "input-jscam")))]
pub struct JSCamera {
media_stream: MediaStream,
diff --git a/src/lib.rs b/src/lib.rs
index 1042a08..6cf50ee 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -52,9 +52,6 @@ pub mod threaded;
pub use backends::capture::NetworkCamera;
pub use camera::Camera;
pub use init::*;
-#[cfg(feature = "input-jscam")]
-#[cfg_attr(feature = "docs-features", doc(cfg(feature = "input-jscam")))]
-pub use js_camera::JSCamera;
pub use nokhwa_core::buffer::Buffer;
pub use nokhwa_core::error::NokhwaError;
pub use query::*;