How to properly display MJPEG snapshot from CCTV in PHP - php

I have a IP CCTV camera which support MJPEG. I would like to display image in HTML (from PHP script) together with other data.
I know that I can get a screenshot from the camera using:
http://username:password#<servername>/Streaming/channels/1/picture
however when I am using this simple html code image is not always displayed:
<html>
<body>
<IMG id="myImage" SRC='http://username:password#192.168.0.20/Streaming/channels/1/picture'>
</body>
</html>
On Microsoft Edge, it is not possible even to login to camera.
On Firefox works fine.
On Chrome camera is logged however image is not displayed.
So the question is how I can get image in HTML or better in PHP to display it on the page. I prefer to use PHP because I want to add more data to page, like temperature etc.
Also will be nice to refresh the image, but this can be done in AJAX later.

Use a second PHP script to retrieve the image and point the <img> tag to that. It's possibly because the page you're displaying the image on uses HTTPS while the camera only supports HTTP. Proxying through PHP will allow it all to appear to come from the same source and PHP will handle the HTTP authentication, which will avoid any of your browser compatibility problems.
<IMG id="myImage" SRC='currentimage.php'>
currentimage.php:
<?php
$crl = curl_init('http://<servername>/Streaming/channels/1/picture');
curl_setopt($crl, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($crl, CURLOPT_USERPWD, 'username:password');
curl_setopt($crl, CURLOPT_RETURNTRANSFER, TRUE);
$contents = curl_exec($crl);
curl_close($crl);
header("Content-Type: image/jpeg");
echo $contents;
?>
To save on server load and allow it to handle more traffic, you could also cache the last-retrieved image to a file for 5-10 seconds, but that's a separate problem to solve.

This code seems to work fine for me:
<?php
while (#ob_end_clean());
header('Content-type: image/jpeg');
// create curl resource
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt($ch, CURLOPT_URL, 'http://<servername>/Streaming/channels/1/picture');
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, 'username:password');
// $output contains the output string
$output = curl_exec($ch);
echo $output;
// close curl resource to free up system resources
curl_close($ch);
?>

Related

How to refresh image from camera in background without refreshing whole page?

I am using PHP script (currentimage.php) to get a snapshot from my CCTV IP camera, which works fine:
<?php
while (#ob_end_clean());
header('Content-type: image/jpeg');
// create curl resource
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, $useragent);
curl_setopt($ch, CURLOPT_URL, 'http://192.168.0.20/Streaming/channels/1/picture');
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, 'username:password');
// $output contains the output string
$output = curl_exec($ch);
echo $output;
// close curl resource to free up system resources
curl_close($ch);
?>
and another PHP/HTML to display the data:
<IMG id="myImage" SRC='currentimage.php'>
but I can't get it to work to refresh the image in background every 30s.
I am trying AJAX, but no success:
<script>
function refresh_image(){
document.getElementbyId("myImage").setAttribute("src", "currentimage.php");
}
setInterval(function(){refresh_image()}, 30000);
</script>
What I am doing wrong? I will appreciate any help
I have tried the concept of changing the displayed image via timed requests to a PHP script, and it works fine. A new request is fired up to the image getting script if the URL is modified, and I did so by appending a version number as a parameter to the URL.
var version = 1;
function refresh_image(){
document.getElementById("myImage").setAttribute("src", "currentimage.php?ver="+version);
version++;
}
setInterval(function(){
refresh_image();
}, 2000);
I suspect the main problem here is that the browser caches your file and will not reload it if you set the attribute again. I've found a way around this though:
document.getElementbyId("myImage").setAttribute("src", "currentimage.php?version=1");
Save the version number and count up every time you make the request. This way, the browser will treat it as a new URL and it will be reloaded again (check this using the developer functions of your browser in the network tab).

Setting up proxy for an axis ip camera in PHP

I have been searching for a way to proxy a mjpeg stream from the AXIS M1114 Network Camera.
using the following url setup
http://host:port/axis-cgi/mjpg/video.cgi?resolution=320x240&camera=1
i try to capture the output and make them available to users with a php script running an apache server on ubuntu.
having browsed the web looking for an answer to no avail i come to you.
my ultimate goal is to have users able to link to the proxy like this:
<img src='proxy.php'>
and have the details of all the things in proxy.php.
I have tried using the way of cURL (advised in similar thread here) but i can't get it to work, probably due to lack of knowledge on the inner workings.
currently my very simple proxy.php looks like this
<?php
$camurl = "http://ip:port";
$campath = "axis-cgi/mjpg/video.cgi";
$userpass = "user:pw";
$ch = curl_init();
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_URL, $camurl + $campath);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'resolution=320x240&camera=1');
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_USERPWD, $userpass);
$result = curl_exec($ch);
header('Content-type: image/jpeg');
echo $result;
curl_close($ch);
?>
My understanding is that this would produce an acceptable output for my plan. But alas.
My question would be if there is a blatant error i do not see. Any simpler option/way of getting the result i aim for is welcome too.
Please point me in the right direction. I happily provide any relevant information i might have missed to provide. Thank you in advance.
solved edit:
After commenting out:
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, true);
changing
curl_setopt($ch, CURLOPT_URL, $camurl + $campath);
to
curl_setopt($ch, CURLOPT_URL, $camurl . $campath); (mixing up some languages)
and most importantly removing a space in the .php file so that the header is actually the header it sort of does what i wanted.
Adding a
curl_setopt($ch,CURLOPT_RETURNTRANSFER,true);
seems to be needed to get the image displayed as image and not as raw data.

Copying an image with PHP

With permission from the other site, I am supposed to periodically download an image hosted on another site and include it in a collection of webcam photos on our site with an external link to the contributing site.
This hasn't been any issue for any of the other sites, but with this particular one, I can't open the image to resize it and save it to our server. It's not a hotlinking issue because I can create a plain ole' <img src="http://THEIRIMAGE /> on a page on our site and it works fine.
I've tried using $img = new Imagick($sourceFilePath) directly as with all the others, as well as trying to use PHP's copy and also trying to copy the image using cURL but when doing so, the page just times out with no results at all.
Here's the image in question: http://island-alpaca.selfip.com:10202/SnapshotJPEG?Resolution=640x480&Quality=Standard
Like I've said, I'm able to do this sort of thing with several other webcams, but it isn't working with this one, and I am stuck as to why it isn't. Any help would be greatly appreciated.
Thank you.
In order to reduce bandwidth and server load some sites block certain bots from accessing their content. Your cURL request needs to more closely mimic an actual browser, which would include a referrer (usually), user agent, etc. It could also be that there is a redirect and you haven't told cURL to follow redirects.
Try setting more opts like this:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_ENCODING , "gzip");
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_USERAGENT, 'PHP');
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
If that doesn't work, get the user agent from an actual browser and put it in there and see if that makes a difference.
Try using file_get_contents().
for example:
$url = 'http://island-alpaca.selfip.com:10202/SnapshotJPEG?Resolution=640x480&Quality=Standard';
$outputfile = "tmp/image" . date("Y-m-d_H.i.s");
$cmd = "wget -q \"$url\" -O $outputfile";
exec($cmd);
$temp_img = file_get_contents($outputfile);
$img = new Imagick($temp_img);
Can you try this and get back to me?

How do I use cURL & PHP to spoof the referrer?

I'm trying to learn cURL with PHP to spoof the referrer to a website.
With the following script I expected to accomplish this...but it seems to not work.
Any ideas/suggestion where I am going wrong??
Or do you know of any tutorials that could help me figure this out?
Thanks!
Jessica
<?php
$host = "http://mysite.com";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $host);
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, false);
curl_setopt($ch, CURLOPT_REFERER, "http://google.com");
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HEADER, 0);
$result = curl_exec($ch);
curl_close($ch);
?>
You wont be able to see the result in webserver's analytics because it might probably using a javascript to get the analytics and curl wont run/execute the javascript. All Curl will do is get the content of the page as it like it is a text file. It wont run any of the scripts or anything.
To be more clear if you have an html tag like
<img src="path/to/image/image.jpg" />
The curl will treat it as a line of text. it wont load the image.jpg from the server. The same goes with the js if their is a
<script type="text/javascript" src="analytics.js"></script>
Normally the browser will load that analytics.js and run it, but the curl wont.

Curl grab HTML content

I have a webpage which requires a login.
I am using curl to build the HTTP authentication request. It works, but I am not able to grab all the content from my links. I miss all the images.
How can I grab the images as well?
<?php
// create cURL resource
$URL = "http://10.123.22.38/nagios/nagvis/nagvis/index.php?map=Nagvis_CC";
//Initl curl
$ch = curl_init();
//Set HTTP authentication option
curl_setopt($ch, CURLOPT_URL, $URL); // Load in the destination URL
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); //Normal HTTP request, not SSL
curl_setopt($ch, CURLOPT_USERPWD, "guest:test" ); // Pass the user name and password
// grab URL and pass it to the browser
$content = curl_exec($ch);
$result = curl_getinfo($ch);
// close cURL resource, and free up system resources
curl_close($ch);
echo $content;
echo $result;
?>
I'm getting this warning message Warning: curl_error(): 2 is not a valid cURL handle resource in C:\xampp\htdocs\LiveServices\LoginTest.php on line 24
cURL doesn't get images or any other 'content', it just gets the raw HTML page. Are you saying you are missing <img /> tags that are present on the original page?
cURL also doesn't parse any CSS or JavaScript, so if the content is modified with those, it won't come through. For example, you may be unable to get a background-image of an element unless you do more scraping, that is, get the associated CSS file and parse that.
The main issue I have is that I cannot see the html, so I cannot be sure what the problem is. Having said that, two things occur to me.
The first thing to check is if the images are relative or not. If they are displayed in the form ../xyz/foo.jpg or foo.jpg then you will either need to edit the images src to the full url or add the base tag to the html
For parsing HTML, use the Simple HTML DOM library as it is faster than rolling your own.
The second issue may be that the images also require the user to be logged in. If this is the case you would also have to download all the images, and either embed them in the content after base 64 encoding them, or store them temporally on your server.
Here the some html codes:
The images that I want to get:
<img id="backgroundImage" style="z-index: 0;" src="/nagios/nagvis/nagvis/images/maps/Nagvis_CC.png"/>
<a href="/nagios/cgi-bin/extinfo.cgi?type=2&host=business_processes&service=NLThirdPartyLive" target="_self">
And a lot of javascript.
I tried to use simple HTML dom libray, but the output is array. nothing
require("/simplehtmldom/simple_html_dom.php");
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERAGENT, 'WhateverBrowser1.45');
curl_setopt($ch, CURLOPT_URL, 'http://10.123.22.38/nagios/nagvis/nagvis/index.php?map=Nagvis_CC');
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt ($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC); //Normal HTTP request, not SSL
curl_setopt($ch, CURLOPT_USERPWD, "guest:test" ); // Pass the user name and password
curl_setopt ($ch, CURLOPT_TIMEOUT, 60);
$result = curl_exec($ch);
$html= str_get_html($result);
echo $ret= $html->find('table[class=header_table]');
echo $result;

Categories