blob: 447871e99b7b7f00e1ffdf9bab8cd9a56dd9012a [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<script>
let stream = null;
function promptForCapture()
{
navigator.mediaDevices.enumerateDevices().then(() => {
return navigator.mediaDevices.getUserMedia({ audio: false, video: true })
}).then((s) => {
stream = s;
video.srcObject = stream;
console.log("Got user media");
}).catch((error) => console.log(`Failed with error: ${error}`));
}
function stop(kind)
{
let activeTracks = [];
stream.getTracks().forEach(track => {
if (!kind || track.kind == kind)
track.stop();
else
activeTracks.push(track);
});
if (!activeTracks.length) {
stream = null;
video.srcObject = null;
}
}
function haveStream()
{
return stream !== null;
}
function doMultipleGetUserMediaSynchronously()
{
navigator.mediaDevices.getUserMedia({video: true});
navigator.mediaDevices.getUserMedia({video: true});
navigator.mediaDevices.getUserMedia({video: true});
// This one should prompt.
navigator.mediaDevices.getUserMedia({audio: true});
navigator.mediaDevices.getUserMedia({audio: true});
navigator.mediaDevices.getUserMedia({audio: true});
navigator.mediaDevices.getUserMedia({audio: true, video: true});
}
function captureAudio()
{
navigator.mediaDevices.getUserMedia({audio: true}).then(s => stream = s);
}
function captureVideo()
{
navigator.mediaDevices.getUserMedia({video: true}).then(s => video.srcObject = s);
}
function captureAudioAndVideo(notifySuccess)
{
navigator.mediaDevices.getUserMedia({audio: true, video: true}).then(s => {
if (notifySuccess)
window.webkit.messageHandlers.gum.postMessage("PASS");
stream = s;
});
}
function notifyEndedEvent()
{
if (!stream || !stream.getVideoTracks().length) {
window.webkit.messageHandlers.gum.postMessage("No stream or video track");
return;
}
let waitForEndedEvent = true;
stream.getVideoTracks()[0].onended = () => {
if (!waitForEndedEvent)
return;
waitForEndedEvent = false;
window.webkit.messageHandlers.gum.postMessage("PASS");
}
setTimeout(() => {
if (!waitForEndedEvent)
return;
waitForEndedEvent = false;
window.webkit.messageHandlers.gum.postMessage("Did not receive an ended event after 5 seconds");
}, 5000);
}
function checkGetCapabilities() {
window.webkit.messageHandlers.gum.postMessage(RTCRtpSender.getCapabilities('video') != null ? "PASS" : "FAIL checkGetCapabilities");
}
function getStats(connection, type, kind)
{
return connection.getStats().then((report) => {
var stats;
report.forEach((statItem) => {
if (statItem.type === type && statItem.kind === kind) {
stats = statItem;
}
});
return stats;
});
}
var pc1, pc2;
function createConnection() {
pc1 = new RTCPeerConnection();
pc2 = new RTCPeerConnection();
pc1.onicecandidate = (e) => { if (e.candidate) pc2.addIceCandidate(e.candidate) }
pc2.onicecandidate = (e) => { if (e.candidate) pc1.addIceCandidate(e.candidate) }
stream.getTracks().forEach(track => pc1.addTrack(track, stream));
pc1.createOffer()
.then((o) => pc1.setLocalDescription(o))
.then(() => pc2.setRemoteDescription(pc1.localDescription))
.then(() => pc2.createAnswer())
.then((a) => pc2.setLocalDescription(a))
.then((a) => pc1.setRemoteDescription(pc2.localDescription))
.then(() => {
window.webkit.messageHandlers.gum.postMessage("PASS");
});
}
function checkVideoStatus(counter) {
if (!counter)
counter = 0;
else if (counter > 100) {
window.webkit.messageHandlers.gum.postMessage("FAIL checkVideoStatus");
return;
}
getStats(pc1, "outbound-rtp", "video").then((stats) => {
if (stats && stats.framesEncoded) {
window.webkit.messageHandlers.gum.postMessage("PASS");
return;
}
setTimeout(() => checkVideoStatus(++counter), 50);
});
}
function checkDecodingVideoCounterIncreases(counter, framesDecoded) {
if (!counter)
counter = 0;
getStats(pc2, "inbound-rtp", "video").then((stats) => {
if (stats && stats.framesDecoded > framesDecoded) {
window.webkit.messageHandlers.gum.postMessage("PASS");
return;
}
if (counter > 100) {
window.webkit.messageHandlers.gum.postMessage("FAIL checkDecodingVideoCounterIncreases " + framesDecoded + " " + JSON.stringify(stats));
return;
}
setTimeout(() => checkDecodingVideoCounterIncreases(++counter, framesDecoded), 50);
});
}
function checkDecodingVideo(counter) {
if (!counter)
counter = 0;
getStats(pc2, "inbound-rtp", "video").then((stats) => {
if (stats && stats.framesDecoded > 0) {
checkDecodingVideoCounterIncreases(counter, stats.framesDecoded);
return;
}
if (counter > 100) {
window.webkit.messageHandlers.gum.postMessage("FAIL checkDecodingVideo " + JSON.stringify(stats));
return;
}
setTimeout(() => checkDecodingVideo(++counter), 50);
});
}
function checkAudioStatus(counter) {
if (!counter)
counter = 0;
else if (counter > 100) {
window.webkit.messageHandlers.gum.postMessage("FAIL checkAudioStatus");
return;
}
getStats(pc2, "inbound-rtp", "audio").then((stats) => {
if (stats && stats.audioLevel > 0) {
window.webkit.messageHandlers.gum.postMessage("PASS");
return;
}
setTimeout(() => checkAudioStatus(++counter), 50);
});
}
function changeConstraints() {
async function doChangeConstraints() {
const videoTrack = stream.getVideoTracks()[0];
await videoTrack.applyConstraints({ width: 320, height: 240, frameRate: 5});
const audioTrack = stream.getAudioTracks()[0];
await audioTrack.applyConstraints({ echoCancellation: false });
}
doChangeConstraints().then(() => {
window.webkit.messageHandlers.gum.postMessage("PASS");
}, (e) => {
window.webkit.messageHandlers.gum.postMessage("FAIL doChangeConstraints: " + e);
});
}
function checkConstraintsStatus() {
async function doCheckConstraints() {
video2.srcObject = stream;
await video2.play();
if (video2.videoWidth !== 320) {
window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraints, width is not 320 but " + video.videoWidth);
return;
}
if (video2.videoHeight !== 240) {
window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraints, height is not 240 but " + video.videoHeight);
return;
}
let settings = stream.getVideoTracks()[0].getSettings();
if (settings.width !== 320 && settings.height !== 240) {
window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraints, video settings are not correct");
return;
}
settings = stream.getAudioTracks()[0].getSettings();
if (settings.echoCancellation) {
window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraints, audio settings are not correct");
return;
}
window.webkit.messageHandlers.gum.postMessage("PASS");
}
doCheckConstraints().catch(e => {
window.webkit.messageHandlers.gum.postMessage("FAIL checkConstraintsStatus, " + e);
});
}
</script>
<head>
<body onload="promptForCapture()">
<video id="video" controls playsinline autoplay></video>
<video id="video2" controls playsinline autoplay></video>
<p>
<button onclick="stop()">Stop</button>
</p>
</body>
</html>