Struct SdpApi

Source
pub struct SdpApi<'a> { /* private fields */ }
Expand description

Changes to the Rtc via SDP Offer/Answer dance.

Implementations§

Source§

impl<'a> SdpApi<'a>

Source

pub fn accept_offer(self, offer: SdpOffer) -> Result<SdpAnswer, RtcError>

Accept an SdpOffer from the remote peer. If this call returns successfully, the changes will have been made to the session. The resulting SdpAnswer should be sent to the remote peer.

Note. Pending changes from a previous non-completed SdpApi will be considered rolled back when calling this function.

The incoming SDP is validated in various ways which can cause this call to fail. Example of such problems would be an SDP without any m-lines, missing a=fingerprint or if a=group doesn’t match the number of m-lines.

// obtain offer from remote peer.
let json_offer: &[u8] = todo!();
let offer: SdpOffer = serde_json::from_slice(json_offer).unwrap();

let mut rtc = Rtc::new();
let answer = rtc.sdp_api().accept_offer(offer).unwrap();

// send json_answer to remote peer.
let json_answer = serde_json::to_vec(&answer).unwrap();
Source

pub fn accept_answer( self, pending: SdpPendingOffer, answer: SdpAnswer, ) -> Result<(), RtcError>

Accept an answer to a previously created SdpOffer.

This function returns an RtcError::ChangesOutOfOrder if we have created and applied another SdpApi before calling this. The same also happens if we use SdpApi::accept_offer() before using this pending instance.

let mut rtc = Rtc::new();

let mut changes = rtc.sdp_api();
let mid = changes.add_media(MediaKind::Audio, Direction::SendOnly, None, None);
let (offer, pending) = changes.apply().unwrap();

// send offer to remote peer, receive answer back
let answer: SdpAnswer = todo!();

rtc.sdp_api().accept_answer(pending, answer).unwrap();
Source

pub fn has_changes(&self) -> bool

Test if any changes have been made.

If changes have been made, nothing happens until we call SdpApi::apply().

let mut rtc = Rtc::new();

let mut changes = rtc.sdp_api();
assert!(!changes.has_changes());

let mid = changes.add_media(MediaKind::Audio, Direction::SendRecv, None, None);
assert!(changes.has_changes());
Source

pub fn add_media( &mut self, kind: MediaKind, dir: Direction, stream_id: Option<String>, track_id: Option<String>, ) -> Mid

Add audio or video media and get the mid that will be used.

Each call will result in a new m-line in the offer identified by the Mid.

The mid is not valid to use until the SDP offer-answer dance is complete and the mid been advertised via Event::MediaAdded.

  • stream_id is used to synchronize media. It is a=msid-semantic: WMS <streamId> line in SDP.
  • track_id is becomes both the track id in a=msid <streamId> <trackId> as well as the CNAME in the RTP SDES.
let mut rtc = Rtc::new();

let mut changes = rtc.sdp_api();

let mid = changes.add_media(MediaKind::Audio, Direction::SendRecv, None, None);
Source

pub fn set_direction(&mut self, mid: Mid, dir: Direction)

Change the direction of an already existing media.

All media have a direction. The media can be added by this side via SdpApi::add_media() or by the remote peer. Either way, the direction of the line can be changed at any time.

It’s possible to set the direction Direction::Inactive for media that will not be used by the session anymore.

If the direction is set for media that doesn’t exist, or if the direction is the same that’s already set SdpApi::apply() not require a negotiation.

Source

pub fn add_channel(&mut self, label: String) -> ChannelId

Add a new data channel and get the id that will be used.

The first ever data channel added to a WebRTC session results in a media of a special “application” type in the SDP. The m-line is for a SCTP association over DTLS, and all data channels are multiplexed over this single association.

That means only the first ever add_channel will result in an SdpOffer. Consecutive channels will be opened without needing a negotiation.

The label is used to identify the data channel to the remote peer. This is mostly useful whe multiple channels are in use at the same time.

let mut rtc = Rtc::new();

let mut changes = rtc.sdp_api();

let cid = changes.add_channel("my special channel".to_string());
Source

pub fn ice_restart(&mut self, keep_local_candidates: bool) -> IceCreds

Perform an ICE restart.

Only one ICE restart can be pending at the time. Calling this repeatedly removes any other pending ICE restart.

The local ICE candidates can be kept as is, or be cleared out, in which case new ice candidates must be added via Rtc::add_local_candidate before connectivity can be re-established.

Returns the new ICE credentials that will be used going forward.

Source

pub fn apply(self) -> Option<(SdpOffer, SdpPendingOffer)>

Attempt to apply the changes made.

If this returns SdpOffer, the caller the changes are not happening straight away, and the caller is expected to do a negotiation with the remote peer and apply the answer using SdpPendingOffer.

In case this returns None, there either were no changes, or the changes could be applied without doing a negotiation. Specifically for additional SdpApi::add_channel() after the first, there is no negotiation needed.

The SdpPendingOffer is valid until the next time we call this function, at which point using it will raise an error. Using SdpApi::accept_offer() will also invalidate the current SdpPendingOffer.

let mut rtc = Rtc::new();

let changes = rtc.sdp_api();
assert!(changes.apply().is_none());
Source

pub fn merge(&mut self, pending_offer: SdpPendingOffer)

Combines the modifications made in SdpApi with those in SdpPendingOffer.

This function merges the changes present in SdpApi with the changes in SdpPendingOffer. In result this SdpApi will incorporate modifications from both the previous SdpPendingOffer and any newly added changes.

§Example
let mut rtc = Rtc::new();
let mut changes = rtc.sdp_api();
changes.add_media(MediaKind::Audio, Direction::SendOnly, None, None);
let (_offer, pending) = changes.apply().unwrap();

let mut changes = rtc.sdp_api();
changes.add_media(MediaKind::Video, Direction::SendOnly, None, None);
changes.merge(pending);

// This `SdpOffer` will have changes from the first `SdpPendingChanges`
// and new changes from `SdpApi`
let (_offer, pending) = changes.apply().unwrap();

Auto Trait Implementations§

§

impl<'a> Freeze for SdpApi<'a>

§

impl<'a> !RefUnwindSafe for SdpApi<'a>

§

impl<'a> Send for SdpApi<'a>

§

impl<'a> Sync for SdpApi<'a>

§

impl<'a> Unpin for SdpApi<'a>

§

impl<'a> !UnwindSafe for SdpApi<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more