pub struct MediaPort { /* private fields */ }Expand description
A bound media port that is not yet carrying anything.
This exists because of an ordering constraint in offer/answer: an SDP offer has to name the port audio will arrive on, but the codec and the far end’s address are not known until the answer comes back. So the socket is bound first, its port goes into the offer, and the session starts once there is something to start it with.
Binding twice instead — once to learn the port, once to start — fails with “address already in use”, which is how this type came to exist.
Implementations§
Source§impl MediaPort
impl MediaPort
Sourcepub async fn bind(bind: SocketAddr) -> Result<Self>
pub async fn bind(bind: SocketAddr) -> Result<Self>
Bind a port, and the control port above it. Port 0 asks the OS to choose.
RFC 3550 §11: RTP on an even port, RTCP on the next one up. They are bound together because a session that sends reports and cannot receive them is half a control protocol — it can tell the far end what it is hearing and can never learn what the far end hears, and the round-trip time comes from exactly that.
Failing to get the control port is not failing to place the call. The pair is attempted, and if no pair is free the media port is taken alone and reporting is one-way.
Sourcepub fn local_addr(&self) -> SocketAddr
pub fn local_addr(&self) -> SocketAddr
The port audio will arrive on — what goes in the SDP.
Sourcepub fn has_control_port(&self) -> bool
pub fn has_control_port(&self) -> bool
Whether this port got the control port above the media one (RFC 3550 §11).
It decides what ICE may offer: docs/specs/ice.md §6.1 puts component 2 in the offer
only when the control port was actually obtained, because a candidate for a socket
that was never bound is an address the peer will check and nothing will answer on.
Sourcepub async fn key_with_dtls(
self,
identity: Identity,
peer: SocketAddr,
role: Role,
fingerprint: Fingerprint,
timeout: Duration,
) -> Result<(Self, SrtpKeys), DtlsStartError>
pub async fn key_with_dtls( self, identity: Identity, peer: SocketAddr, role: Role, fingerprint: Fingerprint, timeout: Duration, ) -> Result<(Self, SrtpKeys), DtlsStartError>
Run DTLS on this port and return it with the derived SRTP master material.
The handshake borrows a duplicated descriptor for the same bound socket. No RTP worker is
running yet, so it is the only reader; once it finishes, that duplicate is dropped and the
original descriptor is restored to Tokio for Self::start. The timeout is enforced by
the DTLS socket itself, making the blocking worker bounded even if this future is cancelled.
Sourcepub async fn gather(&self, gathering: &Gathering) -> LocalDescription
pub async fn gather(&self, gathering: &Gathering) -> LocalDescription
Gather ICE candidates on this port’s sockets (RFC 8445 §5.1.1).
Called between binding and offering: the sockets are exclusively ours until
Self::start or Self::start_with_ice spawns the loops that read them, which is the
window a STUN transaction to a configured server needs.
The result carries the a=candidate lines for the description
(ice::LocalDescription::attributes) and the agent that will drive them.
Sourcepub async fn gather_with_rtcp_mode(
&self,
gathering: &Gathering,
rtcp_mode: RtcpMode,
) -> LocalDescription
pub async fn gather_with_rtcp_mode( &self, gathering: &Gathering, rtcp_mode: RtcpMode, ) -> LocalDescription
Gather ICE candidates for the negotiated RTCP shape.
A muxed stream has only component 1. The default Self::gather retains the historical
two-component behavior for callers that have not selected RFC 5761.
Sourcepub fn start(self, config: Config) -> Result<MediaSession, SetupError>
pub fn start(self, config: Config) -> Result<MediaSession, SetupError>
Start carrying media, now that negotiation has said where and in what.
Validation and construction finish before the first worker is spawned. On error this consumes and releases the bound port.
§Errors
Returns SetupError when timing is invalid or the negotiated codec cannot be built.
Sourcepub fn start_with_ice(
self,
config: Config,
local: LocalDescription,
) -> Result<MediaSession, SetupError>
pub fn start_with_ice( self, config: Config, local: LocalDescription, ) -> Result<MediaSession, SetupError>
Start carrying media with ICE driving the path (docs/specs/ice.md §2, §11).
The local description must already have been given the peer’s half through
ice::LocalDescription::accept. If that returned false — the peer offered no candidates,
or RFC 8839 §5.3’s ice-mismatch applies — no agent is driven and this is
Self::start: no check is sent, no timer runs, and the stream is carried by symmetric
RTP exactly as it is today.
§Errors
Returns SetupError before starting ICE or media workers when session construction is
invalid.
Sourcepub async fn start_browser_audio(
self,
config: Config,
local_ice: LocalDescription,
ice_generation: u64,
identity: Identity,
role: Role,
peer_fingerprint: Fingerprint,
timeout: Duration,
) -> Result<MediaSession, BrowserStartError>
pub async fn start_browser_audio( self, config: Config, local_ice: LocalDescription, ice_generation: u64, identity: Identity, role: Role, peer_fingerprint: Fingerprint, timeout: Duration, ) -> Result<MediaSession, BrowserStartError>
Start the fail-closed browser-audio runtime on this already-bound component.
ICE begins first on the retained socket. Its selected component becomes the only DTLS peer; DTLS records pass through the component owner rather than a duplicated descriptor. Only a verified handshake installs SRTP/SRTCP keys and attaches the media workers.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for MediaPort
impl RefUnwindSafe for MediaPort
impl Send for MediaPort
impl Sync for MediaPort
impl Unpin for MediaPort
impl UnsafeUnpin for MediaPort
impl UnwindSafe for MediaPort
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more