RTCTrackEvent-fire.html (5853B)
1 <!doctype html> 2 <meta charset=utf-8> 3 <title>Change of msid in remote description should trigger related track events</title> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script> 7 const sdpBase =`v=0 8 o=- 5511237691691746 2 IN IP4 127.0.0.1 9 s=- 10 t=0 0 11 a=group:BUNDLE 0 12 a=ice-options:trickle 13 a=ice-lite 14 a=msid-semantic:WMS * 15 m=audio 9 UDP/TLS/RTP/SAVPF 111 103 9 102 0 8 105 13 110 113 126 16 c=IN IP6 :: 17 a=rtcp:9 IN IP6 :: 18 a=rtcp-mux 19 a=mid:0 20 a=sendrecv 21 a=ice-ufrag:z0i8R3C9C4hPRWls 22 a=ice-pwd:O7bPpOFAqasqoidV4yxnFVbc 23 a=ice-lite 24 a=fingerprint:sha-256 B7:9C:0D:C9:D1:42:57:97:82:4D:F9:B7:93:75:49:C3:42:21:5A:DD:9C:B5:ED:53:53:F0:B4:C8:AE:88:7A:E7 25 a=setup:actpass 26 a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level 27 a=extmap:9 urn:ietf:params:rtp-hdrext:sdes:mid 28 a=rtpmap:0 PCMU/8000`; 29 30 const sdp0 = sdpBase + ` 31 `; 32 33 const sdp1 = sdpBase + ` 34 a=msid:1 2 35 a=ssrc:3 cname:4 36 a=ssrc:3 msid:1 2 37 `; 38 39 const sdp2 = sdpBase + ` 40 a=ssrc:3 cname:4 41 a=ssrc:3 msid:1 2 42 `; 43 44 const sdp3 = sdpBase + ` 45 a=msid:1 2 46 a=ssrc:3 cname:4 47 a=ssrc:3 msid:3 2 48 `; 49 50 const sdp4 = sdp1.replace('msid-semantic', 'unknownattr'); 51 52 const sdp5 = sdpBase + ` 53 a=msid:- 54 `; 55 56 const sdp6 = sdpBase + ` 57 a=msid:1 2 58 a=msid:1 2 59 `; 60 61 async function applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp) 62 { 63 const testTrackPromise = new Promise(resolve => { 64 pc.ontrack = (event) => { resolve([event.track, event.streams]); }; 65 }); 66 await pc.setRemoteDescription({type: 'offer', sdp: sdp}); 67 return testTrackPromise; 68 } 69 70 promise_test(async test => { 71 const pc = new RTCPeerConnection(); 72 test.add_cleanup(() => pc.close()); 73 74 const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp0); 75 assert_equals(streams.length, 1, "track event has a stream"); 76 }, "When a=msid is absent, the track should still be associated with a stream"); 77 78 promise_test(async test => { 79 const pc = new RTCPeerConnection(); 80 test.add_cleanup(() => pc.close()); 81 82 const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp1); 83 assert_equals(streams.length, 1, "track event has a stream"); 84 assert_equals(streams[0].id, "1", "msid should match"); 85 }, "Source-level msid should be ignored if media-level msid is present"); 86 87 promise_test(async test => { 88 const pc = new RTCPeerConnection(); 89 test.add_cleanup(() => pc.close()); 90 91 const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp2); 92 assert_equals(streams.length, 1, "track event has a stream"); 93 assert_equals(streams[0].id, "1", "msid should match"); 94 }, "Source-level msid should be parsed if media-level msid is absent"); 95 96 promise_test(async test => { 97 const pc = new RTCPeerConnection(); 98 test.add_cleanup(() => pc.close()); 99 100 let track; 101 let streams; 102 try { 103 [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp3); 104 } catch (e) { 105 return; 106 } 107 assert_equals(streams.length, 1, "track event has a stream"); 108 assert_equals(streams[0].id, "1", "msid should match"); 109 }, "Source-level msid should be ignored, or an error should be thrown, if a different media-level msid is present"); 110 111 promise_test(async test => { 112 const pc = new RTCPeerConnection(); 113 test.add_cleanup(() => pc.close()); 114 115 const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp4); 116 assert_equals(streams.length, 1, "track event has a stream"); 117 assert_equals(streams[0].id, "1", "msid should match"); 118 }, "stream ids should be found even if msid-semantic is absent"); 119 120 promise_test(async test => { 121 const pc = new RTCPeerConnection(); 122 test.add_cleanup(() => pc.close()); 123 124 const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp5); 125 assert_equals(streams.length, 0, "track event has no stream"); 126 }, "a=msid:- should result in a track event with no streams"); 127 128 promise_test(async test => { 129 const pc = new RTCPeerConnection(); 130 test.add_cleanup(() => pc.close()); 131 132 const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp6); 133 assert_equals(streams.length, 1, "track event has one stream"); 134 }, "Duplicate a=msid should result in a track event with one stream"); 135 136 promise_test(async test => { 137 const pc = new RTCPeerConnection(); 138 test.add_cleanup(() => pc.close()); 139 140 const [track, streams] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp1); 141 assert_equals(streams.length, 1, "track event has a stream"); 142 assert_equals(streams[0].id, "1", "msid should match"); 143 const stream = streams[0]; 144 145 await pc.setLocalDescription(await pc.createAnswer()); 146 147 const testTrackPromise = new Promise((resolve) => { stream.onremovetrack = resolve; }); 148 await pc.setRemoteDescription({type: 'offer', 'sdp': sdp0}); 149 await testTrackPromise; 150 151 assert_equals(stream.getAudioTracks().length, 0, "stream should be empty"); 152 }, "Applying a remote description with removed msid should trigger firing a removetrack event on the corresponding stream"); 153 154 promise_test(async test => { 155 const pc = new RTCPeerConnection(); 156 test.add_cleanup(() => pc.close()); 157 158 let [track0, streams0] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp0); 159 160 await pc.setLocalDescription(await pc.createAnswer()); 161 162 let [track1, streams1] = await applyRemoteDescriptionAndReturnRemoteTrackAndStreams(pc, sdp1); 163 164 assert_equals(streams1.length, 1, "track event has a stream"); 165 assert_equals(streams1[0].id, "1", "msid should match"); 166 assert_equals(streams1[0].getTracks()[0], track0, "track should match"); 167 }, "Applying a remote description with a new msid should trigger firing an event with populated streams"); 168 </script>