Skip to main content

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.Metadata(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.6 — 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.Metadata):
                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.

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.5.0.tar.gz (6.7 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.5.0-cp310-abi3-win_amd64.whl (3.6 MB view details)

Uploaded CPython 3.10+Windows x86-64

tstrans-0.5.0-cp310-abi3-manylinux_2_28_x86_64.whl (3.8 MB view details)

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

tstrans-0.5.0-cp310-abi3-manylinux_2_28_aarch64.whl (3.6 MB view details)

Uploaded CPython 3.10+manylinux: glibc 2.28+ ARM64

tstrans-0.5.0-cp310-abi3-macosx_11_0_arm64.whl (3.1 MB view details)

Uploaded CPython 3.10+macOS 11.0+ ARM64

File details

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

File metadata

  • Download URL: tstrans-0.5.0.tar.gz
  • Upload date:
  • Size: 6.7 MB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for tstrans-0.5.0.tar.gz
Algorithm Hash digest
SHA256 c87557afb5cc0e3b80d6ba4169a16b591e2688ad4096e5862d94559ac28cdeb3
MD5 9c2ead39fb7e6f8ed41384ccdf0883c4
BLAKE2b-256 6ac9601121d3de59d13c0941e816abf92cd33bd691d2822f6bff4c6b4616c918

See more details on using hashes here.

Provenance

The following attestation bundles were made for tstrans-0.5.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.5.0-cp310-abi3-win_amd64.whl.

File metadata

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

File hashes

Hashes for tstrans-0.5.0-cp310-abi3-win_amd64.whl
Algorithm Hash digest
SHA256 c00d7ee711bb06c7aa4a38861d2433bfe8f27a976769dd29daf2ab2b38a2cdd3
MD5 358ef81635935912fb0b1bcc9d4ff82b
BLAKE2b-256 d1e369e36aef15939aa42cc85ac20bee31c7aae3dff5c12199573d33040d4320

See more details on using hashes here.

Provenance

The following attestation bundles were made for tstrans-0.5.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.5.0-cp310-abi3-manylinux_2_28_x86_64.whl.

File metadata

File hashes

Hashes for tstrans-0.5.0-cp310-abi3-manylinux_2_28_x86_64.whl
Algorithm Hash digest
SHA256 838a8bfc3bc19c9dd7925a9693ed34b252464ca5696f78b0cdfec93a51e711a1
MD5 25efa66d940e660bd60de16aad65cd56
BLAKE2b-256 a34e15e2283ada48e234920f4283bc5abaeb3916ac026218cb0aafc9f896bfd1

See more details on using hashes here.

Provenance

The following attestation bundles were made for tstrans-0.5.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.5.0-cp310-abi3-manylinux_2_28_aarch64.whl.

File metadata

File hashes

Hashes for tstrans-0.5.0-cp310-abi3-manylinux_2_28_aarch64.whl
Algorithm Hash digest
SHA256 bfbdfa9f542abb78c7ea5d0078ad1ed806d53eae1429bfb4d308b2c792e48926
MD5 87cad11561e2d8134035922ee4b84f79
BLAKE2b-256 8660e353ceb0abe23deb2722b2fc22365d7b85a2553a8f48c7a21fddb93d6d99

See more details on using hashes here.

Provenance

The following attestation bundles were made for tstrans-0.5.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.5.0-cp310-abi3-macosx_11_0_arm64.whl.

File metadata

File hashes

Hashes for tstrans-0.5.0-cp310-abi3-macosx_11_0_arm64.whl
Algorithm Hash digest
SHA256 2fc0559cd781cdd4d2b1c59b0a1bb5648bab10d948376c4f12f3f6afb8d16fa2
MD5 0bae9c8f4668f400a262a3f448442ff5
BLAKE2b-256 792febd50529134a4549137da54c7b6ea854f8a4bf05959bea8ce5d1118bfc45

See more details on using hashes here.

Provenance

The following attestation bundles were made for tstrans-0.5.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.

Release history Release notifications | RSS feed

0.5.1

5 files

This release

0.5.0 This release

5 files

0.4.0

5 files

0.3.0

5 files

0.2.0

5 files

Supported by

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