Identifies one outbound track before/after negotiation. str0m’s own
[Mid] doesn’t exist until the SDP exchange that creates it completes,
so this is a stable handle usable from the moment
super::track::WebRtcHandle::add_track returns.
Cheaply-cloneable handle for requesting new tracks, completing
renegotiation, and picking up newly-attached tracks — same spirit as
crate::elements::AppSourceHandle. Cloning shares one queue of
pending WebRtcHandle::next_track results, same as any other
multi-consumer channel — only one clone’s call actually receives a
given track, so in practice only one place in the app should be
draining it.
One outbound track. A plain Sink — no bespoke push API, it links
into a crate::pipeline::ChainBuilder exactly like
crate::elements::RtspSink or any other terminal sink.
consume() only ever hands off to WebRtcPeer::run’s own thread via a
channel send; the actual str0m write happens over there.
One inbound track — the mirror image of WebRtcTrackSink. A plain
SourceElement, same shape as crate::elements::AppSource: it
links into its own crate::pipeline::Pipeline via src_pads() like
any other source. The difference from AppSource is only who feeds
it — instead of an crate::elements::AppSourceHandle the app calls
itself, crate::driver::Driver::run pushes into the sending half of this same
channel internally, from its own thread, for every Event::MediaData
on this track’s Mid. Nothing here ever calls back into caller-supplied
code from WebRtcPeer::run’s own thread — that thread only ever touches
this crate’s own types (see the module docs for why WebRtcPeer hands
tracks out through WebRtcHandle::next_track instead of a callback).