MediaRecorder-pause-resume.html (6198B)
1 <!doctype html> 2 <html> 3 <head> 4 <title>MediaRecorder Pause and Resume</title> 5 <meta name=timeout content=long> 6 <meta name=variant content="?mimeType=''"> 7 <meta name=variant content="?mimeType=video/webm;codecs=vp8,opus"> 8 <meta name=variant content="?mimeType=video/webm;codecs=vp9,opus"> 9 <meta name=variant content="?mimeType=video/webm;codecs=av1,opus"> 10 <meta name=variant content="?mimeType=video/mp4;codecs=avc1.64003E,mp4a.40.2"> 11 <meta name=variant content="?mimeType=video/mp4;codecs=avc3.64003E,mp4a.40.2"> 12 <meta name=variant content="?mimeType=video/mp4;codecs=avc1.64003E,opus"> 13 <meta name=variant content="?mimeType=video/mp4;codecs=avc3.64003E,opus"> 14 <meta name=variant content="?mimeType=video/mp4;codecs=vp9,opus"> 15 <meta name=variant content="?mimeType=video/mp4;codecs=vp9,mp4a.40.2"> 16 <meta name=variant content="?mimeType=video/mp4;codecs=av01,opus"> 17 <meta name=variant content="?mimeType=video/mp4;codecs=av01,mp4a.40.2"> 18 <meta name=variant content="?mimeType=video/mp4;codecs=hvc1.1.6.L186.B0,opus"> 19 <meta name=variant content="?mimeType=video/mp4;codecs=hev1.1.6.L186.B0,opus"> 20 <meta name=variant content="?mimeType=video/mp4;codecs=hvc1.1.6.L186.B0,mp4a.40.2"> 21 <meta name=variant content="?mimeType=video/mp4;codecs=hev1.1.6.L186.B0,mp4a.40.2"> 22 <meta name=variant content="?mimeType=video/x-matroska;codecs=hvc1.1.6.L186.B0,opus"> 23 <meta name=variant content="?mimeType=video/x-matroska;codecs=hev1.1.6.L186.B0,opus"> 24 <meta name=variant content="?mimeType=video/mp4"> 25 <link rel="help" href="https://w3c.github.io/mediacapture-record/MediaRecorder.html#mediarecorder"> 26 <script src="/resources/testharness.js"></script> 27 <script src="/resources/testharnessreport.js"></script> 28 <script src="utils/sources.js"></script> 29 </head> 30 <body> 31 <script> 32 function recordEvents(target, events) { 33 let arr = []; 34 for (let ev of events) { 35 target.addEventListener(ev, _ => arr.push(ev)); 36 } 37 return arr; 38 } 39 40 const params = new URLSearchParams(window.location.search); 41 const mimeType = params.get('mimeType'); 42 const tag = `mimeType "${mimeType}"`; 43 promise_test(async t => { 44 const { stream: video } = createFlowingVideoStream(t); 45 if (mimeType && !MediaRecorder.isTypeSupported(mimeType)) { 46 promise_test(async t => { 47 assert_throws_dom('NotSupportedError', 48 () => new MediaRecorder(video, { mimeType })); 49 }, `MediaRecorder constructor throws on no support 1st, ${mimeType}`); 50 return; 51 } 52 53 const recorder = new MediaRecorder(video, {mimeType}); 54 const events = recordEvents(recorder, 55 ["start", "stop", "dataavailable", "pause", "resume", "error"]); 56 57 recorder.start(); 58 assert_equals(recorder.state, "recording", "MediaRecorder has been started successfully"); 59 await new Promise(r => recorder.onstart = r); 60 61 recorder.pause(); 62 assert_equals(recorder.state, "paused", "MediaRecorder should be paused immediately following pause()"); 63 64 // A second call to pause should be idempotent 65 recorder.pause(); 66 assert_equals(recorder.state, "paused", "MediaRecorder should be paused immediately following pause()"); 67 68 let event = await new Promise(r => recorder.onpause = r); 69 assert_equals(event.type, "pause", "the event type should be pause"); 70 assert_true(event.isTrusted, "isTrusted should be true when the event is created by C++"); 71 72 recorder.resume(); 73 assert_equals(recorder.state, "recording", "MediaRecorder state should be recording immediately following resume() call"); 74 75 // A second call to resume should be idempotent 76 recorder.resume(); 77 assert_equals(recorder.state, "recording", "MediaRecorder state should be recording immediately following resume() call"); 78 79 event = await new Promise(r => recorder.onresume = r); 80 assert_equals(event.type, "resume", "the event type should be resume"); 81 assert_true(event.isTrusted, "isTrusted should be true when the event is created by C++"); 82 83 recorder.stop(); 84 await new Promise(r => recorder.onstop = r); 85 86 assert_array_equals(events, ["start", "pause", "resume", "dataavailable", "stop"], 87 "Should have gotten expected events"); 88 }, `MediaRecorder handles pause() and resume() state and events, ${tag}`); 89 90 promise_test(async t => { 91 const { stream: video } = createFlowingVideoStream(t); 92 if (mimeType && !MediaRecorder.isTypeSupported(mimeType)) { 93 promise_test(async t => { 94 assert_throws_dom('NotSupportedError', 95 () => new MediaRecorder(video, { mimeType })); 96 }, `MediaRecorder constructor throws on no support 2nd, ${mimeType}`); 97 return; 98 } 99 const recorder = new MediaRecorder(video, {mimeType}); 100 const events = recordEvents(recorder, 101 ["start", "stop", "dataavailable", "pause", "resume", "error"]); 102 103 recorder.start(); 104 assert_equals(recorder.state, "recording", "MediaRecorder has been started successfully"); 105 await new Promise(r => recorder.onstart = r); 106 107 recorder.pause(); 108 assert_equals(recorder.state, "paused", "MediaRecorder should be paused immediately following pause()"); 109 let event = await new Promise(r => recorder.onpause = r); 110 assert_equals(event.type, "pause", "the event type should be pause"); 111 assert_true(event.isTrusted, "isTrusted should be true when the event is created by C++"); 112 113 recorder.stop(); 114 assert_equals(recorder.state, "inactive", "MediaRecorder should be inactive after being stopped"); 115 await new Promise(r => recorder.onstop = r); 116 117 recorder.start(); 118 assert_equals(recorder.state, "recording", "MediaRecorder has been started successfully"); 119 await new Promise(r => recorder.onstart = r); 120 121 assert_array_equals(events, ["start", "pause", "dataavailable", "stop", "start"], 122 "Should have gotten expected events"); 123 }, `MediaRecorder handles stop() in paused state appropriately, ${tag}`); 124 125 </script> 126 </body> 127 </html>