Reputation: 9583
I have an ipcamera from which /video/feed/1.jpg
(mounted as a ramdrive) is being written to at approx 5fps. Sometimes this can be less than 1 fps if the connection is poor.
I'm trying to update the image in a browser every 500ms but i have two goals:
I tried to achieve this by creating an md5 of the image and storing it in the session, if on the next browser request the md5 is unchanged, the server loops until the md5 is different. The server will also loop until the md5 matches the previous time it was loaded, this way I can be sure that the camera had finished creating the image.
The process works as expected but the cpu usage goes through the roof, so I'm looking for suggestions on improvements.
test.php
<?php
session_start();
$imgFile = '/video/feed/1.jpg';
$lastImg = $_SESSION['image'];
$imgMd5 =0;
do {
sleep(.2);
$img = (file_get_contents($imgFile));
$lastMd5 = $imgMd5;
$imgMd5 = md5($img);
if ($lastMd5 != $imgMd5) {
continue;
}
if ($imgMd5 != $lastImg) {
break;
}
} while (0 == 0);
header("Content-type: image/jpg");
$_SESSION['image'] = md5($img);
echo $img;
exit;
?>
JS
<script>
img = new Image
function f() {
img.src = "test.php?rnd=" + Date.now();
img.onload = function() {
feed.src = img.src;
setTimeout(function() {
f();
}, 500);
};
img.onerror= function(){
setTimeout(function() {
f();
}, 500);
};
}
f();
</script>
Upvotes: 1
Views: 2421
Reputation: 9583
What I really needed was usleep(200000)
sleep(.2)
did not work as I expected.
Upvotes: 3
Reputation:
Instead of using an MD5 hash to check if the file changed, use the last modified time which should be less resource-intensive than computing an MD5 hash each time (but for some reason on my Windows machine it still uses a lot of CPU so I'm not sure), you can try my code :
<?php
session_start();
$path = "/video/feed/1.jpg";
if (isset($_SESSION["lastmodified"])) { // if there's no previous timestamp, do not execute all of this and jump straight into serving the image.
while ($_SESSION["lastmodified"] == filemtime($path)) {
sleep(1); // sleep while timestamp is the same as before.
clearstatcache(); // PHP caches file informations such as last modified timestamp, so we need to clear it each time or we'll run into an infinite loop.
}
}
$_SESSION["lastmodified"] = filemtime($path); // set the new time variable.
header("Content-type: image/jpg");
echo file_get_contents($path);
?>
Edit: you can just let your webserver handle all of this by directly serving the RAMdisk directory, setting appropriate cache-control headers and using a meta refresh tag to reload the page every second. When the page reloads, the webserver will serve a new image only if it exists (and if not, it'll just return "not modified" to the browser and it'll serve the last image from its cache).
Upvotes: 0