| 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> |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 102 return new Promise(function(resolve, reject) { | 102 return new Promise(function(resolve, reject) { |
| 103 var recorder = new MediaRecorder(stream, {'mimeType' : mimeType}); | 103 var recorder = new MediaRecorder(stream, {'mimeType' : mimeType}); |
| 104 console.log('Recorder object created.'); | 104 console.log('Recorder object created.'); |
| 105 resolve(recorder); | 105 resolve(recorder); |
| 106 }); | 106 }); |
| 107 } | 107 } |
| 108 | 108 |
| 109 // Tests that the MediaRecorder's start() function will cause the |state| to be | 109 // Tests that the MediaRecorder's start() function will cause the |state| to be |
| 110 // 'recording' and that a 'start' event is fired. | 110 // 'recording' and that a 'start' event is fired. |
| 111 function testStartAndRecorderState() { | 111 function testStartAndRecorderState() { |
| 112 var theRecorder; | |
| 113 var startEventReceived = false; | 112 var startEventReceived = false; |
| 114 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) | 113 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) |
| 115 .then(function(stream) { | 114 .then(function(stream) { |
| 116 return createMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); | 115 return createMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); |
| 117 }) | 116 }) |
| 118 .then(function(recorder) { | 117 .then(function(recorder) { |
| 119 theRecorder = recorder; | 118 recorder = recorder; |
| 120 theRecorder.onstart = function(event) { | 119 recorder.onstart = function(event) { |
| 121 startEventReceived = true; | 120 startEventReceived = true; |
| 122 assertEquals('recording', theRecorder.state); | 121 assertEquals('recording', recorder.state); |
| 123 }; | 122 }; |
| 124 }) | 123 recorder.start(); |
| 125 .then(function() { | |
| 126 theRecorder.start(); | |
| 127 }) | 124 }) |
| 128 .then(function() { | 125 .then(function() { |
| 129 return waitFor('Make sure the start event was received', | 126 return waitFor('Make sure the start event was received', |
| 130 function() { | 127 function() { |
| 131 return startEventReceived; | 128 return startEventReceived; |
| 132 }); | 129 }); |
| 133 }) | 130 }) |
| 134 .catch(function(err) { | 131 .catch(function(err) { |
| 135 return failTest(err.toString()); | 132 return failTest(err.toString()); |
| 136 }) | 133 }) |
| 137 .then(function() { | 134 .then(function() { |
| 138 reportTestSuccess(); | 135 reportTestSuccess(); |
| 139 }); | 136 }); |
| 140 } | 137 } |
| 141 | 138 |
| 142 // Tests that the MediaRecorder's stop() function will effectively cause the | 139 // Tests that the MediaRecorder's stop() function will effectively cause the |
| 143 // |state| to be 'inactive' and that a 'stop' event is fired. | 140 // |state| to be 'inactive' and that a 'stop' event is fired. |
| 144 function testStartStopAndRecorderState() { | 141 function testStartStopAndRecorderState() { |
| 145 var theRecorder; | |
| 146 var stopEventReceived = false; | 142 var stopEventReceived = false; |
| 147 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) | 143 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) |
| 148 .then(function(stream) { | 144 .then(function(stream) { |
| 149 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); | 145 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); |
| 150 }) | 146 }) |
| 151 .then(function(recorder) { | 147 .then(function(recorder) { |
| 152 recorder.onstop = function(event) { | 148 recorder.onstop = function(event) { |
| 153 stopEventReceived = true; | 149 stopEventReceived = true; |
| 154 assertEquals('inactive', theRecorder.state); | 150 assertEquals('inactive', recorder.state); |
| 155 }; | 151 }; |
| 156 recorder.stop(); | 152 recorder.stop(); |
| 157 }) | 153 }) |
| 158 .then(function() { | 154 .then(function() { |
| 159 return waitFor('Make sure the stop event was received', | 155 return waitFor('Make sure the stop event was received', |
| 160 function() { | 156 function() { |
| 161 return stopEventReceived; | 157 return stopEventReceived; |
| 162 }); | 158 }); |
| 163 }) | 159 }) |
| 164 .catch(function(err) { | 160 .catch(function(err) { |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 288 return createMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); | 284 return createMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); |
| 289 }) | 285 }) |
| 290 .then(function(recorder) { | 286 .then(function(recorder) { |
| 291 assertThrows(function() {recorder.resume()}, 'Calling resume() in' + | 287 assertThrows(function() {recorder.resume()}, 'Calling resume() in' + |
| 292 ' inactive state should cause a DOM error'); | 288 ' inactive state should cause a DOM error'); |
| 293 }); | 289 }); |
| 294 } | 290 } |
| 295 | 291 |
| 296 // Tests that MediaRecorder sends data blobs when resume() is called. | 292 // Tests that MediaRecorder sends data blobs when resume() is called. |
| 297 function testResumeAndDataAvailable() { | 293 function testResumeAndDataAvailable() { |
| 298 var theRecorder; | |
| 299 var videoSize = 0; | 294 var videoSize = 0; |
| 300 var emptyBlobs = 0; | 295 var emptyBlobs = 0; |
| 301 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) | 296 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) |
| 302 .then(function(stream) { | 297 .then(function(stream) { |
| 303 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); | 298 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); |
| 304 }) | 299 }) |
| 305 .then(function(recorder) { | 300 .then(function(recorder) { |
| 306 theRecorder = recorder; | 301 recorder.pause(); |
| 307 theRecorder.pause(); | 302 recorder.ondataavailable = function(event) { |
| 308 }) | |
| 309 .then(function() { | |
| 310 theRecorder.ondataavailable = function(event) { | |
| 311 if (event.data.size > 0) { | 303 if (event.data.size > 0) { |
| 312 videoSize += event.data.size; | 304 videoSize += event.data.size; |
| 313 } else { | 305 } else { |
| 314 console.log('This dataavailable event is empty', event); | 306 console.log('This dataavailable event is empty', event); |
| 315 emptyBlobs += 1; | 307 emptyBlobs += 1; |
| 316 } | 308 } |
| 317 }; | 309 }; |
| 318 }) | 310 recorder.resume(); |
| 319 .then(function() { | |
| 320 theRecorder.resume(); | |
| 321 }) | 311 }) |
| 322 .then(function() { | 312 .then(function() { |
| 323 return waitFor('Make sure the recording has data after resuming', | 313 return waitFor('Make sure the recording has data after resuming', |
| 324 function() { | 314 function() { |
| 325 return videoSize > 0; | 315 return videoSize > 0; |
| 326 }); | 316 }); |
| 327 }) | 317 }) |
| 328 .then(function() { | 318 .then(function() { |
| 329 // There should be no empty blob while recording. | 319 // There should be no empty blob while recording. |
| 330 assertTrue(emptyBlobs == 0, 'Recording has ' + emptyBlobs + | 320 assertTrue(emptyBlobs == 0, 'Recording has ' + emptyBlobs + |
| 331 ' empty blobs, there should be no such empty blobs.'); | 321 ' empty blobs, there should be no such empty blobs.'); |
| 332 }) | 322 }) |
| 333 .catch(function(err) { | 323 .catch(function(err) { |
| 334 return failTest(err.toString()); | 324 return failTest(err.toString()); |
| 335 }) | 325 }) |
| 336 .then(function() { | 326 .then(function() { |
| 337 reportTestSuccess(); | 327 reportTestSuccess(); |
| 338 }); | 328 }); |
| 339 } | 329 } |
| 340 | 330 |
| 341 // Tests that when paused the recorder will transition |state| to |paused| and | 331 // Tests that when paused the recorder will transition |state| to |paused| and |
| 342 // then trigger a |pause| event. | 332 // then trigger a |pause| event. |
| 343 function testPauseAndRecorderState() { | 333 function testPauseAndRecorderState() { |
| 344 var theRecorder; | |
| 345 var pauseEventReceived = false; | 334 var pauseEventReceived = false; |
| 346 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) | 335 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) |
| 347 .then(function(stream) { | 336 .then(function(stream) { |
| 348 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); | 337 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); |
| 349 }) | 338 }) |
| 350 .then(function(recorder) { | 339 .then(function(recorder) { |
| 351 theRecorder = recorder; | 340 recorder.onpause = function(event) { |
| 352 theRecorder.onpause = function(event) { | |
| 353 pauseEventReceived = true; | 341 pauseEventReceived = true; |
| 354 assertEquals('paused', theRecorder.state); | 342 assertEquals('paused', recorder.state); |
| 355 }; | 343 } |
| 356 theRecorder.pause(); | 344 recorder.pause(); |
| 357 }) | 345 }) |
| 358 .then(function() { | 346 .then(function() { |
| 359 return waitFor('Making sure the pause event has been received', | 347 return waitFor('Making sure the pause event has been received', |
| 360 function() { | 348 function() { |
| 361 return pauseEventReceived; | 349 return pauseEventReceived; |
| 362 }); | 350 }); |
| 363 }) | 351 }) |
| 364 .catch(function(err) { | 352 .catch(function(err) { |
| 365 return failTest(err.toString()); | 353 return failTest(err.toString()); |
| 366 }) | 354 }) |
| 367 .then(function() { | 355 .then(function() { |
| 368 reportTestSuccess(); | 356 reportTestSuccess(); |
| 369 }); | 357 }); |
| 370 } | 358 } |
| 371 | 359 |
| 372 // Tests that is is possible to stop a paused MediaRecorder and that the |state| | 360 // Tests that is is possible to stop a paused MediaRecorder and that the |state| |
| 373 // becomes 'inactive'. | 361 // becomes 'inactive'. |
| 374 function testPauseStopAndRecorderState() { | 362 function testPauseStopAndRecorderState() { |
| 375 var theRecorder; | |
| 376 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) | 363 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) |
| 377 .then(function(stream) { | 364 .then(function(stream) { |
| 378 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); | 365 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); |
| 379 }) | 366 }) |
| 380 .then(function(recorder) { | 367 .then(function(recorder) { |
| 381 theRecorder = recorder; | 368 recorder.pause(); |
| 382 theRecorder.pause(); | 369 recorder.stop(); |
| 383 }) | 370 assertEquals('inactive', recorder.state); |
| 384 .then(function() { | |
| 385 theRecorder.stop(); | |
| 386 }) | |
| 387 .then(function() { | |
| 388 assertEquals('inactive', theRecorder.state); | |
| 389 }) | 371 }) |
| 390 .catch(function(err) { | 372 .catch(function(err) { |
| 391 return failTest(err.toString()); | 373 return failTest(err.toString()); |
| 392 }) | 374 }) |
| 393 .then(function() { | 375 .then(function() { |
| 394 reportTestSuccess(); | 376 reportTestSuccess(); |
| 395 }); | 377 }); |
| 396 } | 378 } |
| 397 | 379 |
| 398 // Tests that no dataavailable event is fired after MediaRecorder's pause() | 380 // Tests that no dataavailable event is fired after MediaRecorder's pause() |
| 399 // function is called. | 381 // function is called. |
| 400 function testPausePreventsDataavailableFromBeingFired() { | 382 function testPausePreventsDataavailableFromBeingFired() { |
| 401 var theRecorder; | |
| 402 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) | 383 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) |
| 403 .then(function(stream) { | 384 .then(function(stream) { |
| 404 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); | 385 return createAndStartMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); |
| 405 }) | 386 }) |
| 406 .then(function(recorder) { | 387 .then(function(recorder) { |
| 407 theRecorder = recorder; | 388 recorder.pause(); |
| 408 theRecorder.pause(); | 389 recorder.ondataavailable = function(event) { |
| 409 }) | |
| 410 .then(function() { | |
| 411 theRecorder.ondataavailable = function(event) { | |
| 412 failTest('Received unexpected data after pause!'); | 390 failTest('Received unexpected data after pause!'); |
| 413 }; | 391 }; |
| 414 }) | 392 }) |
| 415 .then(function() { | 393 .then(function() { |
| 416 return waitDuration(2000); | 394 return waitDuration(2000); |
| 417 }) | 395 }) |
| 418 .catch(function(err) { | 396 .catch(function(err) { |
| 419 return failTest(err.toString()); | 397 return failTest(err.toString()); |
| 420 }) | 398 }) |
| 421 .then(function() { | 399 .then(function() { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 549 .then(function(stream) { | 527 .then(function(stream) { |
| 550 return createMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); | 528 return createMediaRecorder(stream, DEFAULT_RECORDER_MIME_TYPE); |
| 551 }) | 529 }) |
| 552 .then(function(recorder) { | 530 .then(function(recorder) { |
| 553 assertThrows(function() {recorder.requestData()}, | 531 assertThrows(function() {recorder.requestData()}, |
| 554 'Calling requestdata() in inactive state should throw a DOM ' + | 532 'Calling requestdata() in inactive state should throw a DOM ' + |
| 555 'Exception'); | 533 'Exception'); |
| 556 }); | 534 }); |
| 557 } | 535 } |
| 558 | 536 |
| 537 // Tests that MediaRecorder fires an Error Event when the associated MediaStream |
| 538 // gets a Track added. |
| 539 function testAddingTrackToMediaStreamFiresErrorEvent() { |
| 540 var theStream; |
| 541 var errorEventReceived = false; |
| 542 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) |
| 543 .then(function(stream) { |
| 544 theStream = stream; |
| 545 return createMediaRecorder(stream); |
| 546 }) |
| 547 .then(function(recorder) { |
| 548 recorder.onerror = function(event) { |
| 549 errorEventReceived = true; |
| 550 }; |
| 551 recorder.start(); |
| 552 // Add a new track, copy of an existing one for simplicity. |
| 553 theStream.addTrack(theStream.getTracks()[1].clone()); |
| 554 }) |
| 555 .then(function() { |
| 556 return waitFor('Waiting for the Error Event', |
| 557 function() { |
| 558 return errorEventReceived; |
| 559 }); |
| 560 }) |
| 561 .catch(function(err) { |
| 562 return failTest(err.toString()); |
| 563 }) |
| 564 .then(function() { |
| 565 reportTestSuccess(); |
| 566 }); |
| 567 } |
| 568 |
| 569 // Tests that MediaRecorder fires an Error Event when the associated MediaStream |
| 570 // gets a Track removed. |
| 571 function testRemovingTrackFromMediaStreamFiresErrorEvent() { |
| 572 var theStream; |
| 573 var errorEventReceived = false; |
| 574 navigator.mediaDevices.getUserMedia(DEFAULT_CONSTRAINTS) |
| 575 .then(function(stream) { |
| 576 theStream = stream; |
| 577 return createMediaRecorder(stream); |
| 578 }) |
| 579 .then(function(recorder) { |
| 580 recorder.onerror = function(event) { |
| 581 errorEventReceived = true; |
| 582 }; |
| 583 recorder.start(); |
| 584 theStream.removeTrack(theStream.getTracks()[1]); |
| 585 }) |
| 586 .then(function() { |
| 587 return waitFor('Waiting for the Error Event', |
| 588 function() { |
| 589 return errorEventReceived; |
| 590 }); |
| 591 }) |
| 592 .catch(function(err) { |
| 593 return failTest(err.toString()); |
| 594 }) |
| 595 .then(function() { |
| 596 reportTestSuccess(); |
| 597 }); |
| 598 } |
| 599 |
| 559 </script> | 600 </script> |
| 560 </body> | 601 </body> |
| 561 </html> | 602 </html> |
| OLD | NEW |