Skip to main content

Python library for RTSP streaming from Axis devices

Project description

ax-devil-rtsp

Python 3.10+ License: MIT Type Hints

A Python library for RTSP streaming from Axis cameras with video and AXIS Scene metadata support.

The words 'AXIS Scene Metadata' is hereby called 'application data' in this project.

See also: ax-devil-device-api and ax-devil-mqtt for other Axis device management tools.


📋 Contents


🔍 Feature Overview

Feature Description Python API
🔄 Combined Streaming Simultaneous video and application data streaming (default) RtspDataRetriever
📹 Video Only Stream video frames without application data RtspVideoDataRetriever
📊 Application Data (AXIS Scene Metadata) Only Stream scene application data without video RtspApplicationDataRetriever
⚡ Real-time Processing Frame-by-frame processing with custom callbacks on_video_data
🎯 RTP Extension Data Access to ONVIF RTP extension data and timing information (enabled by default) rtp_ext=True
🛠️ Axis URL Builder Utility for constructing Axis-compatible RTSP URLs build_axis_rtsp_url

📦 Installation

pip install ax-devil-rtsp

System Dependencies

On Linux, this library requires system packages for PyGObject and GStreamer. If they're missing, you'll see clear error messages with installation instructions.

Quick setup (Ubuntu/Debian):

# Check what's missing
python tools/dep.py --check

# Get installation commands
python tools/dep.py --install

🚀 Quick Start

Python API

from ax_devil_rtsp import RtspDataRetriever, build_axis_rtsp_url
from multiprocessing import freeze_support
import time

# Define callback functions
def on_video_data(payload):
    frame = payload["data"]
    diagnostics = payload["diagnostics"]
    print(f"Video frame: {frame.shape}, {diagnostics}")

def on_application_data(payload):
    xml_data = payload["data"]
    diagnostics = payload["diagnostics"]
    print(f"Application data: {len(xml_data)} bytes, {diagnostics}")

def on_session_start(payload):
    # Called once per RTP pad (e.g. video + application metadata).
    caps_media = payload.get("caps_parsed", {}).get("media")
    structure_media = payload.get("structure_parsed", {}).get("media")
    media = caps_media or structure_media
    print(f"Session start for media={media!r}: {payload['stream_name']}")

def on_error(payload):
    print(f"Error: {payload['message']}")

def main():
    # Build the RTSP URL or supply one directly
    # rtsp_url = "rtsp://username:password@192.168.1.90/axis-media/media.amp?analytics=polygon"
    rtsp_url = build_axis_rtsp_url(
        ip="192.168.1.90",
        username="username",
        password="password",
        video_source=1,
        get_video_data=True,
        get_application_data=True,
        rtp_ext=True,  # Enable RTP extension data
        resolution="640x480",
    )

    retriever = RtspDataRetriever(
        rtsp_url=rtsp_url,
        on_video_data=on_video_data,
        on_application_data=on_application_data,
        on_session_start=on_session_start,
        on_error=on_error,
        latency=100,
    )

    # Use context manager for automatic cleanup
    with retriever:
        print("Streaming... Press Ctrl+C to stop")
        while True:
            time.sleep(0.1)

# Expect `on_session_start` to run once for each RTP pad (typically
# one for video and one for application metadata). Use the parsed
# `media` field to tell them apart, as shown above.

if __name__ == "__main__":
    freeze_support()  # Needed on Windows when multiprocessing start method is 'spawn'
    main()

Note

Because ax-devil-rtsp forces the multiprocessing start method to 'spawn', your script's entry point must be guarded with if __name__ == "__main__": (as shown above). On Windows also call multiprocessing.freeze_support() before starting the retriever.

Video-only and application-data-only

from ax_devil_rtsp import (
    RtspVideoDataRetriever,
    RtspApplicationDataRetriever,
    build_axis_rtsp_url,
)

# Video-only
video_url = build_axis_rtsp_url(
    ip="192.168.1.90",
    username="username",
    password="password",
    video_source=1,
    get_video_data=True,
    get_application_data=False,
    rtp_ext=True,
)
with RtspVideoDataRetriever(
    rtsp_url=video_url,
    on_video_data=lambda p: print(p["diagnostics"]),
):
    ...

# Application data only
app_url = build_axis_rtsp_url(
    ip="192.168.1.90",
    username="username",
    password="password",
    video_source=1,
    get_video_data=False,
    get_application_data=True,
    rtp_ext=True,
)
with RtspApplicationDataRetriever(
    rtsp_url=app_url,
    on_application_data=lambda p: print(len(p["data"]))
):
    ...

### CLI Usage

The CLI offers two subcommands:

- `device` builds the RTSP URL from device details like IP address and
  credentials.
- `url` is for when you already have a complete RTSP URL. Options that modify
  the URL (for example `--resolution` or `--rtp-ext`) are only valid with the
  `device` command.

**Basic Usage (streams both video and application data):**
```bash
ax-devil-rtsp device --device-ip 192.168.1.90 --device-username admin --device-password secret
# or shorthand: ax-devil-rtsp device -a 192.168.1.90 -u admin -p secret

Using a complete RTSP URL:

ax-devil-rtsp url "rtsp://admin:secret@192.168.1.90/axis-media/media.amp?analytics=polygon"

Common Options:

# Custom resolution
ax-devil-rtsp device --device-ip 192.168.1.90 --device-username admin --device-password secret \
  --resolution 1280x720

# Different camera source
ax-devil-rtsp device --device-ip 192.168.1.90 --device-username admin --device-password secret --source 2

Specialized Modes:

# Video only (no application data overlay)
ax-devil-rtsp device --device-ip 192.168.1.90 --device-username admin --device-password secret --only-video

# Application data only (no video window)
ax-devil-rtsp device --device-ip 192.168.1.90 --device-username admin --device-password secret --only-application-data

# Disable RTP extension data
ax-devil-rtsp device --device-ip 192.168.1.90 --device-username admin --device-password secret --no-rtp-ext

For demo processing and lifecycle control, see: --enable-video-processing, --brightness-adjustment, and --manual-lifecycle (run ax-devil-rtsp device --help).

Environment Variables (Optional)

export AX_DEVIL_TARGET_ADDR=192.168.1.90
export AX_DEVIL_TARGET_USER=admin
export AX_DEVIL_TARGET_PASS=secret
export AX_DEVIL_USAGE_CLI=safe  # Set to "unsafe" to skip SSL verification

Set these variables to avoid passing --device-ip, --device-username, or --device-password each time you invoke the device command. AX_DEVIL_USAGE_CLI is shared with related ax-devil-* tools and kept here for consistency.


🧪 Testing

# Unit tests
pytest tests/unit/ -v

# Integration tests (local test servers)
pytest tests/integration/ -v

# Integration tests (real camera)
USE_REAL_CAMERA=true AX_DEVIL_TARGET_ADDR=192.168.1.90 pytest tests/integration/ -v

Note on GI/GStreamer

On Linux, PyGObject and GStreamer are system packages. Install them with your distro package manager before using this library (see Development Setup below). If they are missing, the library will show an error with install instructions.

Python Environment

python3 -m venv .venv
source .venv/bin/activate
pip install -e .[dev]

Helper Scripts

  • tools/dep.py: Unified dependency management tool
    • Check dependencies: python tools/dep.py --check
    • Get install commands (Ubuntu/Debian): python tools/dep.py --install

📄 License

MIT License - See LICENSE file for details.


⚠️ Disclaimer

This project is independent and not affiliated with Axis Communications AB. For official resources, visit Axis developer documentation.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ax_devil_rtsp-0.2.0.tar.gz (38.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ax_devil_rtsp-0.2.0-py3-none-any.whl (41.9 kB view details)

Uploaded Python 3

File details

Details for the file ax_devil_rtsp-0.2.0.tar.gz.

File metadata

  • Download URL: ax_devil_rtsp-0.2.0.tar.gz
  • Upload date:
  • Size: 38.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for ax_devil_rtsp-0.2.0.tar.gz
Algorithm Hash digest
SHA256 c26bb73e34df1abacc296b26df212aa6b1bfd0157596047b9eca78d454425070
MD5 e647afac9eda173fbdb75a2144056e88
BLAKE2b-256 d173917f33b592bacb8215b87cd332c0efdcf6baf892ac18f6c882dc26084cb8

See more details on using hashes here.

File details

Details for the file ax_devil_rtsp-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: ax_devil_rtsp-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 41.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.14

File hashes

Hashes for ax_devil_rtsp-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 169c61f12fcea9a16896b48e347df7215fa5a622d61e4c5558980bcc3789cc1b
MD5 8cf814757712de900fd3bc3af30910ed
BLAKE2b-256 eafe6e11c2956e381b4209bf0f2fdec339cb1a528beac8e7307b6963ba050920

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page