|
| 1 | +use wasm_bindgen::{prelude::*, JsCast}; |
| 2 | +use wasm_bindgen_futures::JsFuture; |
| 3 | +use wasm_bindgen_test::*; |
| 4 | + |
| 5 | +use futures::Future; |
| 6 | + |
| 7 | +use web_sys::{ |
| 8 | + RtcPeerConnection, RtcRtpTransceiver, RtcRtpTransceiverDirection, RtcRtpTransceiverInit, |
| 9 | + RtcSessionDescriptionInit, |
| 10 | +}; |
| 11 | + |
| 12 | + |
| 13 | +#[wasm_bindgen(inline_js = "export function is_unified_avail() { return Object.keys(RTCRtpTransceiver.prototype).indexOf('currentDirection')>-1; }")] |
| 14 | +extern "C" { |
| 15 | + /// Available in FF since forever, in Chrome since 72, in Safari since 12.1 |
| 16 | + fn is_unified_avail() -> bool; |
| 17 | +} |
| 18 | + |
| 19 | +#[wasm_bindgen_test(async)] |
| 20 | +fn rtc_rtp_transceiver_direction() -> impl Future<Item = (), Error = JsValue> { |
| 21 | + |
| 22 | + if !is_unified_avail(){ |
| 23 | + Ok(()) |
| 24 | + } |
| 25 | + |
| 26 | + let mut tr_init: RtcRtpTransceiverInit = RtcRtpTransceiverInit::new(); |
| 27 | + |
| 28 | + let pc1: RtcPeerConnection = RtcPeerConnection::new().unwrap(); |
| 29 | + |
| 30 | + let tr1: RtcRtpTransceiver = pc1.add_transceiver_with_str_and_init( |
| 31 | + "audio", |
| 32 | + tr_init.direction(RtcRtpTransceiverDirection::Sendonly), |
| 33 | + ); |
| 34 | + assert_eq!(tr1.direction(), RtcRtpTransceiverDirection::Sendonly); |
| 35 | + assert_eq!(tr1.current_direction(), None); |
| 36 | + |
| 37 | + let pc2: RtcPeerConnection = RtcPeerConnection::new().unwrap(); |
| 38 | + |
| 39 | + exchange_sdps(pc1, pc2).and_then(move |(_, p2)| { |
| 40 | + assert_eq!(tr1.direction(), RtcRtpTransceiverDirection::Sendonly); |
| 41 | + assert_eq!( |
| 42 | + tr1.current_direction(), |
| 43 | + Some(RtcRtpTransceiverDirection::Sendonly) |
| 44 | + ); |
| 45 | + |
| 46 | + let tr2: RtcRtpTransceiver = js_sys::try_iter(&p2.get_transceivers()) |
| 47 | + .unwrap() |
| 48 | + .unwrap() |
| 49 | + .next() |
| 50 | + .unwrap() |
| 51 | + .unwrap() |
| 52 | + .unchecked_into(); |
| 53 | + |
| 54 | + assert_eq!(tr2.direction(), RtcRtpTransceiverDirection::Recvonly); |
| 55 | + assert_eq!( |
| 56 | + tr2.current_direction(), |
| 57 | + Some(RtcRtpTransceiverDirection::Recvonly) |
| 58 | + ); |
| 59 | + |
| 60 | + Ok(()) |
| 61 | + }) |
| 62 | +} |
| 63 | + |
| 64 | +fn exchange_sdps( |
| 65 | + p1: RtcPeerConnection, |
| 66 | + p2: RtcPeerConnection, |
| 67 | +) -> impl Future<Item = (RtcPeerConnection, RtcPeerConnection), Error = JsValue> { |
| 68 | + JsFuture::from(p1.create_offer()) |
| 69 | + .and_then(move |offer| { |
| 70 | + let offer = offer.unchecked_into::<RtcSessionDescriptionInit>(); |
| 71 | + JsFuture::from(p1.set_local_description(&offer)).join4( |
| 72 | + JsFuture::from(p2.set_remote_description(&offer)), |
| 73 | + Ok(p1), |
| 74 | + Ok(p2), |
| 75 | + ) |
| 76 | + }) |
| 77 | + .and_then(|(_, _, p1, p2)| JsFuture::from(p2.create_answer()).join3(Ok(p1), Ok(p2))) |
| 78 | + .and_then(|(answer, p1, p2)| { |
| 79 | + let answer = answer.unchecked_into::<RtcSessionDescriptionInit>(); |
| 80 | + JsFuture::from(p2.set_local_description(&answer)).join4( |
| 81 | + JsFuture::from(p1.set_remote_description(&answer)), |
| 82 | + Ok(p1), |
| 83 | + Ok(p2), |
| 84 | + ) |
| 85 | + }) |
| 86 | + .and_then(|(_, _, p1, p2)| Ok((p1, p2))) |
| 87 | +} |
0 commit comments