| Crates.io | grafton-visca |
| lib.rs | grafton-visca |
| version | 0.10.0 |
| created_at | 2024-08-12 06:22:40.973081+00 |
| updated_at | 2025-12-24 16:46:43.52112+00 |
| description | Rust based VISCA over IP implementation for controlling PTZ Cameras |
| homepage | https://www.grafton.ai |
| repository | https://github.com/GrantSparks/grafton-visca |
| max_upload_size | |
| id | 1333997 |
| size | 3,335,159 |
A pure Rust library for controlling PTZ cameras via the VISCA protocol. Supports blocking and async APIs with pluggable runtime adapters (Tokio, async-std, smol), TCP/UDP/serial transports, and type-safe camera profiles.
This crate is in pre-release (< 1.0.0). Breaking changes may occur until version 1.0.0.
Tested: PTZOptics cameras G2 and G3 series over TCP and UDP.
Experimental: Other VISCA cameras, Sony encapsulation profiles, serial transport
We can only support what we can test. If you have access to different hardware, please report issues or submit pull requests.
Camera type works in both modes; async futures are Send-safeDegrees, Percentage), built-in inquiry conversionsuse grafton_visca::camera::Connect;
use grafton_visca::profiles::PtzOpticsG2;
fn main() -> Result<(), grafton_visca::Error> {
let mut cam = Connect::open_tcp_blocking::<PtzOpticsG2>("192.168.0.110")?;
cam.power_on()?;
cam.pan_tilt_home()?;
let pos = cam.pan_tilt_position()?;
let (pan, tilt) = pos.as_degrees();
println!("Position: {:.1}°, {:.1}°", pan.0, tilt.0);
cam.close()
}
use grafton_visca::camera::Connect;
use grafton_visca::profiles::PtzOpticsG2;
use grafton_visca::runtime::TokioRuntime;
#[tokio::main]
async fn main() -> Result<(), grafton_visca::Error> {
let runtime = TokioRuntime::from_current()?;
let cam = Connect::open_tcp_async::<PtzOpticsG2, _>("192.168.0.110", runtime).await?;
cam.power().on().await?;
cam.pan_tilt().home().await?;
let pos = cam.inquiry().pan_tilt_position().await?;
let (pan, tilt) = pos.as_degrees();
println!("Position: {:.1}°, {:.1}°", pan.0, tilt.0);
cam.close().await
}
For async-std or smol, enable the corresponding feature and use its runtime adapter.
[dependencies]
grafton-visca = "0.10"
# Async with Tokio
grafton-visca = { version = "0.10", features = ["runtime-tokio"] }
tokio = { version = "1", features = ["full"] }
# With serialization
grafton-visca = { version = "0.10", features = ["serde"] }
# Serial transport (blocking)
grafton-visca = { version = "0.10", features = ["transport-serial"] }
| Feature | Enables |
|---|---|
runtime-tokio |
Tokio async runtime adapter |
runtime-async-std |
async-std runtime adapter |
runtime-smol |
smol runtime adapter |
transport-serial |
Blocking serial (RS-232/422) |
transport-serial-tokio |
Async serial (Tokio) |
serde |
Serialize/Deserialize for all types |
schemars |
JSON Schema generation |
ts-rs |
TypeScript type generation |
dyn-api |
Object-safe camera traits |
Profiles define protocol format and default ports:
| Profile | Protocol | TCP Port | UDP Port |
|---|---|---|---|
GenericVisca |
Raw VISCA | 5678 | 1259 |
PtzOpticsG2/G3 |
Raw VISCA | 5678 | 1259 |
SonyBRC300 |
Raw VISCA | 5678 | 1259 |
SonyBRCH900 |
Sony encapsulation | 52381 | 52381 |
SonyFR7 |
Sony encapsulation | 52381 | 52381 |
Port can be omitted in connection strings; the profile default is used.
| Example | Command |
|---|---|
| Blocking quickstart | cargo run --example quickstart |
| Async inquiry (Tokio) | cargo run --example inquiry_quickstart --features runtime-tokio |
| Builder API | cargo run --example builder_api |
| Error handling | cargo run --example error_handling --features runtime-tokio |
| Serial (async) | cargo run --example serial_async_demo --features runtime-tokio,transport-serial-tokio |
Contributions welcome! See CONTRIBUTING.md for guidelines.
Dual-licensed under Apache 2.0 or MIT at your option.