| <!DOCTYPE html> |
| <html> |
| <head> |
| <script src="media-source-loader.js"></script> |
| <script src="../resources/runner.js"></script> |
| <script> |
| var loader; |
| |
| window.addEventListener('load', () => { |
| loader = new MediaSourceLoader('test-fragmented-video.json'); |
| loader.loadMediaData().then(runTest); |
| }); |
| |
| function *range(start, end) { |
| while (start < end) |
| yield(start++); |
| } |
| |
| function addVideos(count, autoplay) { |
| return new Promise((resolve, reject) => { |
| var promises = []; |
| var videos = []; |
| for (var i of range(0, count)) { |
| var video = document.createElement('video'); |
| video.controls = false; |
| video.loop = true; |
| video.muted = true; |
| document.body.appendChild(video); |
| promises.push(loadMediaDataIntoVideo(video)); |
| videos.push(video); |
| } |
| document.getElementById('video-count').innerText = videoCount(); |
| Promise.all(promises).then(() => { |
| resolve(videos); |
| }); |
| }); |
| } |
| |
| function removeVideos(count) { |
| while (count > 0) { |
| --count; |
| var video = document.querySelector('video:last-child'); |
| video.src = ''; |
| video.load(); |
| document.body.removeChild(video); |
| } |
| document.getElementById('video-count').innerText = videoCount(); |
| } |
| |
| function loadMediaDataIntoVideo(video) { |
| return new Promise((resolve, reject) => { |
| var source = new MediaSource(); |
| source.addEventListener('sourceopen', (e) => { |
| var source = e.target; |
| var currentMediaSegment = 0; |
| var sourceBuffer = source.addSourceBuffer(loader.type); |
| var mediaSegments = loader.mediaSegments(); |
| sourceBuffer.appendBuffer(loader.initSegment); |
| sourceBuffer.addEventListener('update', () => { |
| if (source.readyState === 'closed') { |
| resolve(video); |
| return; |
| } |
| var nextSegment = mediaSegments.next(); |
| if (nextSegment.done) { |
| if (source.readyState !== 'ended') { |
| source.endOfStream(); |
| resolve(video); |
| } |
| return; |
| } |
| |
| sourceBuffer.appendBuffer(nextSegment.value); |
| }); |
| sourceBuffer.addEventListener('error', (e) => { |
| reject(); |
| }); |
| }); |
| video.src = URL.createObjectURL(source); |
| }); |
| } |
| |
| function videoCount() { |
| return document.querySelectorAll('video').length; |
| } |
| |
| function totalDroppedFrames() { |
| var total = 0; |
| for (var video of document.querySelectorAll('video')) { |
| if (typeof(video.getVideoPlaybackQuality) !== 'undefined') |
| total += video.getVideoPlaybackQuality().droppedVideoFrames; |
| else if (typeof(video.webkitDroppedFrameCount) !== 'undefined') |
| total += video.webkitDroppedFrameCount; |
| } |
| return total; |
| } |
| |
| function pauseAll() { |
| for (var video of document.querySelectorAll('video')) |
| video.pause(); |
| } |
| |
| function playVideos(videos) { |
| return new Promise((resolve, reject) => { |
| var promises = []; |
| for (var video of videos) |
| promises.push(video.play()); |
| Promise.all(promises).then(() => { resolve(videos); }); |
| }); |
| } |
| |
| function playAll() { |
| playVideos(document.querySelectorAll('video')); |
| } |
| |
| function runTest() { |
| addVideos(initialVideoCount).then(playVideos); |
| trySeekingFaster(1.6); |
| } |
| |
| function finishTest() { |
| pauseAll(); |
| } |
| |
| var initialVideoCount = 10; |
| var droppedFrameLimit = 1; |
| var initialPlaybackRate = 1; |
| |
| function trySeekingFaster(value) { |
| initialPlaybackRate += value; |
| document.getElementById('video-speed').innerText = initialPlaybackRate; |
| for (var video of document.querySelectorAll('video')) |
| video.playbackRate = initialPlaybackRate; |
| |
| |
| setTimeout(() => { |
| var initialDroppedFrames = totalDroppedFrames(); |
| |
| setTimeout(() => { |
| var endingDroppedFrames = totalDroppedFrames(); |
| document.getElementById('dropped-frame').innerText = endingDroppedFrames - initialDroppedFrames; |
| |
| if (endingDroppedFrames - initialDroppedFrames <= droppedFrameLimit) { |
| if (value <= 0.05) { |
| finishTest(); |
| return; |
| } |
| |
| trySeekingFaster(value); |
| } |
| else |
| trySeekingSlower(value/2); |
| }, 1000); |
| }, 1000); |
| } |
| |
| function trySeekingSlower(value) { |
| initialPlaybackRate -= value; |
| document.getElementById('video-speed').innerText = initialPlaybackRate; |
| for (var video of document.querySelectorAll('video')) |
| video.playbackRate = initialPlaybackRate; |
| |
| setTimeout(() => { |
| var initialDroppedFrames = totalDroppedFrames(); |
| setTimeout(() => { |
| var endingDroppedFrames = totalDroppedFrames(); |
| document.getElementById('dropped-frame').innerText = endingDroppedFrames - initialDroppedFrames; |
| |
| if (endingDroppedFrames - initialDroppedFrames <= droppedFrameLimit) { |
| if (value <= 0.05) { |
| finishTest(); |
| return; |
| } |
| |
| trySeekingFaster(value/2); |
| } else |
| trySeekingSlower(value); |
| }, 2000); |
| }, 2000); |
| } |
| |
| </script> |
| </head> |
| <body> |
| <div> |
| Video Count: <span id="video-count">0</span> Speed: <span id="video-speed">0</span> Dropped Frame Delta: <span id="dropped-frame">0</span> |
| </div> |
| <div> |
| <button onclick="addVideos(1).then(playVideos)">add video</button><button onclick="removeVideos(1)">remove video</button><button onclick="pauseAll()">pause</button><button onclick="playAll()">play</button><br> |
| </div> |
| </body> |
| </html> |