Skip to main content

A tool to grab streams from SLDP WebSocket servers and save/mux them

Project description

sldp-grabber

A small tool and Python library to grab streams from SLDP WebSocket servers.

  • Connects to SLDP servers
  • Saves raw H.264, AAC, or Opus
  • Optionally muxes into MP4/MKV using ffmpeg
  • Supports segmenting, reconnects, and live piping to tools like ffplay
  • Exposes a clean SLDPGrabber API for custom processing

Installation

From PyPI:

pip install sldp-grabber

From source:

git clone https://github.com/dgkn94/sldp-grabber.git
cd sldp-grabber
pip install .

Requirements:

  • Python 3.7+

  • websocket-client>=1.3.0

  • ffmpeg in PATH for MP4/MKV muxing (recommended)

  • Optional:

    • ffplay for live preview
    • av (PyAV) for thumbnail/advanced processing examples

Quick Start (CLI)

Basic recording

sldp-grabber \
  --url wss://example.com/app/stream \
  --duration 60
  • Writes video.h264 / audio.aac into recordings/
  • If ffmpeg is available and --no-mux is not set, also creates recording.mp4

Keep only raw streams

sldp-grabber \
  --url wss://example.com/app/stream \
  --duration 30 \
  --no-mux \
  --keep-raw

Segment recording (e.g. 5-minute chunks)

sldp-grabber \
  --url wss://example.com/app/stream \
  --segment-duration 300

Each segment becomes its own raw/set of files and (optionally) MP4/MKV.


Live Preview with ffplay

You can mirror the live stream to another process while still recording.

Example: live H.264 preview while recording:

sldp-grabber \
  --url wss://example.com/app/stream \
  --pipe-h264-cmd "ffplay -fflags nobuffer -flags low_delay -f h264 -i -" \
  --duration 60

What this does:

  • Pipes Annex B H.264 to ffplay via stdin
  • Still writes to disk
  • Still muxes to MP4 if enabled

Same idea works for audio using --pipe-aac-cmd.


Using as a Library

You can import and use SLDPGrabber directly.

Basic usage

from sldp_grabber import SLDPGrabber

grabber = SLDPGrabber(
    url="wss://example.com/app/stream",
    out_dir="recordings",
    duration=30,
)

grabber.run()  # blocks until done

Custom Frame Processing

You can hook into incoming frames using callbacks.

from sldp_grabber import SLDPGrabber

class FrameProcessor:
    def __init__(self):
        self.video_count = 0
        self.audio_count = 0

    def on_video_frame(self, data: bytes, meta: dict):
        # data: Annex B H.264
        self.video_count += 1
        if meta.get("keyframe"):
            print(f"Keyframe at TS={meta.get('timestamp')}")

    def on_audio_frame(self, data: bytes, meta: dict):
        # data: ADTS AAC or raw Opus
        self.audio_count += 1

processor = FrameProcessor()

grabber = SLDPGrabber(
    url="wss://example.com/app/stream",
    out_dir="processed_recordings",
    duration=10,
    on_video_frame=processor.on_video_frame,
    on_audio_frame=processor.on_audio_frame,
)

grabber.run()

print(
    f"Processed {processor.video_count} video frames and "
    f"{processor.audio_count} audio frames"
)

Example: Extract Thumbnails with PyAV

See examples/extract_thumbnails.py for a full script.

import os
import av
from sldp_grabber import SLDPGrabber

class ThumbnailExtractor:
    def __init__(self, out_dir="thumbnails"):
        os.makedirs(out_dir, exist_ok=True)
        self.out_dir = out_dir
        self.count = 0
        self.codec = av.CodecContext.create("h264", "r")

    def on_video_frame(self, data, meta):
        try:
            packet = av.packet.Packet(data)
            frames = self.codec.decode(packet)
        except av.AVError:
            return

        for frame in frames:
            self.count += 1
            path = os.path.join(self.out_dir, f"thumb_{self.count:04d}.jpg")
            frame.to_image().save(path)
            print(f"Saved {path}")

extractor = ThumbnailExtractor()

grabber = SLDPGrabber(
    url="wss://example.com/app/stream",
    out_dir="thumb_recordings",
    duration=10,
    on_video_frame=extractor.on_video_frame,
    keep_raw=False,
)

grabber.run(create_mp4=False)
print(f"Saved {extractor.count} thumbnails")

Requires:

pip install av

CLI Options Overview

Run:

sldp-grabber --help

Key options:

  • -u, --url(required) SLDP WebSocket URL
  • --stream – Specific stream name (if multiple)
  • -d, --duration – Seconds to record (0 = until interrupted)
  • --out-dir – Output directory (default: recordings)
  • --segment-duration – Split into N-second segments
  • --no-mux – Do not run ffmpeg, keep only raw files
  • --keep-raw – Keep .h264 / .aac / .opus after muxing
  • --pipe-h264-cmd – Pipe H.264 to command via stdin
  • --pipe-aac-cmd – Pipe AAC/Opus to command via stdin
  • -H, --header – Extra HTTP headers (auth, cookies, etc.)
  • --header-file – Load headers from file
  • --strict – Fail fast on unsupported codecs
  • --debug-ts – Save timestamps to timestamps.csv
  • -v – Increase verbosity (-v = DEBUG)

Notes

  • Video is handled as H.264 (Annex B) when supported.

  • Audio is handled as AAC (ADTS) or raw Opus packets.

  • Muxing:

    • H.264 + AAC → MP4
    • H.264 + (no AAC) + Opus sidecar → MKV + .opus kept
  • Designed to be simple to script against and easy to extend.

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

sldp_grabber-1.0.0.tar.gz (19.6 kB view details)

Uploaded Source

Built Distribution

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

sldp_grabber-1.0.0-py3-none-any.whl (16.4 kB view details)

Uploaded Python 3

File details

Details for the file sldp_grabber-1.0.0.tar.gz.

File metadata

  • Download URL: sldp_grabber-1.0.0.tar.gz
  • Upload date:
  • Size: 19.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.9

File hashes

Hashes for sldp_grabber-1.0.0.tar.gz
Algorithm Hash digest
SHA256 1d5e24d10aeeff325d0f393bf210625b446a012541d32bab11c91248f7152b5f
MD5 2d099cce4704a097193ae0db1f623fac
BLAKE2b-256 a058845682a3fbbfd2dc333e49be7b8ae6a5cd81bd51f54a512cee6b7f5588e9

See more details on using hashes here.

File details

Details for the file sldp_grabber-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: sldp_grabber-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 16.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.9

File hashes

Hashes for sldp_grabber-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 55c57884a01b84351d1bd0d07a3d872720d24a207e48b8fe67be1c7863ece773
MD5 c004aaf46625e3f5239abb9fdf84c0c1
BLAKE2b-256 96bc1bbcd6c6c78d10e5c49aaac9e745a857d8b6586196c8588ad5a6cada2934

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