| OLD | NEW |
| 1 <!DOCTYPE html> | 1 <!DOCTYPE html> |
| 2 <html> | 2 <html> |
| 3 <head> | 3 <head> |
| 4 <title>MediaStream Recoder Browser Test (w/ MediaSource)</title> | 4 <title>MediaStream Recoder Browser Test (w/ MediaSource)</title> |
| 5 </head> | 5 </head> |
| 6 <body> | 6 <body> |
| 7 <div> Record Real-Time video content browser test.</div> | 7 <div> Record Real-Time video content browser test.</div> |
| 8 <video id="video" autoplay></video> | 8 <video id="video" autoplay></video> |
| 9 <video id="remoteVideo" autoplay></video> | 9 <video id="remoteVideo" autoplay></video> |
| 10 </body> | 10 </body> |
| 11 <script type="text/javascript" src="mediarecorder_test_utils.js"></script> | 11 <script type="text/javascript" src="mediarecorder_test_utils.js"></script> |
| 12 <script type="text/javascript" src="webrtc_test_utilities.js"></script> | 12 <script type="text/javascript" src="webrtc_test_utilities.js"></script> |
| 13 <script> | 13 <script> |
| 14 | 14 |
| 15 'use strict'; | 15 'use strict'; |
| 16 | 16 |
| 17 const DEFAULT_CONSTRAINTS= {audio:true, video:true}; | 17 const DEFAULT_CONSTRAINTS = {audio: true, video: true}; |
| 18 const DEFAULT_RECORDER_MIME_TYPE = ''; | 18 const DEFAULT_RECORDER_MIME_TYPE = ''; |
| 19 const DEFAULT_TIME_SLICE = 100; | 19 const DEFAULT_TIME_SLICE = 100; |
| 20 const FREQUENCY = 880; | 20 const FREQUENCY = 880; |
| 21 // Note that not all audio sampling rates are supported by the underlying | 21 // Note that not all audio sampling rates are supported by the underlying |
| 22 // Opus audio codec: the valid rates are 8kHz, 12kHz, 16kHz, 24kHz, 48kHz. | 22 // Opus audio codec: the valid rates are 8kHz, 12kHz, 16kHz, 24kHz, 48kHz. |
| 23 // See crbug/569089 for details. | 23 // See crbug/569089 for details. |
| 24 const SAMPLING_RATE = 48000; | 24 const SAMPLING_RATE = 48000; |
| 25 const NUM_SAMPLES = 2 * SAMPLING_RATE; | 25 const NUM_SAMPLES = 2 * SAMPLING_RATE; |
| 26 | 26 |
| 27 // Function assert_throws inspired from Blink's | 27 // Function assert_throws inspired from Blink's |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 121 startEventReceived = true; | 121 startEventReceived = true; |
| 122 assertEquals('recording', theRecorder.state); | 122 assertEquals('recording', theRecorder.state); |
| 123 }; | 123 }; |
| 124 }) | 124 }) |
| 125 .then(function() { | 125 .then(function() { |
| 126 theRecorder.start(); | 126 theRecorder.start(); |
| 127 }) | 127 }) |
| 128 .then(function() { | 128 .then(function() { |
| 129 return waitFor('Make sure the start event was received', | 129 return waitFor('Make sure the start event was received', |
| 130 function() { | 130 function() { |
| 131 return startEventReceived == true; | 131 return startEventReceived; |
| 132 }); | 132 }); |
| 133 }) | 133 }) |
| 134 .catch(function(err) { | 134 .catch(function(err) { |
| 135 return failTest(err.toString()); | 135 return failTest(err.toString()); |
| 136 }) | 136 }) |
| 137 .then(function() { | 137 .then(function() { |
| 138 reportTestSuccess(); | 138 reportTestSuccess(); |
| 139 }); | 139 }); |
| 140 } | 140 } |
| 141 | 141 |
| 142 // Tests that the MediaRecorder's stop() function will effectively cause the | 142 // Tests that the MediaRecorder's stop() function will effectively cause the |
| 143 // |state| to be 'inactive' and that a 'stop' event is fired. | 143 // |state| to be 'inactive' and that a 'stop' event is fired. |
| 144 function testStartStopAndRecorderState() { | 144 function testStartStopAndRecorderState() { |
| 145 var theRecorder; | 145 var theRecorder; |
| 146 var stopEventReceived = false; | 146 var stopEventReceived = false; |
| 147 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) | 147 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) |
| 148 .then(function(stream) { | 148 .then(function(stream) { |
| 149 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); | 149 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); |
| 150 }) | 150 }) |
| 151 .then(function(recorder) { | 151 .then(function(recorder) { |
| 152 recorder.onstop = function(event) { | 152 recorder.onstop = function(event) { |
| 153 stopEventReceived = true; | 153 stopEventReceived = true; |
| 154 assertEquals('inactive', theRecorder.state); | 154 assertEquals('inactive', theRecorder.state); |
| 155 }; | 155 }; |
| 156 recorder.stop(); | 156 recorder.stop(); |
| 157 }) | 157 }) |
| 158 .then(function() { | 158 .then(function() { |
| 159 return waitFor('Make sure the stop event was received', | 159 return waitFor('Make sure the stop event was received', |
| 160 function() { | 160 function() { |
| 161 return stopEventReceived == true; | 161 return stopEventReceived; |
| 162 }); | 162 }); |
| 163 }) | 163 }) |
| 164 .catch(function(err) { | 164 .catch(function(err) { |
| 165 return failTest(err.toString()); | 165 return failTest(err.toString()); |
| 166 }) | 166 }) |
| 167 .then(function() { | 167 .then(function() { |
| 168 reportTestSuccess(); | 168 reportTestSuccess(); |
| 169 }); | 169 }); |
| 170 } | 170 } |
| 171 | 171 |
| 172 // Tests that when MediaRecorder's start() function is called, some data is | 172 // Tests that when MediaRecorder's start() function is called, some data is |
| 173 // made available by media recorder via dataavailable events, containing non | 173 // made available by media recorder via dataavailable events, containing non |
| 174 // empty blob data. | 174 // empty blob data. |
| 175 function testStartAndDataAvailable() { | 175 function testStartAndDataAvailable() { |
| 176 var videoSize = 0; | 176 var videoSize = 0; |
| 177 var emptyBlobs = 0; | 177 var emptyBlobs = 0; |
| 178 var timeStamps = []; | 178 var timeStamps = []; |
| 179 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) | 179 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) |
| 180 .then(function(stream) { | 180 .then(function(stream) { |
| 181 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); | 181 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); |
| 182 }) | 182 }) |
| 183 .then(function(recorder) { | 183 .then(function(recorder) { |
| 184 // Save history of Blobs received via dataavailable. | 184 // Save history of Blobs received via dataavailable. |
| 185 recorder.ondataavailable = function(event) { | 185 recorder.ondataavailable = function(event) { |
| 186 timeStamps.push(event.timeStamp); | 186 timeStamps.push(event.timeStamp); |
| 187 if (event.data.size > 0) | 187 if (event.data.size > 0) |
| 188 videoSize += event.data.size; | 188 videoSize += event.data.size; |
| 189 else | 189 else |
| 190 emptyBlobs += 1; | 190 emptyBlobs += 1; |
| 191 }; | 191 }; |
| 192 }) | 192 }) |
| 193 .then(function() { | 193 .then(function() { |
| 194 return waitFor('Make sure the recording has data', | 194 return waitFor('Make sure the recording has data', |
| 195 function() { | 195 function() { |
| 196 return videoSize > 0; | 196 return videoSize > 0; |
| 197 }); | 197 }); |
| 198 }) | 198 }) |
| (...skipping 17 matching lines...) Expand all Loading... |
| 216 var timeStamps = []; | 216 var timeStamps = []; |
| 217 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) | 217 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) |
| 218 .then(function(stream) { | 218 .then(function(stream) { |
| 219 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE, | 219 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE, |
| 220 DEFAULT_TIME_SLICE); | 220 DEFAULT_TIME_SLICE); |
| 221 }) | 221 }) |
| 222 .then(function(recorder) { | 222 .then(function(recorder) { |
| 223 recorder.ondataavailable = function(event) { | 223 recorder.ondataavailable = function(event) { |
| 224 timeStamps.push(event.timeStamp); | 224 timeStamps.push(event.timeStamp); |
| 225 if (event.data.size > 0) | 225 if (event.data.size > 0) |
| 226 videoSize += event.data.size; | 226 videoSize += event.data.size; |
| 227 else | 227 else |
| 228 emptyBlobs += 1; | 228 emptyBlobs += 1; |
| 229 }; | 229 }; |
| 230 }) | 230 }) |
| 231 .then(function() { | 231 .then(function() { |
| 232 return waitFor('Making sure the recording has data', | 232 return waitFor('Making sure the recording has data', |
| 233 function() { | 233 function() { |
| 234 return videoSize > 0 && timeStamps.length > 10; | 234 return videoSize > 0 && timeStamps.length > 10; |
| 235 }); | 235 }); |
| 236 }) | 236 }) |
| (...skipping 20 matching lines...) Expand all Loading... |
| 257 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); | 257 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); |
| 258 }) | 258 }) |
| 259 .then(function(recorder) { | 259 .then(function(recorder) { |
| 260 theRecorder = recorder; | 260 theRecorder = recorder; |
| 261 theRecorder.pause(); | 261 theRecorder.pause(); |
| 262 }) | 262 }) |
| 263 .then(function() { | 263 .then(function() { |
| 264 theRecorder.onresume = function(event) { | 264 theRecorder.onresume = function(event) { |
| 265 resumeEventReceived = true; | 265 resumeEventReceived = true; |
| 266 assertEquals('recording', theRecorder.state); | 266 assertEquals('recording', theRecorder.state); |
| 267 } | 267 }; |
| 268 theRecorder.resume(); | 268 theRecorder.resume(); |
| 269 }) | 269 }) |
| 270 .then(function() { | 270 .then(function() { |
| 271 return waitFor('Making sure the resume event has been received', | 271 return waitFor('Making sure the resume event has been received', |
| 272 function() { | 272 function() { |
| 273 return resumeEventReceived == true; | 273 return resumeEventReceived; |
| 274 }); | 274 }); |
| 275 }) | 275 }) |
| 276 .catch(function(err) { | 276 .catch(function(err) { |
| 277 return failTest(err.toString()); | 277 return failTest(err.toString()); |
| 278 }) | 278 }) |
| 279 .then(function() { | 279 .then(function() { |
| 280 reportTestSuccess(); | 280 reportTestSuccess(); |
| 281 }); | 281 }); |
| 282 } | 282 } |
| 283 | 283 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 302 .then(function(stream) { | 302 .then(function(stream) { |
| 303 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); | 303 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); |
| 304 }) | 304 }) |
| 305 .then(function(recorder) { | 305 .then(function(recorder) { |
| 306 theRecorder = recorder; | 306 theRecorder = recorder; |
| 307 theRecorder.pause(); | 307 theRecorder.pause(); |
| 308 }) | 308 }) |
| 309 .then(function() { | 309 .then(function() { |
| 310 theRecorder.ondataavailable = function(event) { | 310 theRecorder.ondataavailable = function(event) { |
| 311 if (event.data.size > 0) { | 311 if (event.data.size > 0) { |
| 312 videoSize += event.data.size; | 312 videoSize += event.data.size; |
| 313 } else { | 313 } else { |
| 314 console.log('This dataavailable event is empty', event); | 314 console.log('This dataavailable event is empty', event); |
| 315 emptyBlobs += 1; | 315 emptyBlobs += 1; |
| 316 } | 316 } |
| 317 }; | 317 }; |
| 318 }) | 318 }) |
| 319 .then(function() { | 319 .then(function() { |
| 320 theRecorder.resume(); | 320 theRecorder.resume(); |
| 321 }) | 321 }) |
| 322 .then(function() { | 322 .then(function() { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 345 var pauseEventReceived = false; | 345 var pauseEventReceived = false; |
| 346 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) | 346 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) |
| 347 .then(function(stream) { | 347 .then(function(stream) { |
| 348 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); | 348 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); |
| 349 }) | 349 }) |
| 350 .then(function(recorder) { | 350 .then(function(recorder) { |
| 351 theRecorder = recorder; | 351 theRecorder = recorder; |
| 352 theRecorder.onpause = function(event) { | 352 theRecorder.onpause = function(event) { |
| 353 pauseEventReceived = true; | 353 pauseEventReceived = true; |
| 354 assertEquals('paused', theRecorder.state); | 354 assertEquals('paused', theRecorder.state); |
| 355 } | 355 }; |
| 356 theRecorder.pause(); | 356 theRecorder.pause(); |
| 357 }) | 357 }) |
| 358 .then(function() { | 358 .then(function() { |
| 359 return waitFor('Making sure the pause event has been received', | 359 return waitFor('Making sure the pause event has been received', |
| 360 function() { | 360 function() { |
| 361 return pauseEventReceived == true; | 361 return pauseEventReceived; |
| 362 }); | 362 }); |
| 363 }) | 363 }) |
| 364 .catch(function(err) { | 364 .catch(function(err) { |
| 365 return failTest(err.toString()); | 365 return failTest(err.toString()); |
| 366 }) | 366 }) |
| 367 .then(function() { | 367 .then(function() { |
| 368 reportTestSuccess(); | 368 reportTestSuccess(); |
| 369 }); | 369 }); |
| 370 } | 370 } |
| 371 | 371 |
| (...skipping 20 matching lines...) Expand all Loading... |
| 392 }) | 392 }) |
| 393 .then(function() { | 393 .then(function() { |
| 394 reportTestSuccess(); | 394 reportTestSuccess(); |
| 395 }); | 395 }); |
| 396 } | 396 } |
| 397 | 397 |
| 398 // Tests that no dataavailable event is fired after MediaRecorder's pause() | 398 // Tests that no dataavailable event is fired after MediaRecorder's pause() |
| 399 // function is called. | 399 // function is called. |
| 400 function testPausePreventsDataavailableFromBeingFired() { | 400 function testPausePreventsDataavailableFromBeingFired() { |
| 401 var theRecorder; | 401 var theRecorder; |
| 402 var videoSize = 0; | |
| 403 var emptyBlobs = 0; | |
| 404 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) | 402 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) |
| 405 .then(function(stream) { | 403 .then(function(stream) { |
| 406 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); | 404 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); |
| 407 }) | 405 }) |
| 408 .then(function(recorder) { | 406 .then(function(recorder) { |
| 409 theRecorder = recorder; | 407 theRecorder = recorder; |
| 410 theRecorder.pause(); | 408 theRecorder.pause(); |
| 411 }) | 409 }) |
| 412 .then(function() { | 410 .then(function() { |
| 413 theRecorder.ondataavailable = function(event) { | 411 theRecorder.ondataavailable = function(event) { |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 508 assertThrows(function() {recorder.start()}, 'Calling start() in' + | 506 assertThrows(function() {recorder.start()}, 'Calling start() in' + |
| 509 ' paused state should cause a DOM error'); | 507 ' paused state should cause a DOM error'); |
| 510 }); | 508 }); |
| 511 } | 509 } |
| 512 | 510 |
| 513 // Tests that MediaRecorder can record a 2 Channel audio stream. | 511 // Tests that MediaRecorder can record a 2 Channel audio stream. |
| 514 function testTwoChannelAudio() { | 512 function testTwoChannelAudio() { |
| 515 var audioSize = 0; | 513 var audioSize = 0; |
| 516 var context = new OfflineAudioContext(2, NUM_SAMPLES, SAMPLING_RATE); | 514 var context = new OfflineAudioContext(2, NUM_SAMPLES, SAMPLING_RATE); |
| 517 var oscillator = context.createOscillator(); | 515 var oscillator = context.createOscillator(); |
| 518 oscillator.type = "sine"; | 516 oscillator.type = 'sine'; |
| 519 oscillator.frequency.value = FREQUENCY; | 517 oscillator.frequency.value = FREQUENCY; |
| 520 var dest = context.createMediaStreamDestination(); | 518 var dest = context.createMediaStreamDestination(); |
| 521 dest.channelCount = 2; | 519 dest.channelCount = 2; |
| 522 oscillator.connect(dest); | 520 oscillator.connect(dest); |
| 523 createMediaRecorder(dest.stream, DEFAULT_RECORDER_MIME_TYPE) | 521 createMediaRecorder(dest.stream, DEFAULT_RECORDER_MIME_TYPE) |
| 524 .then(function(recorder) { | 522 .then(function(recorder) { |
| 525 recorder.ondataavailable = function(event) { | 523 recorder.ondataavailable = function(event) { |
| 526 audioSize += event.data.size; | 524 audioSize += event.data.size; |
| 527 }; | 525 }; |
| 528 recorder.start(); | 526 recorder.start(); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 554 .then(function(recorder) { | 552 .then(function(recorder) { |
| 555 assertThrows(function() {recorder.requestData()}, | 553 assertThrows(function() {recorder.requestData()}, |
| 556 'Calling requestdata() in inactive state should throw a DOM ' + | 554 'Calling requestdata() in inactive state should throw a DOM ' + |
| 557 'Exception'); | 555 'Exception'); |
| 558 }); | 556 }); |
| 559 } | 557 } |
| 560 | 558 |
| 561 </script> | 559 </script> |
| 562 </body> | 560 </body> |
| 563 </html> | 561 </html> |
| OLD | NEW |