Streaming uploaded Jpegs or build a mjpeg file.

SBSP

Senior Member
Joined
Sep 7, 2007
Messages
663
Browser is uploading JPG snapshots from a webcam to a folder on the web server.

So whilst the browser is open and taking snapshots i want another browser client from a different IP to be able to see the same stream.

Currently I do this.
index.php takes the snapshots from the webcam then upload the image to a folder on the server over and over and its overwriting the jpeg everytime.

The second browser from a different IP then constantly updates a css DIV with the image using an interval.
I'm adding a date stamp to the file to ensure it keeps downloading the latest image instead of keeping the cached image.

webcam.jpg?filetime+newint

See below.
Code:
<div id="StreamWindow" ></div>


<script language="JavaScript">
var sec = 0;


setInterval(Load_stream, 500);
function Load_stream() 
{
sec = sec + 1;
	document.getElementById('StreamWindow').innerHTML =  '<img src="uploads/webcam.jpg?<?php echo filemtime('uploads/webcam.jpg') ?>' + sec + '  "/>' ;
	
}


</script>

The above very inefficient and also causes the div to flicker every time it downloads the image.

I'm not sure how I should approach this and my Java script skills is of the worst.
When uploading the image im using a simple PHP upload, is there a way I can have the below upload script append the image to become a M-Jpeg instead of overwriting it all the time ?

PHP:
<?php 

// be aware of file / directory permissions on your server 

move_uploaded_file($_FILES['webcam']['tmp_name'], 'uploads/webcam.jpg'); 

?>
 
Last edited:

rward

Senior Member
Joined
Oct 26, 2007
Messages
865
Browser is uploading JPG snapshots from a webcam to a folder on the web server.

So whilst the browser is open and taking snapshots i want another browser client from a different IP to be able to see the same stream.

If thatis all you are wanting then why not stream your webcam via your browser using WebRTC?
Full tutorial here: https://www.html5rocks.com/en/tutorials/webrtc/basics/

The above very inefficient and also causes the div to flicker every time it downloads the image.
You could try using websockets ..

Or you could try change your javascript to something along the lines of:
Code:
setInterval(Load_stream, 500);
function Load_stream() 
{
sec = sec + 1;
	document.getElementById('hiddenDiv').innerHTML =  '<img src="uploads/webcam.jpg?<?php echo filemtime('uploads/webcam.jpg') ?>' + sec + '  "/>' ;
        setInterval(function() {
	       document.getElementById('StreamWindow').innerHTML =  '<img src="uploads/webcam.jpg?<?php echo filemtime('uploads/webcam.jpg') ?>' + sec + '  "/>' ;
	}, 200);
}

</script>
<div id="hiddenDiv" style="display:none;"></div>

Basicall you load the image into a hidden div and then you request it again into your actual location. Becuase the browser has already loaded the image it's cached and it should read the second load from the cache and display it without the "flash".

But updating the image 2 times a second - you probably want to be using WebRTC instead..
 

SBSP

Senior Member
Joined
Sep 7, 2007
Messages
663
If thatis all you are wanting then why not stream your webcam via your browser using WebRTC?
Full tutorial here: https://www.html5rocks.com/en/tutorials/webrtc/basics/


You could try using websockets ..

Or you could try change your javascript to something along the lines of:
Code:
setInterval(Load_stream, 500);
function Load_stream() 
{
sec = sec + 1;
	document.getElementById('hiddenDiv').innerHTML =  '<img src="uploads/webcam.jpg?<?php echo filemtime('uploads/webcam.jpg') ?>' + sec + '  "/>' ;
        setInterval(function() {
	       document.getElementById('StreamWindow').innerHTML =  '<img src="uploads/webcam.jpg?<?php echo filemtime('uploads/webcam.jpg') ?>' + sec + '  "/>' ;
	}, 200);
}

</script>
<div id="hiddenDiv" style="display:none;"></div>

Basicall you load the image into a hidden div and then you request it again into your actual location. Becuase the browser has already loaded the image it's cached and it should read the second load from the cache and display it without the "flash".

But updating the image 2 times a second - you probably want to be using WebRTC instead..

Thanks that's clever! Didnt think of that. Will also be looking at the link.
 

battletoad

Expert Member
Joined
Mar 10, 2009
Messages
1,451
+1 for webrtc. Although, it could be complicated to setup if you're rolling your own.

Assuming you add an <img> element in your #StreamWindow...
Code:
setInterval(Load_stream, 500);
function Load_stream() {
    var cacheImg = new Image();
    cacheImg.onload = function() {
        document.querySelector('#StreamWindow img').src = cacheImg.src;
    }
    cacheImg.src = 'uploads/webcam.jpg?_' + (new Date()).getTime();
}

Keeping in line with rward's advice on caching, you could cache the image with an Image() object. Once the image is loaded in full, the .onload() function is triggered, allowing you to swap out fully-cached images.

Use this if [the 200ms delay in rward's reply is too short/still results in flickers] (e.g. large pictures).

Thinking further... you could even draw to canvas, do diffs on consecutive images, and send those diffs. Sounds like a fun experiment.
 

SBSP

Senior Member
Joined
Sep 7, 2007
Messages
663
It does! , Bad lighting and shading on a web camera causes the pixels to change often though.

I also noted the longer i leave ma camera the more white balance it applies eventually the image becomes distorted (Mostly the cheap cameras fault)

I have another question. Wil it be faster to save the image as a Base64 string into a database ? or directly to file ?
 

rward

Senior Member
Joined
Oct 26, 2007
Messages
865
+1 for webrtc. Although, it could be complicated to setup if you're rolling your own.

Assuming you add an <img> element in your #StreamWindow...
Code:
setInterval(Load_stream, 500);
function Load_stream() {
    var cacheImg = new Image();
    cacheImg.onload = function() {
        document.querySelector('#StreamWindow img').src = cacheImg.src;
    }
    cacheImg.src = 'uploads/webcam.jpg?_' + (new Date()).getTime();
}

Keeping in line with rward's advice on caching, you could cache the image with an Image() object. Once the image is loaded in full, the .onload() function is triggered, allowing you to swap out fully-cached images.

Use this if [the 200ms delay in rward's reply is too short/still results in flickers] (e.g. large pictures).

Thinking further... you could even draw to canvas, do diffs on consecutive images, and send those diffs. Sounds like a fun experiment.

Aah yes - much better.
 

rward

Senior Member
Joined
Oct 26, 2007
Messages
865
It does! , Bad lighting and shading on a web camera causes the pixels to change often though.

I also noted the longer i leave ma camera the more white balance it applies eventually the image becomes distorted (Mostly the cheap cameras fault)

I have another question. Wil it be faster to save the image as a Base64 string into a database ? or directly to file ?

If I remember correctly, the Base64 is about 30% bigger than the binary file.
Do 2 quick scripts, one to filesystem and 1 to db, and benchmark them. It shouldn't take long..
 
Top