Skip to main content

MPEG-TS video + MISB KLV streaming — mux/demux, typed KLV (ST 0601/0102/0605/0903), codec parsers, and live SRT/RTP/UDP/TCP/RIST transports

Project description

tstrans

Python bindings (via PyO3) for the ts-transformer Rust workspace.

Status: tstrans covers file inspection + construction (Demuxer / Muxer / MuxerFileSink), typed KLV decode + encode for ST 0601 / ST 0102 / ST 0605 / ST 0903 (with VTargetPack), codec parsers for H.264 / H.265 / H.266 / AV1 / AAC / MPEG-2 audio, optional pandas DataFrame adapters + NumPy snapshot views via pip install tstrans[pandas], and live transports: SRT (tstrans.srt — Sender / Receiver / Builder / Socket / Listener / MuxSender / DemuxReceiver + Managed* auto-reconnect + ReconnectPolicy), RTP + RTSP (tstrans.rtp — Sender / Receiver / MuxSender / DemuxReceiver / RtspClient / RtspServer / MountHandle), and raw UDP / TCP / RIST (tstrans.udp / tstrans.tcp / tstrans.rist). 1,149 pytest tests. Minimum Python 3.10.

Install

pip install tstrans

Optional extras for DataFrame / NumPy integration:

pip install 'tstrans[pandas]'

Quickstart

Inspect a .ts file:

from tstrans.io import parse_file, probe
from tstrans.mpegts import DemuxEvent

# Quick summary
r = probe("capture.ts")
print(r.video_codecs, r.audio_codecs, r.has_klv)

# Full event stream
for event in parse_file("capture.ts"):
    match event:
        case DemuxEvent.Video(pts=p, codec=c, payload=b):
            print(f"Video {c.name} pts={p.ms}ms len={len(b)}")
        case DemuxEvent.Klv(pts=p, payload=b):
            print(f"KLV pts={p.ms}ms len={len(b)}")

Build a .ts file (single-program H.264):

from tstrans.mpegts import (
    Muxer,
    MuxerConfigBuilder,
    MuxerProgramConfigBuilder,
    Pts90khz,
    VideoCodec,
)

prog = (
    MuxerProgramConfigBuilder(program_number=1, pmt_pid=0x100)
    .add_video(0x101, VideoCodec.H264)
    .build()
)
cfg = MuxerConfigBuilder().add_program(prog).build()
m = Muxer(cfg)

with m.write_file("out.ts") as proxy:
    proxy.push_video(nal_bytes, Pts90khz.from_raw(900_000))

RTP + RTSP transport

tstrans.rtp ships RTP-over-UDP and a full RTSP client + server. Available by default in published wheels — no extra needed (pip install tstrans already includes it). The Rust-side rtp cargo feature is on by default; source builds that don't need it can opt out with maturin develop --no-default-features for a smaller binary.

Connect to a camera and iterate demuxed events:

from tstrans.rtp import RtspClient, RtspClientConfig
from tstrans.mpegts import DemuxEvent

cfg = RtspClientConfig(url="rtsp://camera.local/live")
with RtspClient.connect(cfg) as session:
    demux = session.into_demux_receiver()
    for event in demux:
        if isinstance(event, DemuxEvent.Video):
            handle(event.payload)

Publish a stream from your own RTSP server:

from tstrans.rtp import RtspServer, RtspServerConfig
from tstrans.mpegts import MuxerProgramConfigBuilder, Pts90khz, VideoCodec

program = (
    MuxerProgramConfigBuilder(1, 0x100)
    .add_video(0x101, VideoCodec.H264)
    .build()
)
with RtspServer.start(RtspServerConfig(bind_addr="0.0.0.0:8554")) as server:
    mount = server.add_unicast_mount("/live", program)
    mount.push_video(nal_bytes, pts=Pts90khz.from_raw(0), key_frame=True)

The full surface — Sender / Receiver for raw RTP, MuxSender / DemuxReceiver for one-call mux/demux convenience, RtspClient / RtspSession with Basic + Digest auth and TCP-interleaved fallback, RtspServer + MountHandle with 16 push methods and multicast mounts — is documented in the per-class docstrings and the python/tstrans/rtp.pyi type stubs (mypy --strict clean).

SRT transport

tstrans.srt ships full SRT (Secure Reliable Transport) bindings on top of libsrt 1.5.5 — 18 PyClasses spanning low-level Builder / Socket / Listener primitives, high-level Sender / Receiver for raw bytes, MuxSender / DemuxReceiver for one-call mux/demux convenience, and ManagedSender / ManagedReceiver / ManagedMuxSender / ManagedDemuxReceiver for auto-reconnect-with-gap-buffer ergonomics. Available by default in published wheels — no extra needed (pip install tstrans already includes it). The Rust-side srt cargo feature is on by default; source builds that don't need SRT can opt out with maturin develop --no-default-features for a smaller binary that drops the libsrt + mbedTLS link.

Hello world — caller-side send + listener-side receive:

import threading
import tstrans.srt

# Listener side (run on one host / thread):
def listen_side() -> None:
    with tstrans.srt.Receiver.from_url("srt://0.0.0.0:9000?mode=listener") as rx:
        chunk = rx.recv_bytes(max_len=1500)
        print(f"received {len(chunk)} bytes; sync byte = {chunk[0]:#04x}")

threading.Thread(target=listen_side, daemon=True).start()

# Caller side (the other host / thread):
with tstrans.srt.Sender.from_url("srt://127.0.0.1:9000?mode=caller") as tx:
    payload = (b"\x47" + b"\x00" * 187) * 7  # one 1316-byte TS bundle
    tx.send_bytes(payload)

Full mux + demux example — push H.264 NALs + KLV blobs from the caller, iterate DemuxEvents on the listener:

import threading
import tstrans.srt
from tstrans.mpegts import (
    DemuxEvent, KlvStreamType, MuxerProgramConfigBuilder, Pts90khz, VideoCodec,
)

program = (
    MuxerProgramConfigBuilder(program_number=1, pmt_pid=0x100)
    .add_video(0x101, VideoCodec.H264)
    .add_klv(0x102, KlvStreamType.SYNCHRONOUS_METADATA, carries_pts=True)
    .build()
)

def consumer() -> None:
    with tstrans.srt.DemuxReceiver.from_url("srt://:9001?mode=listener") as rx:
        for event in rx:
            if isinstance(event, DemuxEvent.Video):
                print(f"video pts={event.pts.ms}ms nals={len(event.payload)}")
            elif isinstance(event, DemuxEvent.Klv):
                print(f"klv pts={event.pts.ms}ms len={event.byte_len}")

threading.Thread(target=consumer, daemon=True).start()

with tstrans.srt.MuxSender.from_url(
    "srt://127.0.0.1:9001?mode=caller", program
) as tx:
    # tx.push_video / tx.push_klv handle bundling, PSI emission, and
    # ts-packet framing transparently.
    tx.push_video(nal_bytes, pts=Pts90khz.from_raw(0), key_frame=True)
    tx.push_klv(klv_ls_bytes, pts=Pts90khz.from_raw(0))

Builder + Socket promotion for fine-grained control (passphrase, custom latency, stream id, congestion mode):

import tstrans.srt

# Caller side with encryption + a custom SRT latency.
sock = (
    tstrans.srt.Builder("srt://127.0.0.1:9000?mode=caller")
    .passphrase("hunter-too-long-thanks!!")  # >= 10 chars
    .latency_ms(200)
    .stream_id("cam-01")
    .caller()
    .connect()
)
sender = sock.into_sender()  # consumes the Socket
sender.send_bytes(b"...")
sender.close()

Auto-reconnect with ManagedReceiver — wraps the underlying SRT transport in a tst_pipeline::ManagedRecvTransport that catches connection breaks, reconnects per a ReconnectPolicy, and surfaces a DemuxEvent.ReconnectDiscontinuity to the consumer:

import tstrans.srt
from tstrans.srt import BackoffStrategy, ReconnectPolicy

policy = ReconnectPolicy(
    max_attempts=5,
    backoff=BackoffStrategy.exponential(base_ms=100, max_ms=10_000),
)

with tstrans.srt.ManagedReceiver.from_url(
    "srt://:9000?mode=listener", policy=policy
) as rx:
    while True:
        try:
            chunk = rx.recv_bytes(max_len=1500)
            print(f"received {len(chunk)} bytes; "
                  f"reconnects so far = {rx.reconnect_attempts()}")
        except KeyboardInterrupt:
            break

The full surface — Sender / Receiver for raw bytes, MuxSender / DemuxReceiver for one-call mux/demux, Builder / Socket / Listener for low-level construction, ManagedSender / ManagedReceiver / ManagedMuxSender / ManagedDemuxReceiver for auto-reconnect, plus ReconnectPolicy / BackoffStrategy / OverflowPolicy policy types and SocketStats / SrtStats / CancelHandle — is documented in the per-class docstrings and the python/tstrans/srt.pyi type stubs (mypy --strict clean).

See also docs/languages/python.md for the broader Python binding guide.

See also

See docs/languages/python.md for the full guide and docs/languages/python.md for the DataFrame / NumPy integration.

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

tstrans-0.2.0.tar.gz (2.5 MB view details)

Uploaded Source

Built Distributions

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

tstrans-0.2.0-cp310-abi3-win_amd64.whl (2.3 MB view details)

Uploaded CPython 3.10+Windows x86-64

tstrans-0.2.0-cp310-abi3-manylinux_2_28_x86_64.whl (2.4 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ x86-64

tstrans-0.2.0-cp310-abi3-manylinux_2_28_aarch64.whl (2.3 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ ARM64

tstrans-0.2.0-cp310-abi3-macosx_11_0_arm64.whl (1.9 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: tstrans-0.2.0.tar.gz
  • Upload date:
  • Size: 2.5 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tstrans-0.2.0.tar.gz
Algorithm Hash digest
SHA256 603782aca773a24ff3ff79b79504f43b0c060f9a12458dc49ffa51c3b3134169
MD5 1699a8a092249f6b23fb9c5585c4945f
BLAKE2b-256 fd152baed59125e7b9b5bd121787fe2d31b09ad6235aa924b177fa5afab3acfb

See more details on using hashes here.

Provenance

The following attestation bundles were made for tstrans-0.2.0.tar.gz:

Publisher: python-wheels.yml on aklofas/ts-transformer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tstrans-0.2.0-cp310-abi3-win_amd64.whl.

File metadata

  • Download URL: tstrans-0.2.0-cp310-abi3-win_amd64.whl
  • Upload date:
  • Size: 2.3 MB
  • Tags: CPython 3.10+, Windows x86-64
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for tstrans-0.2.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 7db3462d8495f0946a058765116ff558e86168aad03e964c72975781a7505671
MD5 4978c1a6cc00a0719b218586327b4bc9
BLAKE2b-256 3746e34cb2b530792ff5bc3d9e6b8e9fef1312ab4209bfd818f47a8798f2f516

See more details on using hashes here.

Provenance

The following attestation bundles were made for tstrans-0.2.0-cp310-abi3-win_amd64.whl:

Publisher: python-wheels.yml on aklofas/ts-transformer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tstrans-0.2.0-cp310-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for tstrans-0.2.0-cp310-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 dc7a567e62247fd35e2cebf1d5dadd6fe791e32ffa3aaa7f32bcf8dc7d487147
MD5 2133855e0ae651146b2271f5b8fad4e7
BLAKE2b-256 91cd53f07d1c2e90d3ca20ad52ac1d6cd8ebbae8eb78bf0016f3d399b10413b5

See more details on using hashes here.

Provenance

The following attestation bundles were made for tstrans-0.2.0-cp310-abi3-manylinux_2_28_x86_64.whl:

Publisher: python-wheels.yml on aklofas/ts-transformer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tstrans-0.2.0-cp310-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for tstrans-0.2.0-cp310-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 2f9174d841a3c5b52e0cc023090526c5dbbf49c31c3032025f274a5f7564e548
MD5 ead6b3fb197e740194162ae42fa4989c
BLAKE2b-256 ece467cd08b8e2d909c42d3bf901f60ee08750b509b5f120e30d56a554e1d616

See more details on using hashes here.

Provenance

The following attestation bundles were made for tstrans-0.2.0-cp310-abi3-manylinux_2_28_aarch64.whl:

Publisher: python-wheels.yml on aklofas/ts-transformer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file tstrans-0.2.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tstrans-0.2.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 a6dd2eedab2e8612d0a9dc4f242e0d79c166402d4bb75123bd13f48a5941b61c
MD5 3d40b8920b53344bcedba6349d4d85d3
BLAKE2b-256 7a39f49ac7f5e535e0f116f44bce5d1063f3ed47b1b37d203413b7232634a675

See more details on using hashes here.

Provenance

The following attestation bundles were made for tstrans-0.2.0-cp310-abi3-macosx_11_0_arm64.whl:

Publisher: python-wheels.yml on aklofas/ts-transformer

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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