Jump to content

grabing a single jpeg frame from mjpeg stream using PHP


fsusr

Recommended Posts

Hello,
I have a webcam on a computer running Motion, a webcam streaming program popular in Linux.  Motion basically outputs a mjpeg stream.  I'd like to use PHP to grab a single jpeg from the mjpeg stream and display it.  The reason I'm doing this is because Motion doesn't have any built in password protection.  With PHP, I can hide the port and IP address of my home server.

I'm trying code provided by the creators of Motion on their website.  The code is suppose to grab just a single jpeg from the mjpeg stream, but I get an error when trying to run it on an nginx server locally.

 

<?
$camurl="http://127.0.0.1:8080/";
$boundary="\n--";
$f = fopen($camurl,"r") ;

   if(!$f)
   {
        //**** cannot open
        echo "error";
   }
    else
  {
        //**** URL OK
         while (substr_count($r,"Content-Length") != 2) $r.=fread($f,512);

         $start = strpos($r,'ÿ');
         $end   = strpos($r,$boundary,$start)-1;
         $frame = substr("$r",$start,$end - $start);

         header("Content-type: image/jpeg");
         echo $frame;
   }
fclose($f);

?>



For reference, this is where I got the code from:
http://www.lavrsen.dk/foswiki/bin/view/Motion/MjpegFrameGrabPHP

Maybe someone could help me out?  I have very little understanding of PHP, and don't understand why the fopen command is returning a fault.

In case you're wondering, I've also tried this code snippet.  It works, but it's grabbing an entire mjpeg stream.  When ran locally on my lan, it works, but when I try the code on a shared host, the shared host computer seems to be trying to download the entire mjpeg stream, which would never complete of course.  That's why I'm trying to find code that grabs just a single jpeg instead of streaming the mjpeg.
 

set_time_limit(0);
$fp = fsockopen ("xxxx.dyndns.org", 20804, $errno, $errstr, 30);
if (!$fp) {
        echo "$errstr ($errno)<br>\n";
} else {
        fputs ($fp, "GET / HTTP/1.0\r\n\r\n");
        while ($str = trim(fgets($fp, 4096)))
           header($str);
        fpassthru($fp);
        fclose($fp);
        }





 

Link to comment
Share on other sites

Post the error... if you want us to help you with it...

 

Opps, sorry I wasn't clear.  I meant the first "if" statement where it looks to see "if(!$f)" results in the "error" text, so $f returned false when ran.

 

I'm still pretty new to this, if there is somewhere else to look for more verbose error messages, please let me know.  I'm fairly certain the IP address I use is valid because I can paste in the same IP address and port on the browser and get to the stream.  I'm doing the test on LAN.

Link to comment
Share on other sites

$camurl="http://127.0.0.1:8080/"; - 127.0.0.1 is the local loopback address on whatever system the code is running. If this is the address you actually used on your host, it is not going to find the web server on your home computer.

 

$f = fopen($camurl,"r") ; - It is possible that your host does not have allow_url_fopen enabled which would cause this to fail on a url (http://). If this is the case, you will have to use sockets as in your second example, or curl.

 

shared host computer seems to be trying to download the entire mjpeg stream

What exactly are you seeing, and what have you done to debug this?

 

Try putting a true jpg file in the root of your home system, and change the fputs() call to "... GET /test.jpg..." or whatever name you used for the image. See if you get the image or the thing sill hangs up.

 

Try capturing, oh say, 1000 bytes from the socket and dump it

 

Try printing out the $str values you are sending to header(). Maybe you are getting an "error" page - does your home web server deny access to anything not on the LAN?

Link to comment
Share on other sites

$camurl="http://127.0.0.1:8080/";

 

What exactly are you seeing, and what have you done to debug this?

 

Try putting a true jpg file in the root of your home system, and change the fputs() call to "... GET /test.jpg..." or whatever name you used for the image. See if you get the image or the thing sill hangs up.

 

Try capturing, oh say, 1000 bytes from the socket and dump it

 

Try printing out the $str values you are sending to header(). Maybe you are getting an "error" page - does your home web server deny access to anything not on the LAN?

 

 

Oh, thanks.  I don't have any experience debugging this.  Your tips are helpful.  Will try and report back.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.