Skip to content
SJavadPublic

About

Sony VISCA Camera Control Protocol C++ library for controlling every camera uses visca protocol

Resources

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

5 Commits

Folders and files

Repository files navigation

viscalib

A cross-platform C++17 library for controlling Sony VISCA PTZ cameras (zoom, focus, pan/tilt, presets, power, and more) over serial (RS-232) and IP (VISCA-over-IP / UDP), built on Boost.Asio.

#include <visca/visca.hpp>

visca::SerialConfig config;
config.port = "/dev/ttyUSB0";
config.baud_rate = 9600;

auto transport = std::make_shared<visca::SerialTransport>(config);
visca::Camera camera(transport, /*address=*/1);
camera.connect();
camera.power_on();
camera.zoom_tele(4);
camera.preset_recall(2);

Features

  • SerialTransport — RS-232/RS-422 serial control via boost::asio::serial_port.
  • IpTransport — VISCA-over-IP over UDP (port 52381 by default), with the standard 8-byte encapsulation header (payload type, length, sequence number), or raw mode for devices that skip it.
  • Camera — a high-level class with named methods for power, zoom, focus, pan/tilt (including absolute/relative positioning), and presets, which automatically handles VISCA's ACK → Completion → Error reply sequence and throws visca::visca_error with the camera's error code on failure.
  • visca::message — the underlying byte-level frame builder/parser, plus a command()/inquiry() escape hatch so you can send any VISCA command from your camera's command list, not just the ones wrapped by Camera.
  • CMake install step that produces a find_package(viscalib)-ready package (headers + .dll/.so + .lib/.a + CMake config files) on both Windows and Linux, with an optional step to set VISCALIB_ROOT and update PATH/LD_LIBRARY_PATH.

A note on protocol coverage

VISCA has grown a lot of vendor- and model-specific extensions over the years (white balance, iris, gain, backlight compensation, PTZ trace, block inquiries, etc). This library implements the common core — power, zoom, focus, pan/tilt, presets — plus a generic command()/inquiry() call so you can add anything else in a couple of lines, using the byte sequences from your camera's own VISCA command list PDF (Sony publishes one per model/firmware version). VISCA-over-IP framing in particular has minor variations between vendors (Sony, Avonic, BirdDog, PTZOptics, AVer, etc.) — if a camera doesn't respond, that's the first thing worth double-checking.

Requirements

  • CMake ≥ 3.16
  • A C++17 compiler (GCC ≥ 9, Clang ≥ 10, MSVC ≥ 2019)
  • Boost ≥ 1.71 (system component; Asio itself is header-only)

Building

Linux

sudo apt install cmake libboost-dev libboost-system-dev

git clone https://github.com/SJavad/viscalib.git
cd viscalib
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build -j
cmake --install build

By default this installs to ~/.local/viscalib (no sudo needed). Pass -DCMAKE_INSTALL_PREFIX=/usr/local (with sudo cmake --install build) for a system-wide install instead.

Windows

Easiest via vcpkg for Boost:

vcpkg install boost-asio boost-system

git clone https://github.com/SJavad/viscalib.git
cd viscalib
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=C:\path\to\vcpkg\scripts\buildsystems\vcpkg.cmake
cmake --build build --config Release
cmake --install build --config Release

By default this installs to %LOCALAPPDATA%\viscalib.

CMake options

Option Default Description
BUILD_SHARED_LIBS ON Build viscalib as a shared library (.dll/.so) instead of static
VISCALIB_BUILD_EXAMPLES ON Build examples/serial_example.cpp and examples/ip_example.cpp
VISCALIB_SET_ENV_VARS OFF During cmake --install, also set VISCALIB_ROOT and update PATH/LD_LIBRARY_PATH

To have install set environment variables automatically:

cmake -S . -B build -DVISCALIB_SET_ENV_VARS=ON
cmake --build build -j
cmake --install build

On Windows this sets VISCALIB_ROOT and adds <prefix>\bin to PATH for the current user (no admin rights required; pass -Scope Machine to scripts/set_env_windows.ps1 yourself for an all-users install). On Linux it writes ~/.viscalib_env.sh and sources it from ~/.bashrc/~/.zshrc. You can also just run the scripts in scripts/ manually at any time.

Open a new terminal after installing for the environment changes to apply.

Using viscalib from your own CMake project

find_package(viscalib REQUIRED)
target_link_libraries(your_target PRIVATE viscalib::viscalib)

If you installed to a non-default prefix, point CMake at it:

cmake -S . -B build -DCMAKE_PREFIX_PATH=$VISCALIB_ROOT

Usage

Serial

#include <visca/visca.hpp>

visca::SerialConfig config;
config.port = "/dev/ttyUSB0";   // Windows: "COM3"
config.baud_rate = 9600;

auto transport = std::make_shared<visca::SerialTransport>(config);
visca::Camera camera(transport, /*address=*/1);
camera.connect();

camera.power_on();
camera.zoom_tele(4);
camera.zoom_stop();
camera.focus_auto();
camera.pan_tilt(0x08, 0x08, visca::pan_tilt::Right);
camera.pan_tilt_stop();
camera.preset_recall(0);

IP (VISCA-over-IP / UDP)

#include <visca/visca.hpp>

visca::IpConfig config;
config.host = "192.168.1.88";
config.port = 52381;

auto transport = std::make_shared<visca::IpTransport>(config);
visca::Camera camera(transport, /*address=*/1);
camera.connect();
transport->reset_sequence_number();  // recommended once, right after connecting

camera.preset_recall(1);
auto [pan, tilt] = camera.get_pan_tilt_position();

Anything not wrapped by Camera

Look up the bytes in your camera's VISCA command list, and send them directly — no need to touch framing:

// Example: CAM_WB (white balance) Auto = 8x 01 04 35 00 FF
camera.send_command({0x04, 0x35, 0x00});

// Example: CAM_WB inquiry = 8x 09 04 35 FF
auto data = camera.send_inquiry({0x04, 0x35});

Error handling

try {
    camera.zoom_direct(0x4000);
} catch (const visca::visca_error& e) {
    // The camera replied with an error frame (e.g. out-of-range value).
    std::cerr << "VISCA error 0x" << std::hex << int(e.code()) << ": " << e.what() << "\n";
} catch (const visca::transport_timeout& e) {
    // No reply within the configured timeout (default 1500 ms).
    std::cerr << "Timeout: " << e.what() << "\n";
} catch (const visca::transport_error& e) {
    // Serial port / socket problem (port not found, cable unplugged, etc).
    std::cerr << "Transport error: " << e.what() << "\n";
}

License

MIT — see LICENSE.

About

Sony VISCA Camera Control Protocol C++ library for controlling every camera uses visca protocol

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages