154 lines
5.2 KiB
HTML
154 lines
5.2 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
||
|
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
||
|
<head>
|
||
|
<title>MJPG-streamer</title>
|
||
|
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
|
||
|
<link rel="stylesheet" href="style.css" type="text/css" />
|
||
|
<!--[if IE 6]>
|
||
|
<link rel="stylesheet" href="fix.css" type="text/css" />
|
||
|
<![endif]-->
|
||
|
<script type="text/javascript">
|
||
|
|
||
|
/* Copyright (C) 2007 Richard Atterer, richard©atterer.net
|
||
|
* This program is free software; you can redistribute it and/or modify it
|
||
|
* under the terms of the GNU General Public License, version 2. See the file
|
||
|
* COPYING for details.
|
||
|
*/
|
||
|
|
||
|
var imageNr = 0; // Serial number of current image
|
||
|
var finished = new Array(); // References to img objects which have finished downloading
|
||
|
var paused = false;
|
||
|
var previous_time = new Date();
|
||
|
var fNi = 0, msAvg = 0, fpsAvg = 0, fcnt = 0, fN = 80, msa = [], wsize = 4;
|
||
|
|
||
|
function createImageLayer() {
|
||
|
var img = new Image();
|
||
|
img.style.position = "absolute";
|
||
|
img.style.zIndex = -1;
|
||
|
img.onload = imageOnload;
|
||
|
img.onclick = imageOnclick;
|
||
|
img.width = 512;
|
||
|
img.height = 384;
|
||
|
img.src = "./?action=snapshot&n=" + (++imageNr);
|
||
|
var webcam = document.getElementById("webcam");
|
||
|
window.info = document.getElementById('info').firstChild;
|
||
|
window.ravgFps = document.getElementById('ravgfps').firstChild;
|
||
|
window.ravgMs = document.getElementById('ravgms').firstChild;
|
||
|
webcam.insertBefore(img, webcam.firstChild);
|
||
|
document.getElementById('fN').firstChild.nodeValue = fN;
|
||
|
}
|
||
|
|
||
|
|
||
|
function runningAvgs (delta) {
|
||
|
// delta is the measured frame period
|
||
|
var len;
|
||
|
if (fcnt < fN) {
|
||
|
|
||
|
fcnt++;
|
||
|
// we need to populate the sample array
|
||
|
msa.push(delta);
|
||
|
// calculate average period so far
|
||
|
msAvg += (delta - msAvg) / fcnt;
|
||
|
|
||
|
} else {
|
||
|
/*
|
||
|
running average (fN samples) according to the formula:
|
||
|
rAvg = rAvg - value_fN_samples_back / fN + newest_value / fN
|
||
|
*/
|
||
|
msAvg += (delta - msa[0])/fN;
|
||
|
// drop oldest ms value, msa[0]
|
||
|
msa = msa.slice(1);
|
||
|
// append newest value, delta
|
||
|
msa.push(delta);
|
||
|
}
|
||
|
// calculate average fps
|
||
|
fpsAvg = 1000 / msAvg;
|
||
|
/*
|
||
|
once every fN frames, check if we need to adjust the averaging window
|
||
|
since faster rates seem to need more samples to reach a stable(er) readout
|
||
|
*/
|
||
|
if (++fNi == fN) {
|
||
|
|
||
|
fNi = 0;
|
||
|
// new window size
|
||
|
fN = parseInt(fpsAvg * wsize);
|
||
|
len = fcnt - fN;
|
||
|
// if our sample array, msa, has extra samples, then trim it to the new size
|
||
|
if (len > 0) {
|
||
|
|
||
|
// adjust averaging window (nr of samples)
|
||
|
msa = msa.splice(len);
|
||
|
// avoid populating the sample array again
|
||
|
fcnt = fN;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Two layers are always present (except at the very beginning), to avoid flicker
|
||
|
function imageOnload() {
|
||
|
this.style.zIndex = imageNr; // Image finished, bring to front!
|
||
|
while (1 < finished.length) {
|
||
|
var del = finished.shift(); // Delete old image(s) from document
|
||
|
del.parentNode.removeChild(del);
|
||
|
}
|
||
|
finished.push(this);
|
||
|
current_time = new Date();
|
||
|
delta = current_time.getTime() - previous_time.getTime();
|
||
|
fps = (1000.0 / delta).toFixed(1);
|
||
|
runningAvgs(delta);
|
||
|
info.nodeValue = delta + " ms (" + fps + " fps)";
|
||
|
ravgFps.nodeValue = fpsAvg.toFixed(1);
|
||
|
ravgMs.nodeValue = msAvg.toFixed(0);
|
||
|
previous_time = current_time;
|
||
|
if (!paused) createImageLayer();
|
||
|
}
|
||
|
|
||
|
function imageOnclick() { // Clicking on the image will pause the stream
|
||
|
paused = !paused;
|
||
|
if (!paused) createImageLayer();
|
||
|
}
|
||
|
|
||
|
</script>
|
||
|
</head>
|
||
|
|
||
|
<body onload="createImageLayer();">
|
||
|
<div id="sidebar">
|
||
|
<h1>MJPG-Streamer Demo Pages</h1>
|
||
|
<h2>a resource-friendly streaming application</h2>
|
||
|
|
||
|
<div id="menu">
|
||
|
<a href="index.html">Home</a>
|
||
|
<a href="static.html">Static</a>
|
||
|
<a href="stream.html">Stream</a>
|
||
|
<a href="java.html">Java</a>
|
||
|
<a class="active" href="javascript.html">Javascript</a>
|
||
|
<a href="videolan.html">VideoLAN</a>
|
||
|
<a target="_blank" onClick="window.open(this.href, '_blank','width=400,height=400'); return false;" href="control.htm">Control</a>
|
||
|
</div>
|
||
|
|
||
|
<h3>Version info:</h3>
|
||
|
<p>v0.1 (Okt 22, 2007)</p>
|
||
|
|
||
|
<h3>Runtime info:</h3>
|
||
|
<p><span id="info">-</span><br/>
|
||
|
Avg<sub id="fN">-</sub> : <span id="ravgms">-</span> ms (<span id="ravgfps">-</span> fps)
|
||
|
</p>
|
||
|
</div>
|
||
|
|
||
|
<div id="content">
|
||
|
<h1>Javascript</h1>
|
||
|
<h2>Display the stream with javascript</h2>
|
||
|
|
||
|
<h3>Hints</h3>
|
||
|
<p>This example shows the stream by using java script. It works with most browsers. To see a simple example click <a href="javascript_simple.html">here</a>.</p>
|
||
|
|
||
|
<div id="webcam" style="width:512px;height:394px"><noscript><img src="./?action=snapshot" width="512px" height="384px" /></noscript></div>
|
||
|
|
||
|
<p>© The <a href="http://mjpg-streamer.sf.net">MJPG-streamer team</a> | Design by <a href="http://andreasviklund.com">Andreas Viklund</a></p>
|
||
|
</div>
|
||
|
</body>
|
||
|
</html>
|
||
|
|
||
|
|