8eb224f8d7cbdceac81547412b3d488f908d9622
[gecko.git] / test_peerConnection_replaceTrack.html
blob8eb224f8d7cbdceac81547412b3d488f908d9622
1 <!DOCTYPE HTML>
2 <html>
3 <head>
4 <script type="application/javascript" src="pc.js"></script>
5 </head>
6 <body>
7 <pre id="test">
8 <script type="application/javascript;version=1.8">
9 createHTML({
10 bug: "1032839",
11 title: "Replace video and audio (with WebAudio) tracks",
12 visible: true
13 });
15 function allLocalStreamsHaveSender(pc) {
16 return pc.getLocalStreams()
17 .every(s => s.getTracks() // Every local stream,
18 .some(t => pc.getSenders() // should have some track,
19 .some(sn => sn.track == t))) // that's being sent over |pc|.
22 function allRemoteStreamsHaveReceiver(pc) {
23 return pc.getRemoteStreams()
24 .every(s => s.getTracks() // Every remote stream,
25 .some(t => pc.getReceivers() // should have some track,
26 .some(sn => sn.track == t))) // that's being received over |pc|.
29 function replacetest(wrapper) {
30 var pc = wrapper._pc;
31 var oldSenderCount = pc.getSenders().length;
32 var sender = pc.getSenders().find(sn => sn.track.kind == "video");
33 var oldTrack = sender.track;
34 ok(sender, "We have a sender for video");
35 ok(allLocalStreamsHaveSender(pc),
36 "Shouldn't have any local streams without a corresponding sender");
37 ok(allRemoteStreamsHaveReceiver(pc),
38 "Shouldn't have any remote streams without a corresponding receiver");
40 var newTrack;
41 var audiotrack;
42 return navigator.mediaDevices.getUserMedia({video:true, audio:true})
43 .then(newStream => {
44 window.grip = newStream;
45 newTrack = newStream.getVideoTracks()[0];
46 audiotrack = newStream.getAudioTracks()[0];
47 isnot(newTrack, sender.track, "replacing with a different track");
48 ok(!pc.getLocalStreams().some(s => s == newStream),
49 "from a different stream");
50 return sender.replaceTrack(newTrack);
52 .then(() => {
53 is(pc.getSenders().length, oldSenderCount, "same sender count");
54 is(sender.track, newTrack, "sender.track has been replaced");
55 ok(!pc.getSenders().map(sn => sn.track).some(t => t == oldTrack),
56 "old track not among senders");
57 ok(pc.getLocalStreams().some(s => s.getTracks()
58 .some(t => t == sender.track)),
59 "track exists among pc's local streams");
60 return sender.replaceTrack(audiotrack)
61 .then(() => ok(false, "replacing with different kind should fail"),
62 e => is(e.name, "IncompatibleMediaStreamTrackError",
63 "replacing with different kind should fail"));
64 });
67 runNetworkTest(function () {
68 test = new PeerConnectionTest();
69 test.audioCtx = new AudioContext();
70 test.setMediaConstraints([{video: true, audio: true}], [{video: true}]);
71 test.chain.removeAfter("PC_REMOTE_WAIT_FOR_MEDIA_FLOW");
73 // Test replaceTrack on pcRemote separately since it's video only.
74 test.chain.append([
75 function PC_REMOTE_VIDEOONLY_REPLACE_VIDEOTRACK(test) {
76 return replacetest(test.pcRemote);
78 function PC_LOCAL_NEW_VIDEOTRACK_WAIT_FOR_MEDIA_FLOW(test) {
79 return test.pcLocal.waitForMediaFlow();
81 ]);
83 // Replace video twice on pcLocal to make sure it still works
84 // (does audio twice too, but hey)
85 test.chain.append([
86 function PC_LOCAL_AUDIOVIDEO_REPLACE_VIDEOTRACK_1(test) {
87 return replacetest(test.pcLocal);
89 function PC_REMOTE_NEW_VIDEOTRACK_WAIT_FOR_MEDIA_FLOW_1(test) {
90 return test.pcRemote.waitForMediaFlow();
92 function PC_LOCAL_AUDIOVIDEO_REPLACE_VIDEOTRACK_2(test) {
93 return replacetest(test.pcLocal);
95 function PC_REMOTE_NEW_VIDEOTRACK_WAIT_FOR_MEDIA_FLOW_2(test) {
96 return test.pcRemote.waitForMediaFlow();
98 ]);
100 test.chain.append([
101 function PC_LOCAL_AUDIOVIDEO_REPLACE_VIDEOTRACK_WITHSAME(test) {
102 var pc = test.pcLocal._pc;
103 var sender = pc.getSenders().find(sn => sn.track.kind == "video");
104 ok(sender, "should still have a sender of video");
105 return sender.replaceTrack(sender.track)
106 .then(() => ok(true, "replacing with itself should succeed"));
108 function PC_REMOTE_NEW_SAME_VIDEOTRACK_WAIT_FOR_MEDIA_FLOW(test) {
109 return test.pcRemote.waitForMediaFlow();
113 // Replace the gUM audio track on pcLocal with a WebAudio track.
114 test.chain.append([
115 function PC_LOCAL_AUDIOVIDEO_REPLACE_AUDIOTRACK_WEBAUDIO(test) {
116 var pc = test.pcLocal._pc;
117 var sender = pc.getSenders().find(sn => sn.track.kind == "audio");
118 ok(sender, "track has a sender");
119 var oldSenderCount = pc.getSenders().length;
120 var oldTrack = sender.track;
122 var sourceNode = test.audioCtx.createOscillator();
123 sourceNode.type = 'sine';
124 // We need a frequency not too close to the fake audio track
125 // (440Hz for loopback devices, 1kHz for fake tracks).
126 sourceNode.frequency.value = 2000;
127 sourceNode.start();
129 var destNode = test.audioCtx.createMediaStreamDestination();
130 sourceNode.connect(destNode);
131 var newTrack = destNode.stream.getAudioTracks()[0];
133 return sender.replaceTrack(newTrack)
134 .then(() => {
135 is(pc.getSenders().length, oldSenderCount, "same sender count");
136 ok(!pc.getSenders().some(sn => sn.track == oldTrack),
137 "Replaced track should be removed from senders");
138 ok(allLocalStreamsHaveSender(pc),
139 "Shouldn't have any streams without a corresponding sender");
140 is(sender.track, newTrack, "sender.track has been replaced");
141 ok(pc.getLocalStreams().some(s => s.getTracks()
142 .some(t => t == sender.track)),
143 "track exists among pc's local streams");
147 test.chain.append([
148 function PC_LOCAL_CHECK_WEBAUDIO_FLOW_PRESENT(test) {
149 return test.pcRemote.checkReceivingToneFrom(test.audioCtx, test.pcLocal);
152 test.chain.append([
153 function PC_LOCAL_INVALID_ADD_VIDEOTRACKS(test) {
154 var stream = test.pcLocal._pc.getLocalStreams()[0];
155 var track = stream.getVideoTracks()[0];
156 try {
157 test.pcLocal._pc.addTrack(track, stream);
158 ok(false, "addTrack existing track should fail");
159 } catch (e) {
160 is(e.name, "InvalidParameterError",
161 "addTrack existing track should fail");
163 try {
164 test.pcLocal._pc.addTrack(track, stream);
165 ok(false, "addTrack existing track should fail");
166 } catch (e) {
167 is(e.name, "InvalidParameterError",
168 "addTrack existing track should fail");
172 test.run();
174 </script>
175 </pre>
176 </body>
177 </html>