Ok well firstly make sure that what you think is happening, is happening.

Use a telnet client to connect to the same URL that the script is. Then feed in the GET, Host, Authorization commands. See if those are working and not returning an error, or a warning. If all that is working ok you will probably get a screen full of hex. This is a good thing, that's the image you want.

By the way, any reason you aren't using cUrl?

    All new ground to me, but these are the problems I see as likely...

    You can't push to an img element.

    I don't see where any content-type header of type image/jpeg is supposed to be sent, but the result is correct: the type is NOT image/jpeg, it is multipart/x-mixed-replace, consisting of several parts where some are image/jpeg.

    Also, while (!feof($fh)) won't ever happen will it? Or at least not until you send a close header.

      @ khaine:

      I checked all this and everything seems to be okay. You see, I'm already getting data from the webcam in plain text format (this data is also protected and I'm getting it using the exact same script as above). In fact, I can read ALL data the webcam broadcasts, except for the image feed (using the GetData.cgi file as a source - well actually I CAN - using the browser's address bar, but not by using PHP).

      The reason why I'm not using cUrl is uhh.. Well, I'm basically an ASP.NET developer and I'm only reaching out to PHP when I can't get stuff done in ASP.NET (or whenever the PHP approach seems to be easier). So what's this cUrl all about then?

      @ johanafm:

      But how in earth can I ever get the image feed then - using PHP ?? (i need to use PHP for two reasons: one is javascript's restricted cross-domain policy, and two is that I need to be able to auto-bypass the Basic Authentication system).

      BTW, you're right, the feed is endless, so (!feof($fh)) is of little use here. It's just in there because I use the exact same script to successfully retrieve non-binary data from the same source (webcam's build-in server).

      Thnx!!!
      Roel.

        Curl could be the answer. It is basically a pretend browser that you can get data with.

        http://uk2.php.net/manual/en/book.curl.php

        Basically.

        <?php
        
        // create curl resource
        $ch = curl_init('http://192.x.x.4/GetData.cgi');
        
        //return the transfer as a string
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        curl_setopt($ch, CURLOPT_POSTFIELDS, '?1234&status='.$status);
        curl_setopt($ch, CURLAUTH_NTLM);
        curl_setopt($ch, CURLOPT_USERPWD, $masteruser.':'.$masterpass);
        
        // $output contains the output string
        $output = curl_exec($ch);
        
        // close curl resource to free up system resources
        curl_close($ch);
        
        ?>

        Would be something like it. Then the $output string will contain the raw output. You should be able to send the image/jpg header and then just echo it to screen.

          khaine;10925434 wrote:

          Curl could be the answer. It is basically a pretend browser that you can get data with.

          http://uk2.php.net/manual/en/book.curl.php

          Basically.

          <?php
          
          // create curl resource
          $ch = curl_init('http://192.x.x.4/GetData.cgi');
          
          //return the transfer as a string
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
          curl_setopt($ch, CURLOPT_HEADER, 0);
          curl_setopt($ch, CURLOPT_POSTFIELDS, '?1234&status='.$status);
          curl_setopt($ch, CURLAUTH_NTLM);
          curl_setopt($ch, CURLOPT_USERPWD, $masteruser.':'.$masterpass);
          
          // $output contains the output string
          $output = curl_exec($ch);
          
          // close curl resource to free up system resources
          curl_close($ch);
          
          ?>

          Would be something like it. Then the $output string will contain the raw output. You should be able to send the image/jpg header and then just echo it to screen.

          Hey thnx for that tip!
          Well, when I use your code to call the GetData.cgi script, the script keeps on running (at least the page keeps on loading) however nothing appears on screen, even more so, the page isn't loaded into the browser at all.

          When I call the /Jpeg/CamImg1234.jpg file on the cam's server (which normaly, when used in an img tag, gives me the last JPG image the cam produced), I strangely enough get the following error:

          404 Not Found
          The requested URL /Jpeg/CamImg1234.jpg was not found on this server.

          Weird, because, it DOES exist.. (well not on my shared hosting web server, but on the cam's server I'm pointing to.

          This is the script I'm using:

          <?php
          
          // create curl resource
          //$ch = curl_init('http://194.x.x.104/GetData.cgi');
          $ch = curl_init('http://194.x.x.104/Jpeg/CamImg1234.jpg');
          
          
          //return the transfer as a string
          curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
          curl_setopt($ch, CURLOPT_HEADER, 0);
          curl_setopt($ch, CURLOPT_POSTFIELDS, '');
          curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
          curl_setopt($ch, CURLOPT_USERPWD, 'myloginname:mypassword');
          
          // $output contains the output string
          $output = curl_exec($ch);
          echo $output;
          
          // close curl resource to free up system resources
          curl_close($ch);
          
          ?> 

          Btw, :
          $output = curl_exec($ch);
          header('Content-type: image/jpeg');
          imagejpeg($im);

          Doesnt work either... I'll get nothing but the URL of the page I'm in at that time printed on screen.

            imagejpeg($im); ?!?! There's one problem. The imagejpeg expects an image resource, what we got back from the curl is just raw hex.

            header('Content-type: image/jpeg');
            echo $output;
            

            is all you need. The url output is a mix up between your browser, the server and the PHP code. None know what to do properly so they come up with that between them. Not massively helpful from them though. πŸ™‚

              Thinking about it, that might have been the problem with your initial code.

                khaine;10925445 wrote:

                Thinking about it, that might have been the problem with your initial code.

                Great advice! I'll try this adjustment to the cUrl code version first thing when I get home. I'll post my findings right after πŸ˜‰

                Thnx a lot so far!!

                  khaine;10925444 wrote:

                  imagejpeg($im); ?!?! There's one problem. The imagejpeg expects an image resource, what we got back from the curl is just raw hex.

                  header('Content-type: image/jpeg');
                  echo $output;
                  

                  is all you need. The url output is a mix up between your browser, the server and the PHP code. None know what to do properly so they come up with that between them. Not massively helpful from them though. πŸ™‚

                  Hmmm weird. I still get just the url printed on screen. No errors what so ever, so clearly the PHP code is getting access to the file and get back SOMETHING, but no image (from JPEG/CamImage1234.jpg), or image stream (from GetData.cgi)..

                  This is the current code:

                  <?php
                  
                  // create curl resource
                  //$ch = curl_init('http://194.x.x.104/GetData.cgi');
                  //$ch = curl_init('http://194.x.x.104/Jpeg/CamImg1234.jpg');
                  
                  $ch = curl_init();
                  curl_setopt($ch, CURLOPT_URL, 'http://194.x.x.104/Jpeg/CamImg1234.jpg');
                  curl_setopt($ch, CURLOPT_HEADER, 0);
                  curl_setopt($ch, CURLOPT_POSTFIELDS, '?1234&status=false');
                  curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
                  curl_setopt($ch, CURLOPT_USERPWD, 'myusername:mypass');
                  
                  // $output contains the output string
                  $output = curl_exec($ch);
                  header('Content-type: image/jpeg');
                  echo $output; 
                  
                  // close curl resource to free up system resources
                  curl_close($ch);
                  
                  ?> 

                  Any more ideas??
                  πŸ™‚
                  Thnx a lot!
                  Roel.

                    OK this is nice.. I'm making some progress.!!!!

                    I am actually able to get the single JPG file (the latest image the webcam's MJPEG stream produced) from location "http://194.x.x.104/Jpeg/CamImg1234.jpg". This is good news, since at last I'm able to get SOMETHING through PHP. However, what I'm really after, is the MJPEG stream itself, which is accessible by GetData.cgi?1234&status=false.. When I type this in my browser's address bar, I get a streaming image in a document which is tagged as image/jpeg..

                    Problem is, when I'm trying to connect to this file (GetData.cgi), the browser just keeps loading and running and loading and running but nothing, and I mean nothing, appears on screen, actually nothing happens at all (the only thing happening is that the browser is trying to load the page, or at least it seems to continue for ever... - so I'm guessing the browser IS getting the feed, it just can't output it in any kind, at least not as a image/jpeg).

                    What can I do to get this stream working as well?? I'm so close...!!!!!!!!!!!!!

                    This is my current code, which works perfectly for the single image source:

                    <?php
                    while (@ob_end_clean());
                    header('Content-type: image/jpeg');
                    // create curl resource
                    //http://194.x.x.104/GetData.cgi  <- doesnt work
                    //http://194.x.x.104/Jpeg/CamImg1234.jpg  <- works
                    $ch = curl_init();
                    curl_setopt($ch, CURLOPT_URL, 'http://194.x.x.104/Jpeg/CamImg1234.jpg');
                    curl_setopt($ch, CURLOPT_HEADER, 0);
                    //curl_setopt($ch, CURLOPT_POSTFIELDS, '?1234&status=false');  <- disabling this line helped to make it work!! However, GetData.cgi needs these parameters.
                    curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
                    curl_setopt($ch, CURLOPT_USERPWD, 'mylogin:mypass');
                    // $output contains the output string
                    $output = curl_exec($ch);
                    echo $output; 
                    // close curl resource to free up system resources
                    curl_close($ch);
                    ?> 

                      Wandering into the realm of the unknown a little now as we haven't got the cgi to dismantle. However, it could be that the stream is not sending the end of file that curl is expecting. This is going to be a problem with all grabs of this type. With it being a continual stream, most likely, it is sending something in the headers that tells you how big the following image is. So dumping those might help.

                      Try changing

                      curl_setopt($ch, CURLOPT_HEADER, 0);

                      to

                      curl_setopt($ch, CURLOPT_HEADER,  1);
                      curl_setopt($ch, CURLOPT_NOBODY, 1);
                      curl_setopt($ch, CURLOPT_RETURNTRANSFER,  1);
                      curl_setopt($ch, CURLOPT_TIMEOUT, 10);
                      

                      Then remove the header output. You should get a dump of the html headers from the stream, which if we are lucky will have the filesize in. Can then add the buffersize option to the curl options to limit the returned size, which should get just the latest part of the stream.

                        Hi Khaine!!!

                        Thanks for the insights.

                        This is what I got back from GetData.cgi:

                        HTTP/1.0 200 OK Date: Thu, 01 Jan 1970 03:07:59 GMT Server: WYM/1.0 Connection: close Content-Type: multipart/x-mixed-replace;boundary=WINBONDBOUDARY Last-Modified: Thu, 01 Jan 1970 03:07:59 GMT Pragma: no-cache Cache-Control: no-cache Expires: 01 Jan 1970 00:00:00 GMT 

                        Something I probably should have mentioned before: here's exactly what GetData.cgi is supposed spit out according to the cam's manual:

                        http://www.canvision.net/support/pt300-cgi/GetData.htm

                        Hope any of this helps us further along.

                        Thanks a million for your help so far!!!!!!!!!

                          Now I understand, and it complicates things. But just so I am 100% clear. You need javascript to reference a file on the local server that is actually performing a proxy to a remote server script which contains the streaming data.

                          Firstly I was wrong to lead you along the curl route. It does do what I originally said and gets the data, but because of the transmission, there is no EOF. So curl will continue until time out.

                          There are 2 things we can try.

                          Firstly htaccess, but my memories of doing this are a little shaky. Easiest one to try though.

                          You need to set up a file called .htaccess in the website root. (hoping that htaccess files are allowed and not just ignored)

                          RewriteEngine on
                          RewriteOptions inherit
                          RewriteBase /
                          
                          RewriteCond %{REQUEST_URI} /GetData.cgi.*
                          
                          # where they all go.
                          RewriteRule http://194.x.x.104/GetData.cgi [QSA,L]
                          

                          This will allow you to access GetData.cgi on the local server and it will be redirected to the remote one. Javascript is calling a local file so shouldn't complain.

                          The second option is a script that might get rather complex.

                            Been corrected on what is actually required as a redirect. The htaccess file just needs

                            Redirect 301 /GetData.cgi http://194.x.x.104/GetData.cgi?12345&status=XX
                            
                              khaine;10925575 wrote:

                              Been corrected on what is actually required as a redirect. The htaccess file just needs

                              Redirect 301 /GetData.cgi http://194.x.x.104/GetData.cgi?12345&status=XX
                              

                              Hey Khaine,

                              Wow, this info startles me! I'm not sure if I'm really following what you're saying. I'm getting the part that I need to create a new file on my shared hosting server where I'm running the website (.htaccess) .. Btw, I can't place any files on my cam's build-in web server, it's completely un-updatable (is that even English??), but I'm guessing that won't be necessary.

                              So, I have two questions:

                              1) what exactly do I place in the htaccess file, is it just the code in your last post? Or do I append this code to the code you pasted in the post before that one?

                              2) when I have created this htaccess file, how can I test it works on my web server? And if it does work, how do I get the streaming data from GetData.cgi inside my IMG tag then? Do I still have to use my PHP proxy file - since the GetData.cgi is protected by Basic Authentication.. ?

                              Hope to hear from you!
                              Can't say how incredible thankful I am your helping me, reallY!!!!!!!!!!!!!!!!!!!! πŸ™‚

                              Roel.

                                Hey Khaine,

                                I found this on the web, could this work???? (I'm not able to test it myself for at least 8 hours but I will when I get home from work).

                                I wrote the following PHP script to pull the MJPEG stream directly from the CB-V10 camera on it’s native 65310 streaming port:

                                <?
                                // Set time limit to indefinite execution
                                set_time_limit(0);
                                // create TCP socket
                                $sock = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
                                // connect to the camera's native stream protocol IP:Port
                                socket_connect($sock,"10.0.0.20", 65310);
                                // handshake with the camera
                                socket_write($sock,"START\r\n");
                                // ignore the handshake response
                                socket_read($sock, 12000);
                                // daemonize this script
                                while (true) {
                                    // simulate 4 escape sequences "\0A" with "\r\n" - or chr(0)
                                    socket_write($sock,"\r\n\r\n\r\n\r\n");
                                    // read the image from the stream (max 80k)
                                    print socket_read($sock, 80000);
                                    // limit to ~6 frames per second
                                    usleep(166666);
                                }
                                ?>

                                Source: http://www.overset.com/2007/01/22/live-streaming-of-a-webcam-feed-from-canon-vb-c10c50-from-a-relay-proxy-server/

                                  I forgot about authentication on the htaccess stuff. So it won't work.

                                  As for the proxy server script, I can only say give it a go. I don't have access to a camera here and the stream source I am using is just a basic stream. I think it may run into blocking though. As all PHP scripts can. Basically the PHP is waiting to see the end of the input data. Since is is a continual stream it dosn't have one. My guess, and this is only a guess, is that the above script will run until timeout, which it sets to never. So you could end up with a runaway script. When you test it set the

                                  set_time_limit(0)

                                  ;

                                  line to something that will allow a timeout, although I think apache will timeout anyway. Something like 120 would do it. You should get a stream which then stops. If you do then it would be ok to set it to 0.

                                    7 months later

                                    I've had the same problem with a 7links px 3309 and found a solution I'd like to share - maybe it helps someone.

                                    The trick is that the camera sends several images one after another seperating each of them with a boundary. When you use your own PHP Script to forward the images you will have to send this boundary inside the header. So the solution is:

                                    # To stop apache from killing the script
                                    set_time_limit(0);
                                    
                                    # Sending the correct header
                                    # The boundary=ipcamera is important.
                                    # You will have to change "ipcamera" to whatever your camera uses to seperate the 
                                    # images. Mine uses "--ipcamera" as seperator. You can omit the leading --, but have
                                    # to use the rest.
                                    header('Content-Type: multipart/x-mixed-replace;boundary=ipcamera');
                                    
                                    # Sending the images
                                    # You probably have to adapt the url to the video screen of your cam.
                                    readfile('http://user:pass@ip_adresse_of_camera/video.cgi')
                                    
                                    
                                    
                                      2 months later

                                      Hello,
                                      I have the same need, I want to see the stream of an IP Camera.
                                      I tried your solution (I change the boundary and the path of the cgi) but it doesn't work!

                                      Can you help me with a more complete code? πŸ˜•
                                      Thanks.

                                        Actually - that's all the code I needed - there is nothing more inside my script.