test_background_video_suspend_ready_state.html (2618B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <title>Check element's ready state while suspending video decoding</title> 5 <script src="/tests/SimpleTest/SimpleTest.js"></script> 6 <script src="manifest.js"></script> 7 <script src="background_video.js"></script> 8 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 9 <script type="application/javascript"> 10 11 /** 12 * This test is used to ensure that the media element's ready state won't be 13 * incorrectly changed to `HAVE_METADATA` or lower when seeking happens on a 14 * null decoder that is caused by suspending video decoding. 15 */ 16 add_task(async function setupTestingPref() { 17 await SpecialPowers.pushPrefEnv({ 18 set: [ 19 ["media.test.video-suspend", true], 20 ["media.suspend-background-video.enabled", true], 21 ["media.suspend-background-video.delay-ms", 0], 22 ], 23 }); 24 }); 25 26 add_task(async function testReadyStateWhenSuspendingVideoDecoding() { 27 const video = await createPlayingVideo(); 28 assertVideoReadyStateIsSufficientForPlaying(video); 29 await suspendVideoDecoding(video); 30 await seekVideo(video); 31 assertVideoReadyStateIsSufficientForPlaying(video); 32 }); 33 34 async function createPlayingVideo() { 35 let video = document.createElement("video"); 36 video.src = "gizmo.mp4"; 37 video.controls = true; 38 video.loop = true; 39 document.body.appendChild(video); 40 ok(await video.play().then(_=>true, _=>false), "video started playing"); 41 return video; 42 } 43 44 function assertVideoReadyStateIsSufficientForPlaying(video) { 45 ok(video.readyState > HTMLMediaElement.HAVE_METADATA, 46 `Ready state ${video.readyState} is suffient for playing`); 47 } 48 49 async function suspendVideoDecoding(video) { 50 video.setVisible(false); 51 nextVideoSuspends(video); 52 info(`suspended video decoding`); 53 // Because the suspend event we received can only indicate MDSM finishes the 54 // setup of suspending decoding, but the actual setting the null decoder 55 // happens on MediaFormatReader where we are not able to observe the behavior 56 // via event. Instread of implementing something in MFR to propagate the event 57 // or changing the timing of current suspend event, which might increase the 58 // maintenance effect, Here choose to use a simple workaround to wait for a 59 // short while to ensure the decoding has been switched to the null decoder. 60 // eslint-disable-next-line mozilla/no-arbitrary-setTimeout 61 await new Promise(resolve => setTimeout(resolve, 2000)); 62 } 63 64 async function seekVideo(video) { 65 video.currentTime = 0; 66 ok(await new Promise(r => video.onseeked = r).then(_=>true, _=>false), 67 `seeking completed`); 68 } 69 70 </script> 71 </head> 72 <body> 73 </body> 74 </html>