1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
[]
= "multimux"
= "0.10.0"
= "2024"
= true
= "MIT OR Apache-2.0"
= "Multi-input (RTSP/RTP/TS-UDP/TS-HTTP/SRT/HLS-pull/DASH-pull/Smooth-pull/RTMP/file), multi-output (LL-HLS/DASH/LL-DASH/Smooth/TS-HLS/catch-up + SRT/RTMP/RTSP push) just-in-time repackaging HTTP origin (library: tokio + axum), with shared output auth and an external scheme plugin registry."
= "https://github.com/fishloa/rust-broadcast"
= ["rtsp", "hls", "ll-hls", "cmaf", "origin"]
= ["multimedia", "network-programming"]
= "README.md"
[]
= true
= ["--cfg", "docsrs"]
[]
# Floor is 0.23.1, not 0.23: `push::rtmp` uses
# `flv_sequence_header_payloads` / `flv_frame_payloads`, which do not
# exist in 0.23.0 (verified at the tag). Published multimux 0.8.0 shipped
# with the understated `"0.23"` bound.
= { = "../transmux", = "0.24" }
= { = "../container-probe", = "0.1" }
# HLS (M3U8) playlist syntax (issue #878): `source::hls_pull` builds/parses
# playlists via this crate directly rather than through `transmux`.
= { = "../broadcast-hls", = "0.2" }
= { = "../rtsp-runtime", = "0.6", = ["tokio"] }
# RTMP push ingest (`source::rtmp`, issue #738): the `tokio` feature pulls
# `rtmp_runtime::io::AsyncRtmpServer`/`RtmpConnection`, the real-socket
# adapter over the sans-IO `ServerSession`.
= { = "../rtmp-runtime", = "0.6", = ["tokio"] }
# SRT push/pull ingest (`source::srt`, issue #739): the `tokio` feature
# pulls `srt_runtime::io::{SrtListener, SrtSocket}`, the real-socket adapter
# over the sans-IO ARQ/TSBPD/handshake engines.
= { = "../srt-runtime", = "0.4", = ["tokio"] }
# The LL-HLS origin engine itself (rolling window/store, blocking-reload +
# part-availability decision logic, playlist rendering — issue #663/#717
# Stage 2). multimux is now a thin tokio+axum adapter over
# `hls_runtime::server`; see `output::llhls`. The `tokio` feature also
# pulls in `hls_runtime::client::tokio_client::TokioClient` — the
# HLS-pull input (`source::hls_pull`, issue #663 P3c) wraps it rather than
# re-implementing LL-HLS playback.
# Floor is 0.6, not 0.5: `catchup.rs` uses `server::ClosedSegment` and
# `HlsOrigin::closed_segments()`, which do not exist in the published
# 0.5.0 (verified: 0 hits at the hls-runtime-v0.5.0 tag). hls-runtime
# must publish 0.6.0 before multimux can publish.
= { = "../hls-runtime", = "0.6", = ["std", "tokio"] }
# Needed directly (not just via hls-runtime/transmux) by `source::hls_pull`
# to recover `TrackSpec`s from a pulled stream's init segment via
# `Fmp4Demux::unpackage` (the `Unpackage` trait) — issue #663 P3c.
# API floor is 9.2, not 9: `output::smooth` uses `hex::hex_encode`, added in
# 9.2.0 (absent at the 9.0.0 and 9.1.0 tags — verified). Published
# multimux 0.8.0 shipped with the understated `"9"` bound, so a lock
# resolving 9.0/9.1 fails to compile it today. The pin below is 9.3, above
# that floor, tracking the current published line; same caret bucket, so it
# is not an epoch change.
= { = "../broadcast-common", = "9.3" }
# The media-plane ingress traits this crate's sources port onto (plan step
# 5a): `Dialer`/`Listener`/`IngestSession`/`IngestDriver`/`ListenDriver`, and
# the `Trunk` every ported session publishes into.
= { = "../media-plane", = "0.4", = ["std"] }
= "1"
# Shared Basic/Digest/Bearer auth model + challenge/response helper
# (`source::http_auth`, issue #663 P3b/P3c) — the same crate `rtsp-runtime`
# and `hls_runtime::client::tokio_client` use.
# Floor is 0.2.1, not 0.2: `config.rs` uses `Verifier::signed_url` /
# `SignedUrlKeySet`, added in 0.2.1 (#747). A `"0.2"` bound admits 0.2.0,
# which lacks them — multimux 0.8.0 shipped with that understated bound and
# fails to compile against a lock that pins 0.2.0 (hit for real while
# bumping acap-multimux).
= { = "../broadcast-auth", = "0.3" }
= "0.1"
= { = "1", = ["rt-multi-thread", "net", "io-util", "macros", "time", "sync", "signal"] }
= "0.7"
# HTTP-layer resource limits (issue #663 P5, audit-concurrency #3): request
# timeout + request-body size cap (`tower-http`) and a concurrency bound
# (`tower::limit`) — see `origin::HttpLimits`/`origin::router`. `util` is
# needed for `tower::ServiceExt::oneshot` in this crate's own axum-router
# tests.
= { = "0.5", = false, = ["timeout", "limit"] }
= { = "0.5", = false, = ["limit", "util"] }
= { = "1", = ["derive"] }
= "1"
= "2"
= "2"
= "2"
= "0.1"
# Push output driver (`push`, issue #744): `#[async_trait]` drives the
# `PushTransport` trait's async methods over the sans-IO `SrtSocket` handle.
= "0.1"
# `tokio_util::sync::CancellationToken` for cooperative cancellation of the
# push loop (`drive_push`).
= { = "0.7", = ["rt"] }
= "0.24"
= { = "0.18", = false }
= { = "0.26", = true }
# `rustls::pki_types::ServerName` for SNI, plus the loopback TLS test server
# (`source::rtsp`'s `rtsps://` connect, issue #804) — pinned to the same
# "0.23" line as `rtsp-runtime`'s own optional `rustls` dep, already resolved
# at that version transitively (via `reqwest`/`hyper-rustls`), so this adds no
# new version to the lock.
= { = "0.23", = true }
# TS-over-HTTP ingest (`source::ts_http`, issue #663 P3c): a streaming GET
# fed straight into `StreamingTsDemux`. `rustls-tls` for consistency with the
# rest of the workspace's TLS backend (rustls/aws-lc-rs); `stream` for
# `Response::bytes_stream()`.
= { = "0.12", = false, = ["rustls-tls", "stream"] }
# `.next()` on `reqwest::Response::bytes_stream()` (a bare `Stream`, no
# extension methods of its own).
= { = "0.3", = false, = ["std"] }
# WHIP input (`source::whip`, issue #740) / WHEP output (`output::whep`,
# issue #743), `whip`/`whep` features only: the ICE + DTLS-SRTP media
# transport this crate has no reason to reimplement.
# Declared as a *plain* optional dep (no extra features) so merely depending
# on it (feature off) never pulls `webrtc-runtime`'s own `media` feature —
# only `multimux`'s `whip`/`whep` features below turn that on. See this
# crate's `rust-version` note on those features for why the split matters.
= { = "../webrtc-runtime", = "0.1", = true, = false }
# WHEP output (`output::whep`, issue #743) only: builds the typed
# `rtp_packet::RtpPacket` values `webrtc_runtime::media::MediaTransport::
# encrypt_rtp` requires — see that method's own signature. Unlike
# `webrtc-runtime`, this crate has no `rtc-dtls` transitive dependency; it
# is kept behind the `whep` feature (rather than unconditional) purely so it
# is never pulled in by a build that never touches WHEP.
= { = "../rtp-packet", = "0.4", = true, = false }
# DVB SI EIT present/following (issue #903, `dvr`): `dvb_si::demux::SiDemux`
# reassembles EIT p/f sections from raw TS packets so `DvrRecorder` can roll
# the archive period on the programme boundary rather than only on the
# clock. `default-features = false` — only `std` (this crate always links
# std) + `ts` (the section reassembler `SiDemux` needs); `chrono`/`serde`
# are not needed since `dvr::EitProgramme` decodes MJD+BCD itself.
= { = "../dvb-si", = "10", = false, = ["std", "ts"] }
# TS packet/PSI-section framing. Two uses: `mpeg_ts::pid::Pid`, which
# `dvr::DvrRecorder::new` wraps the EIT PID (`dvb_si::tables::eit::PID`) in
# to pass to `SiDemux::builder().pid(..)`; and
# `mpeg_ts::mux::SectionPacketiser`, which `dvr`'s own tests use to wrap the
# genuine-bytes transition section back into TS packets. Also still used by
# `source::segment`'s MPTS test (issue #887). Promoted from
# `[dev-dependencies]` because production code (`dvr.rs`) now needs it too.
= { = "../mpeg-ts", = "0.4" }
[]
# `tls` is default-on: `rtsps://` sources should work out of the box. It pulls
# rtsp-runtime's `tls` feature (rustls/webpki-roots via its
# `default_tls_client_config` helper) plus `tokio-rustls` directly, needed here
# only to name the connected stream's concrete type
# (`tokio_rustls::client::TlsStream<TcpStream>`).
= ["tls"]
= ["rtsp-runtime/tls", "dep:tokio-rustls", "dep:rustls"]
# WHIP (RFC 9725) push input (issue #740): accepts an inbound WHIP publisher
# over HTTP + ICE/DTLS-SRTP, via `webrtc_runtime::media::MediaTransport`.
#
# Opt-in rather than `default` because it pulls the whole ICE/DTLS-SRTP
# dependency tree (`rtc-ice`/`rtc-dtls`/`rtc-srtp`/`rcgen`), which a
# deployment serving only HTTP outputs has no reason to build.
#
# This used to carry an MSRV constraint too — `rcgen ^0.14.8` needs rustc
# >= 1.88, while the workspace MSRV was 1.86 — which is why the feature was
# excluded from the `--all-features` lanes and covered by a dedicated CI job.
# The workspace MSRV is now 1.95.0 (issue #949), so that gap is gone and the
# feature is opt-in purely on dependency weight.
= ["dep:webrtc-runtime", "webrtc-runtime/media"]
# WHEP (draft-ietf-wish-whep) egress (issue #743): accepts a viewer's HTTP
# `POST` + SDP offer, negotiates ICE/DTLS-SRTP, and pushes the route's
# `Trunk` samples out as SRTP RTP — the mirror image of `whip` (see
# `crate::output::whep`'s module doc). A *sibling* feature to `whip` rather
# than folded into it: ingest and egress are independently useful (a route
# may want only one), matching this crate's one-feature-per-protocol
# pattern elsewhere (`InputSpec::Whip` vs. a hypothetical output-side
# equivalent). Both enable `webrtc-runtime/media`, so both pull the same
# ICE/DTLS-SRTP dependency tree described on `whip` above.
= ["dep:webrtc-runtime", "webrtc-runtime/media", "dep:rtp-packet"]
[[]]
= "serve_rtsp"
[[]]
= "custom_scheme"
[]
= "0.22"
# Independent RFC 7616 Digest response verification in the mock auth server
# (`testutil`, issue #663 "Finish client-side multi-scheme auth") — the
# `http-auth` crate (this workspace's Digest *client*) has no server-side
# counterpart to reuse, and this is already a transitive dependency of
# `http-auth` at the same version, so this adds no new version to the lock.
= "0.10"
# Adds `reqwest`'s `json` feature (`Response::json`/`RequestBuilder::json`)
# for test-only use (`tests/admin_api.rs`, issue #749) — Cargo unifies this
# into the one `reqwest` dependency only for test builds, never for the
# library target itself.
= { = "0.12", = false, = ["json"] }