Adding webrtc-sample demos under trunk/samples.
Review URL: https://webrtc-codereview.appspot.com/1126005 git-svn-id: http://webrtc.googlecode.com/svn/trunk@3578 4adac7df-926f-26a2-2b94-8c16560cd09d
This commit is contained in:
262
samples/js/demos/html/constraints-and-stats.html
Normal file
262
samples/js/demos/html/constraints-and-stats.html
Normal file
@@ -0,0 +1,262 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Constraints and Statistics</title>
|
||||
<script>
|
||||
var mystream;
|
||||
var pc1;
|
||||
var pc2;
|
||||
|
||||
$ = function(id) {
|
||||
return document.getElementById(id);
|
||||
}
|
||||
|
||||
function log(txt) {
|
||||
console.log(txt);
|
||||
}
|
||||
|
||||
function openCamera() {
|
||||
if (mystream) {
|
||||
mystream.stop();
|
||||
}
|
||||
navigator.webkitGetUserMedia(cameraConstraints(), gotStream, function() {
|
||||
log("GetUserMedia failed");
|
||||
});
|
||||
}
|
||||
|
||||
function gotStream(stream) {
|
||||
log("GetUserMedia succeeded");
|
||||
mystream = stream;
|
||||
$("local-video").src = webkitURL.createObjectURL(stream);
|
||||
}
|
||||
|
||||
function cameraConstraints() {
|
||||
var constraints = {};
|
||||
constraints.audio = true;
|
||||
constraints.video = { mandatory: {}, optional: [] };
|
||||
if ($("minwidth").value != "0") {
|
||||
constraints.video.mandatory.minWidth = $("minwidth").value;
|
||||
}
|
||||
if ($("maxwidth").value != "0") {
|
||||
constraints.video.mandatory.maxWidth = $("maxwidth").value;
|
||||
}
|
||||
if ($("minheight").value != "0") {
|
||||
constraints.video.mandatory.minHeight = $("minheight").value;
|
||||
}
|
||||
if ($("maxheight").value != "0") {
|
||||
constraints.video.mandatory.maxHeight = $("maxheight").value;
|
||||
}
|
||||
if ($("frameRate").value != "0") {
|
||||
constraints.video.mandatory.minFrameRate = $("frameRate").value;
|
||||
}
|
||||
log('Camera constraints are ' + JSON.stringify(constraints));
|
||||
$("cameraConstraints").innerHTML = JSON.stringify(constraints, null, ' ');
|
||||
return constraints;
|
||||
}
|
||||
|
||||
function streamConstraints() {
|
||||
var constraints = { mandatory: {}, optional: [] };
|
||||
if ($("bandwidth").value != "0") {
|
||||
constraints.optional[0] = { 'bandwidth' : $('bandwidth').value };
|
||||
}
|
||||
log('Constraints are ' + JSON.stringify(constraints));
|
||||
$("addStreamConstraints").innerHTML = JSON.stringify(constraints, null, ' ');
|
||||
return constraints;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function connect() {
|
||||
pc1 = new webkitRTCPeerConnection(null);
|
||||
pc2 = new webkitRTCPeerConnection(null);
|
||||
pc1.addStream(mystream, streamConstraints());
|
||||
log('PC1 creating offer');
|
||||
pc1.onnegotiationeeded = function() {
|
||||
log('Negotiation needed - PC1');
|
||||
}
|
||||
pc2.onnegotiationeeded = function() {
|
||||
log('Negotiation needed - PC2');
|
||||
}
|
||||
pc1.onicecandidate = function(e) {
|
||||
log('Candidate PC1');
|
||||
if (e.candidate) {
|
||||
pc2.addIceCandidate(new RTCIceCandidate(e.candidate));
|
||||
}
|
||||
}
|
||||
pc2.onicecandidate = function(e) {
|
||||
log('Candidate PC2');
|
||||
if (e.candidate) {
|
||||
pc1.addIceCandidate(new RTCIceCandidate(e.candidate));
|
||||
}
|
||||
}
|
||||
pc2.onaddstream = function(e) {
|
||||
log('PC2 got stream');
|
||||
$('remote-video').src = webkitURL.createObjectURL(e.stream);
|
||||
log('Remote video is ' + $('remote-video').src);
|
||||
}
|
||||
pc1.createOffer(function(desc) {
|
||||
log('PC1 offering');
|
||||
pc1.setLocalDescription(desc);
|
||||
pc2.setRemoteDescription(desc);
|
||||
pc2.createAnswer(function(desc2) {
|
||||
log('PC2 answering');
|
||||
pc2.setLocalDescription(desc2);
|
||||
pc1.setRemoteDescription(desc2);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// Display statistics
|
||||
var statCollector = setInterval(function() {
|
||||
var display = function(str) {
|
||||
$('bitrate').innerHTML = str;
|
||||
}
|
||||
|
||||
display("No stream");
|
||||
if (pc2 && pc2.remoteStreams[0]) {
|
||||
if (pc2.getStats) {
|
||||
display('No stats callback');
|
||||
pc2.getStats(function(stats) {
|
||||
log('Raw stats ' + stats);
|
||||
var statsString = '';
|
||||
var results = stats.result();
|
||||
log('Raw results ' + results);
|
||||
for (var i = 0; i < results.length; ++i) {
|
||||
var res = results[i];
|
||||
log(i + ': ' + JSON.stringify(res));
|
||||
statsString += '<h3>Report ';
|
||||
statsString += i;
|
||||
statsString += '</h3>';
|
||||
if (res.local) {
|
||||
statsString += "<p>Local ";
|
||||
statsString += dumpStats(res.local);
|
||||
}
|
||||
if (res.remote) {
|
||||
statsString += "<p>Remote ";
|
||||
statsString += dumpStats(res.remote);
|
||||
}
|
||||
}
|
||||
$('stats').innerHTML = statsString;
|
||||
display('No bitrate stats');
|
||||
});
|
||||
} else {
|
||||
display('No stats function. Use at least Chrome 24.0.1285');
|
||||
}
|
||||
} else {
|
||||
log('Not connected yet');
|
||||
}
|
||||
// Collect some stats from the video tags.
|
||||
local_video = $('local-video');
|
||||
if (local_video) {
|
||||
$('local-video-stats').innerHTML = local_video.videoWidth +
|
||||
'x' + local_video.videoHeight;
|
||||
}
|
||||
remote_video = $('remote-video');
|
||||
if (remote_video) {
|
||||
$('remote-video-stats').innerHTML = remote_video.videoWidth +
|
||||
'x' + remote_video.videoHeight;
|
||||
}
|
||||
}, 1000);
|
||||
|
||||
// Dumping a stats variable as a string.
|
||||
// might be named toString?
|
||||
function dumpStats(obj) {
|
||||
var statsString = 'Timestamp:';
|
||||
statsString += obj.timestamp;
|
||||
if (obj.names) {
|
||||
log('Have names function');
|
||||
names = obj.names();
|
||||
for (var i = 0; i < names.length; ++i) {
|
||||
statsString += '<br>';
|
||||
statsString += names[i];
|
||||
statsString += ':';
|
||||
statsString += obj.stat(names[i]);
|
||||
}
|
||||
} else {
|
||||
log('No names function');
|
||||
if (obj.stat('audioOutputLevel')) {
|
||||
statsString += "audioOutputLevel: ";
|
||||
statsString += obj.stat('audioOutputLevel');
|
||||
statsString += "<br>";
|
||||
}
|
||||
}
|
||||
return statsString;
|
||||
}
|
||||
|
||||
|
||||
// Utility to show the value of a field in a span called name+Display
|
||||
function showValue(name, value) {
|
||||
$(name + 'Display').innerHTML = value;
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Constraints and Statistics</h1>
|
||||
This page is meant to give some hints on how one can use constraints and statistics in WebRTC applications.
|
||||
<p>
|
||||
The form to the left gives constraints you can set on the getUserMedia call.
|
||||
When you hit "open", it will (re)open the camera with these constraints.
|
||||
<p>
|
||||
The left picture is the local preview. The right picture is the picture
|
||||
after being passed through the PeerConnection (locally).
|
||||
<p>
|
||||
Underneath the picture you will see a running display of how many Kbits/sec
|
||||
the video feed uses for transmission.
|
||||
<hr>
|
||||
<table>
|
||||
<tr>
|
||||
<td align="top">
|
||||
<h2>getUserMedia constraints</h2>
|
||||
<table>
|
||||
<tr><td><td>Min<td>Max
|
||||
<tr><td>Horizontal
|
||||
<td><input type="range" id="minwidth" min="0" max="1280" value="300"
|
||||
onchange="showValue(this.id, this.value)">
|
||||
<td><input type="range" id="maxwidth" min="0" max="1280" value="640"
|
||||
onchange="showValue(this.id, this.value)">
|
||||
<td><span id="minwidthDisplay">300</span>-<span id="maxwidthDisplay">640</span>
|
||||
<tr><td>Vertical
|
||||
<td><input type="range" id="minheight" min="0" max="1280" value="200"
|
||||
onchange="showValue(this.id, this.value)">
|
||||
<td><input type="range" id="maxheight" min="0" max="1280" value="480"
|
||||
onchange="showValue(this.id, this.value)">
|
||||
<td><span id="minheightDisplay">200</span>-<span id="maxheightDisplay">480</span>
|
||||
<tr><td>
|
||||
FrameRate
|
||||
<td colspan=2><input type="range" id="frameRate" min="0" max="60" value="30"
|
||||
onchange="showValue(this.id, this.value)">
|
||||
<td><span id="frameRateDisplay">30</span>
|
||||
</table>
|
||||
<input type="submit" name="capture" value="Capture!" onclick="openCamera()">
|
||||
</td>
|
||||
<td align="top">
|
||||
<h2>addStream constraints</h2>
|
||||
Maximum bitrate
|
||||
<input type="range" id="bandwidth" min="0" max="2000" value="1000"
|
||||
onchange="showValue(this.id, this.value)">
|
||||
<span id="bandwidthDisplay">1000</span>
|
||||
<br>
|
||||
<input type="submit" name="connect" value="Connect!" onclick="connect()">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<video id="local-video" autoplay width=400></video>
|
||||
</td>
|
||||
<td>
|
||||
<video id="remote-video" autoplay width=400></video>
|
||||
</td>
|
||||
<tr>
|
||||
<td><span id="local-video-stats"></span>
|
||||
<td><span id="remote-video-stats"></span>
|
||||
<br>
|
||||
<span id="bitrate">Bitrate unknown</span>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><pre><span id="cameraConstraints"></span></pre>
|
||||
<td><pre><span id="addStreamConstraints"></span></pre>
|
||||
</table>
|
||||
<h2>Statistics report display</h2>
|
||||
<div id="stats">Stats will appear here.</div>
|
||||
</body>
|
||||
</html>
|
Reference in New Issue
Block a user