blob: 9f38cfdd64c1e831c7659b66220846b8ba246e8e [file] [log] [blame]
<!DOCTYPE html>
<html lang="en" class="reftest-wait">
<head>
<meta charset="UTF-8">
<title>HTML MSE test: video is shown</title>
<link rel="author" title="Alicia Boya GarcĂ­a" href="mailto:aboya@igalia.com">
<link rel="match" href="mediasource-video-is-visible-expected.html">
<meta name="fuzzy" content="maxDifference=30;totalPixels=76800">
<meta name="assert" content="Video is rendered in the MSE player.">
<style>
html, body {
margin: 0;
padding: 0;
overflow: hidden;
background: white;
}
body {
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
}
#video {
width: 320px;
height: 240px;
}
#explanation {
position: absolute;
top: 260px;
}
</style>
</head>
<body>
<video id="video"></video>
<div id="explanation">A video containing a blue static image should be visible above.</div>
<script>
if ("testRunner" in window)
// WebKit reftests use a different mechanism for delaying the test finish.
testRunner.waitUntilDone();
const mediaElement = document.getElementById("video");
class NetworkError extends Error {
constructor(message) {
super(message);
}
}
function requestJSON(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "text";
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(JSON.parse(xhr.responseText));
} else {
reject(new NetworkError(`Error ${xhr.status}`));
}
}
};
xhr.send(null);
});
}
function requestBinaryMedia(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.responseType = "arraybuffer";
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300) {
resolve(xhr.response);
} else {
reject(new NetworkError(`Error ${xhr.status}`));
}
}
};
xhr.send(null);
})
}
function waitForEvent(element, eventName) {
return new Promise(resolve => {
element.addEventListener(eventName, function handler() {
element.removeEventListener(eventName, handler);
resolve();
})
});
}
function waitForAppend(sourceBuffer, data) {
return new Promise(resolve => {
const listener = () => {
sourceBuffer.removeEventListener("update", listener);
resolve();
};
sourceBuffer.addEventListener("update", listener);
sourceBuffer.appendBuffer(data);
});
}
let mediaSource;
let audioSB;
let videoSB;
async function main(audioType, audioUrl, videoType, videoUrl) {
const audioManifest = await requestJSON(audioUrl);
const videoManifest = await requestJSON(videoUrl);
const audioData = await requestBinaryMedia(audioManifest.url);
const videoData = await requestBinaryMedia(videoManifest.url);
mediaSource = new MediaSource();
mediaElement.src = window.URL.createObjectURL(mediaSource);
mediaElement.volume = 0.1;
await waitForEvent(mediaSource, "sourceopen");
audioSB = mediaSource.addSourceBuffer(audioType);
videoSB = mediaSource.addSourceBuffer(videoType);
await waitForAppend(audioSB, audioData.slice(0, audioManifest.init.size));
await waitForAppend(videoSB, videoData.slice(0, videoManifest.init.size));
await waitForAppend(audioSB, audioData.slice(audioManifest.init.size));
await waitForAppend(videoSB, videoData.slice(videoManifest.init.size));
mediaSource.endOfStream();
mediaElement.play();
await waitForEvent(mediaElement, "ended");
if ("testRunner" in window)
testRunner.notifyDone();
document.documentElement.classList.remove("reftest-wait");
}
function selectAlternative(alternatives) {
for (let alternative of alternatives) {
if (MediaSource.isTypeSupported(alternative.mimeType))
return [alternative.mimeType, alternative.url];
}
throw new Error("Could not find suitable alternative");
}
const [audioType, audioUrl] = selectAlternative([
{mimeType: 'audio/mp4; codecs="mp4a.40.2"', url: "mp4/test-a-1s.mp4-manifest.json"},
{mimeType: 'audio/webm; codecs="opus"', url: "webm/test-a-1s.webm-manifest.json"},
]);
const [videoType, videoUrl] = selectAlternative([
{mimeType: 'video/mp4; codecs="avc1.42C015"', url: "mp4/test-v-1s-blue.mp4-manifest.json"},
{mimeType: 'video/webm; codecs="vp9"', url: "webm/test-v-1s-blue.webm-manifest.json"},
]);
main(audioType, audioUrl, videoType, videoUrl);
</script>
</body>
</html>