Skip to content

olkham/pysonycam

Repository files navigation

Sony Camera Control — Python Library

A Pythonic library for controlling Sony cameras over USB using PTP (Picture Transfer Protocol) with Sony's proprietary SDIO extensions.

Built from the Sony Camera Remote Command SDK C/C++ reference implementation, this library provides the same functionality in a clean, easy-to-use Python package.

Features

  • Connect to Sony cameras via USB (auto-detects Sony PTP devices)
  • Authenticate using the Sony SDIO handshake (v2 and v3 protocols)
  • Read all camera properties — exposure mode, ISO, aperture, shutter speed, white balance, battery level, and 50+ more
  • Change settings — set exposure mode, ISO, aperture, shutter speed, white balance, image quality, save media, and more
  • Capture photos — full shutter control with image download to host
  • LiveView streaming — get real-time JPEG preview frames
  • Zoom and focus control — optical zoom in/out, manual focus near/far
  • Movie recording — start/stop video recording
  • Context manager support for safe connection handling
  • Comprehensive enums — human-readable constants for all settings

Requirements

  • Python 3.10+
  • libusb 1.0 — USB backend
  • A Sony camera with USB connection in PC Remote mode

Installation

Quick Install (pip)

pip install -e .

Install directly from GitHub

pip install git+https://github.com/olkham/pysonycam.git

Using the Setup Scripts

Linux / macOS:

chmod +x install.sh
./install.sh

Windows:

install.bat

System Dependencies

Linux (Ubuntu/Debian)

sudo apt install libusb-1.0-0 libusb-1.0-0-dev

To use without root, add a udev rule:

echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="054c", MODE="0666"' | \
  sudo tee /etc/udev/rules.d/99-sony-camera.rules
sudo udevadm control --reload-rules && sudo udevadm trigger

macOS

brew install libusb

Windows

You must replace the camera's driver with WinUSB using Zadig.
Use Zadig v2.7 — newer versions may fail to install the driver. Download v2.7 from here.

  1. Connect your Sony camera and set it to PC Remote mode
  2. Right-click zadig.exeRun as administrator
  3. In Zadig, go to Options → List All Devices
  4. Select your Sony camera from the dropdown (vendor ID 054C)
  5. Set the target driver to WinUSB and click Replace Driver

Note: This replaces the MTP driver. To restore it later:
Device Manager → right-click your camera → Update Driver → Search Automatically

Quick Start

from pysonycam import SonyCamera

# Connect and authenticate
with SonyCamera() as camera:
    camera.authenticate()

    # Read all properties
    props = camera.get_all_properties()
    for code, info in sorted(props.items()):
        print(f"0x{code:04X}: {info}")

Usage Examples

Capture a Photo

from pysonycam import SonyCamera

with SonyCamera() as camera:
    camera.authenticate()
    camera.set_mode("still")
    camera.capture("photo.jpg")

Change Camera Settings

from pysonycam import SonyCamera, ExposureMode, WhiteBalance

with SonyCamera() as camera:
    camera.authenticate()
    camera.set_mode("still")

    # Set to Aperture Priority
    camera.set_exposure_mode(ExposureMode.APERTURE_PRIORITY)

    # Set ISO to 400
    camera.set_iso(0x00000190)

    # Set aperture to F2.8
    camera.set_aperture(0x0118)

    # Set white balance to Daylight
    camera.set_white_balance(WhiteBalance.DAYLIGHT)

LiveView Streaming

from pysonycam import SonyCamera

with SonyCamera() as camera:
    camera.authenticate()
    camera.set_mode("still")

    # Get 100 LiveView frames
    for i, frame in enumerate(camera.liveview_stream(count=100)):
        with open(f"frame_{i:04d}.jpg", "wb") as f:
            f.write(frame)

Zoom Control

import time
from pysonycam import SonyCamera

with SonyCamera() as camera:
    camera.authenticate()
    camera.set_mode("still")

    camera.zoom_in(speed=3)   # speed: 1=slow, 3=medium, 7=fast
    time.sleep(2)
    camera.zoom_stop()

Movie Recording

import time
from pysonycam import SonyCamera

with SonyCamera() as camera:
    camera.authenticate()
    camera.set_mode("movie")

    camera.start_movie()
    time.sleep(10)  # Record for 10 seconds
    camera.stop_movie()

Read a Specific Property

from pysonycam import SonyCamera
from pysonycam.constants import DeviceProperty, ISO_TABLE

with SonyCamera() as camera:
    camera.authenticate()
    camera.set_mode("still")

    info = camera.get_property(DeviceProperty.ISO)
    print(f"ISO: {ISO_TABLE.get(info.current_value, 'Unknown')}")
    print(f"Writable: {info.is_writable}")
    print(f"Supported values: {[ISO_TABLE.get(v) for v in info.supported_values]}")

API Reference

SonyCamera

Method Description
connect() Open USB connection and PTP session
disconnect() Close session and USB connection
authenticate() Perform Sony SDIO authentication handshake
get_all_properties() Read all device properties → dict[int, DevicePropInfo]
get_property(code) Read a single property → DevicePropInfo
set_property(code, value) Write a property value
set_mode(mode) Set operating mode: "still", "movie", "transfer", "standby"
set_exposure_mode(mode) Set exposure mode (M, P, A, S, Auto...)
set_iso(value) Set ISO (use 0x00FFFFFF for AUTO)
set_aperture(code) Set F-number
set_shutter_speed(code) Set shutter speed
set_white_balance(wb) Set white balance mode
set_exposure_compensation(value) Set EV compensation
set_save_media(media) Set save destination (host/camera/both)
capture(path=None) Capture a photo, optionally save to file → bytes
get_liveview_frame() Get one LiveView JPEG frame → bytes
liveview_stream(count) Yield LiveView frames as a generator
zoom_in(speed) / zoom_out(speed) / zoom_stop() Zoom control
focus_near(step) / focus_far(step) Manual focus control
start_movie() / stop_movie() Movie recording control
battery_level (property) Read battery level → DevicePropInfo or None

DevicePropInfo

Returned by get_property() and get_all_properties():

Attribute Type Description
property_code int Property code (hex)
data_type int PTP data type code
is_writable bool True if read-write
is_valid bool True if property is currently valid
current_value int|str|list Current value
default_value int|str|list Factory default value
supported_values list Enumeration of supported values (if applicable)
minimum_value int Min of range (if applicable)
maximum_value int Max of range (if applicable)
step_size int Step size (if applicable)

Constants & Enums

All constants are importable from pysonycam.constants:

  • DeviceProperty — all property codes (EXPOSURE_MODE, ISO, F_NUMBER, etc.)
  • ExposureMode — Manual, Program Auto, Aperture Priority, Shutter Priority, Auto, etc.
  • OperatingMode — Standby, Still Rec, Movie Rec, Contents Transfer
  • WhiteBalance — AWB, Daylight, Cloudy, Tungsten, Flash, Custom, etc.
  • FocusMode — Manual, AF-S, AF-C, AF-Auto, DMF
  • FocusArea — Wide, Zone, Center, Flexible Spot, Lock-On AF
  • ImageSize — Large, Medium, Small
  • JpegQuality — Extra Fine, Fine, Standard, Light
  • FileFormat — RAW, RAW+JPEG, JPEG
  • AspectRatio — 3:2, 16:9, 4:3, 1:1
  • SaveMedia — Host, Camera, Host and Camera
  • SHUTTER_SPEED_TABLE — hex code → human-readable string
  • F_NUMBER_TABLE — hex code → "F2.8" etc.
  • ISO_TABLE — hex code → "100", "200", "AUTO" etc.

Logging

Enable detailed protocol logging:

import logging
logging.basicConfig(level=logging.DEBUG)

Log levels:

  • INFO — connection events, authentication, mode changes
  • DEBUG — every PTP command, response, and data transfer

Project Structure

├── pysonycam/        # Python package
│   ├── __init__.py             # Package exports
│   ├── camera.py               # High-level SonyCamera API
│   ├── ptp.py                  # PTP/USB transport layer
│   ├── parser.py               # Binary protocol parser
│   ├── constants.py            # All opcodes, property codes, enums
│   ├── format.py               # Human-readable value formatting
│   └── exceptions.py           # Custom exception hierarchy
├── examples/                   # Python usage examples
│   ├── README.md               # Full example index with descriptions and dependency notes
│   ├── requirements.txt        # Optional deps for OpenCV-based examples (cv2, numpy)
│   ├── basic_usage.py          # Read and display all device properties
│   ├── capture_photo.py        # Take a single photo
│   ├── burst_capture.py        # Multi-shot burst (pulse S2 per shot)
│   ├── continuous_burst.py     # Hardware-rate continuous burst (hold S2)
│   ├── rapid_fire.py           # Rapid single-shot with full S1→S2 cycle
│   ├── interactive_shutter.py  # Keyboard-driven AF+AE lock and shutter
│   ├── live_viewfinder.py      # OpenCV LiveView window with capture controls
│   ├── change_settings.py      # Read and modify exposure settings
│   ├── zoom_control.py         # Optical zoom in/out
│   ├── advanced_focus.py       # Focus point, magnifier, continuous drive, AF settings
│   ├── astrophotography.py     # Long-exposure, bulb mode, and live astrophotography HUD
│   ├── timelapse.py            # Fixed-interval timelapse with optional video assembly
│   ├── hfr_slow_motion.py      # HFR slow-motion recording (auto-loop or interactive)
│   ├── sq_mode_capture.py      # S&Q movie recording with event confirmation
│   ├── custom_white_balance.py    # Custom WB measurement sequence with event feedback
│   ├── creative_look_recipes.py  # Apply film-simulation recipes (16 built-in looks)
│   ├── browse_and_download.py    # Browse card content, download full or proxy, delete
│   ├── download_videos.py        # Download MP4s via bare PTP / SDIO fallback strategies
│   ├── camera_status.py          # Full diagnostic report (firmware, lens, battery, slots)
│   └── event_listener.py         # Register event callbacks and listen for 30 s
├── CameraRemoteCommadExamples/ # Sony C/C++ SDK reference examples
│   ├── example-v2-linux/       # v2 protocol — Linux (libusb)
│   ├── example-v2-windows/     # v2 protocol — Windows (MFC)
│   ├── example-v3-linux/       # v3 protocol — Linux (libusb)
│   └── example-v3-windows/     # v3 protocol — Windows (MFC)
├── pyproject.toml              # Package metadata & build config
├── requirements.txt            # Dependencies
├── install.sh                  # Linux/macOS setup script
├── install.bat                 # Windows setup script
└── README.md                   # This file

Supported Cameras

This library should work with Sony cameras that support the Camera Remote Command SDK via PTP/USB.

Tested configuration: Windows 11 with a Sony RX100 VII (DSC-RX100M7), using the v3 protocol.
Behaviour on other cameras, operating systems, or protocol versions is untested — feedback welcome.

Supported protocol versions:

  • v2 (SDK version 0x00C8 / 200) — parser support only, not tested on real hardware
  • v3 (SDK version 0x012C / 300) — tested on RX100 VII / Windows 11

To use v2, pass version=0x00C8 when creating the camera:

from pysonycam.constants import SDI_VERSION_V2
camera = SonyCamera(version=SDI_VERSION_V2)

SDIO Protocol Versions: v2 vs v3

The Sony SDIO extension to PTP comes in two versions. This library defaults to v3 — it is both feature-complete and backward-negotiated at connect time. Older cameras that only support v2 will fail the version handshake and you should pass version=SDI_VERSION_V2 explicitly.

Feature v2 (0x00C8) v3 (0x012C)
Enumeration sets Single set of supported values per property Dual enumeration sets — properties can expose a second group of valid values
Storage management Not supported Full storage API: GetStorageID, GetStorageInfo, GetObjectHandles, DeleteObject
Zoom ZOOM_SETTING only Enhanced: ZOOM_SCALE (0xD25C), ZOOM_OPTIC (0xD25D), ZOOM control (0xD2DD)
Focus magnify 8 separate directional commands Single consolidated command (FOCUS_MAGNIFY = 0xD254)
Image format Basic COMPRESSION_SETTING JPEG_QUALITY (0xD252), FILE_FORMAT (0xD253), IMAGE_FILE_FORMAT (0x5004)
Creative controls Not available PICTURE_PROFILE (0xD23F), CREATIVE_STYLE (0xD240)
Focus area Basic modes (Wide, Zone, Center, Flex) Adds FOCUS_AREA_XY (0xD2DC) for coordinate-based placement
Movie format code 0xD219 Changed to 0xD241
Battery BATTERY_CHARGE + BATTERY_LEVEL BATTERY_LEVEL only
Contents transfer mode Not supported SDIOSetContentsTransferMode (0x9212)

Parser differences

The most impactful protocol change is in how Enumeration-Form device property datasets are structured. In v2 each property has a single list of supported values. In v3, every Enumeration-Form property includes a second count field followed by a second list — even if that second list is empty (count = 0). Parsers that don't consume this second block will misalign the byte stream and fail to parse subsequent properties.

Our parser handles this correctly by always reading and consuming the second enumeration block regardless of the negotiated version:

# parse_device_prop_info() in parser.py — excerpt
elif info.form_flag == 2:
    num_values = struct.unpack_from("<H", data, offset)[0]; offset += 2
    for _ in range(num_values):
        val, sz = _read_scalar(data, offset, scalar_dt)
        info.supported_values.append(val)
        offset += sz

    # v3: always has a second enumeration set (may be count=0)
    num_values_2nd = struct.unpack_from("<H", data, offset)[0]; offset += 2
    for _ in range(num_values_2nd):
        val, sz = _read_scalar(data, offset, scalar_dt)
        offset += sz   # consumed but not exposed

Relationship to C/C++ SDK

This Python library is a clean-room reimplementation of the protocol used in Sony's Camera Remote Command SDK examples (located in CameraRemoteCommadExamples/):

  • example-v2-linux/ and example-v3-linux/ — C++ with libusb
  • example-v2-windows/ and example-v3-windows/ — C++ MFC application

The Python version provides the same functionality with a simpler API.

License

MIT License. See LICENSE for details.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages