Solved

Using <IMG> w/ CGI call. Stream Images?

Posted on 1998-07-21
13
356 Views
Last Modified: 2013-12-25
I have been programming in perl and doing some CGI work for a few months now and I must admite its pretty interesting stuff.

I have seen and figured many things but I just can't figure out how some sites do this trick.  They make a call to a CGI script via an <IMG> tag on their webpage.  Normally when I do such a thing I can only return back the single JPG or GIF image file and that's that.  But these site make the same call and have moving images returned back, many slides of JPG or GIF pics coming down being laid "on top" of one another (it appears to be streaming video just really chunky).   Example webpage would be:
-----
<html>
<head></head>
<body>
<IMG SRC="http://mysite.com/cgi-bin/video.cgi?10">
</body>
</html>
----

How do they get the streaming images without a META REFRESH or something?  Does the CGI script have to return NO-CACHE and then send back a single JPG/GIF image, and then.....Well now I'm lost.  What next?!  Maybe I should return back a different CONTENT-TYPE header?

BTW: No Javascript or JAVA is being used, just straight up HTML and a CGI call.  The HTML page as a whole does not refresh only the IMAGE itself keeps changing from one image to the next.

Please, any answeres would be greatly appreciated!
0
Comment
Question by:mirror
13 Comments
 
LVL 1

Expert Comment

by:slinky
ID: 1830842
You can always link to an animated GIF
0
 
LVL 6

Accepted Solution

by:
alamo earned 100 total points
ID: 1830843
Ever seen a html page refresh itself automatically using multipart/mixed headers? Well, it's not limited to html, it can work with images too.

You will find the headers for the image are something like: (I captured this from an actual such page):

HTTP/1.0 200 OK
Pragma: no-cache
Content-type: multipart/x-mixed-replace; boundary=ThisRandomString

--ThisRandomString

Content-type: image/jpeg

(image data goes here)
--ThisRandomString
Content-type: image/jpeg

(new image data goes here)
--ThisRandomString
Content-type: image/jpeg

etc.

Hope this helps!
0
 

Author Comment

by:mirror
ID: 1830844
Alamo, first thing:  How do you "capture" such a header from a website.  I would love to know how to do that?

And next, you said the the CGI returns a header like this:
------
HTTP/1.0 200 OK
Pragma: no-cache
Content-type: multipart/x-mixed-replace; boundary=ThisRandomString

 --ThisRandomString

Content-type: image/jpeg

(image data goes here)
-----
For CGI-Perl output I would handle it like this (I will make it a Non-Parsed Header CGI):
print "HTTP/1.0 200 OK\n";
print "Pragma: no-cache\n";
print "Content-type: multipart/x-mixed-replace\n";

now, I'm confused with "boundary=ThisRandomString ".  Do I just add the line:
print "boundary=ThisRandomString\n";

And then:
print "Content-type: image/jpeg\n\n";  <--Note doubel \n here to finish off the HTTP header
while($image_count<10)
{
  open (IN,"images/pic$image_count.jpg"); binmode(IN); binmode(STDOUT);
  print <IN>; close(IN);
  $image_count++;
}

Is the above accurate in creating a CGI script that feeds out multiple JPG/GIF images making the client's browser show an animating movie?  Could I improve the code in anyway?

Thanks a million.
0
 
LVL 6

Expert Comment

by:alamo
ID: 1830845
>Alamo, first thing:  How do you "capture" such a header from a website.  I would love to know how to do that?

A winsock 'sniffer' program and a perl script to extract the text from the raw data. I have heard there are free sniffer programs on the net, though I bought the one I have (shareware).

Here's my rewrite of what you posted - haven't had a chance to test it yet. Note that for nph scripts you usually need to use \r\n instead of \n.

print "HTTP/1.0 200 OK\r\n";
print "Pragma: no-cache\r\n";
$boundary = "ThisRandomString";
print "Content-type: multipart/x-mixed-replace; boundary=$boundary\r\n\r\n";
binmode(STDOUT);

while($image_count<10)
{
    print "\r\n--$boundary\r\n";
    print "Content-type: image/jpeg\r\n\r\n";  
    open (IN,"images/pic$image_count.jpg");
    binmode(IN);
    print <IN>;
    close(IN);
    $image_count++;
}

It's the -- followed by the boundary string that signals the browser it's a noew image, so start looking for headers.
0
 
LVL 6

Expert Comment

by:alamo
ID: 1830846
I made a couple of changes  - I forgot $|=1 was needed - and also found that the image wouldn't be completely drawn unless the boundary was at the end rather than the beginning. Here's the full modified program, which works very well for me:

print "HTTP/1.0 200 OK\r\n";
print "Pragma: no-cache\r\n";
$boundary = "ThisRandomString";
print "Content-type: multipart/x-mixed-replace; boundary=$boundary\r\n\r\n";
binmode(STDOUT);
$|=1;
print "--$boundary\r\n";
$image_count=0;
while($image_count<4)
{
    print "Content-type: image/jpeg\r\n\r\n";
    open IN,"<images/pic$image_count.jpg";
    binmode(IN);
    print <IN>;
    close(IN);
    print "\r\n--$boundary\r\n";
    $image_count++;
    sleep 1;
}
0
 

Author Comment

by:mirror
ID: 1830847
Alamo, you are incredible!

Just one other thing though.  What if a site is calling the CGI yuo mentioned above so that my browser is receiving this "stream" of images being laid one on top of another for animation.  All the while the images are not being cached (Just like your CGI script above). ** Is there ANYWAY to somehow tell Netscape to capture these "individual" images and to store them to disk so that I'd be able to have these stream of separate image on my Hard Drive?

Thansk again.
0
Free Trending Threat Insights Every Day

Enhance your security with threat intelligence from the web. Get trending threat insights on hackers, exploits, and suspicious IP addresses delivered to your inbox with our free Cyber Daily.

 

Author Comment

by:mirror
ID: 1830848
Oh I forgot.  Where would I find a "SNIFFER" program to use?  Or maybe some code I could use in a Perl script to call up a URL (the CGI script I'm interested in) and to get the returned data from it.

Thanks.

0
 
LVL 6

Expert Comment

by:alamo
ID: 1830849
To capture to disk, Save Image  As, just as you'd save any image. On Netscape 4 it saves the whole stream including the boundaries and headers, you will have to use a binary editor program to break it up into the individual images.

By the way, don't necessarily expect this to work on all browsers, you'll need to experiment with what works and what doesn't. If you find it doesn't work for a browser test an independent site, it probably won't work either, otherwise you'd need to look at how the headers differ for that site. As you know by now, nothing is standard :-(

Glad I could help!
0
 
LVL 6

Expert Comment

by:alamo
ID: 1830850
As to sniffers, I bought the one at http://www.win-tech.com/, that's all I know of. For others, try searching the net. For perl socket code, try www.perl.com, I have done almost none of that stuff (my page capture programs right now do a system() to lynx to save the source page to disk, it's very simple and I havent so far needed more).
0
 

Author Comment

by:mirror
ID: 1830851
One more question.

If I tell Netscape 4 to just simpy save such a streaming image file, which can grow to megabytes in size, what if the image streams in an infinite loop, and since no caching is set then it should do a continuous save growing larger and larger!  

Now from experience I have found out when Netscape is downloading a file from a site and when you hit CANCEL it "auto-kills" the file it was saving.  Even then the file had a byte size of 0 no matter how much it downloads.  If that infinit loop occurs in the streaming images, is there anyway to tell Netscape 4 to stop donwloading and to leave the file for me to inspect?

Thansk again!  and BTW do you know of any FREE WEBHOSTERS out there (ie Geocities, Tripod) that give you completely free webhosting for your site "with at least a CGI-BIN" for CGI-Perl script?
0
 
LVL 6

Expert Comment

by:alamo
ID: 1830852
>One more question.
I count 2 :-)

>Now from experience I have found out when Netscape is downloading a file from a site and when you hit CANCEL it "auto-kills" the file it was saving.  
>is there anyway to tell Netscape 4 to stop donwloading and to leave the file for me to inspect?

I have found killing my internet connection cancels the download but leaves the file. You could also try copying or xcopying the file to another file as it's downloading, that works for me too.

>Thansk again!  and BTW do you know of any FREE WEBHOSTERS out there (ie Geocities, Tripod) that give you completely free webhosting for your site "with at least a CGI-BIN" for CGI-Perl script?

look at http://www.experts-exchange.com/topics/comp/www/cgi/Q.10062179, I don't know any more.
0
 

Expert Comment

by:ljaques
ID: 1830853
Alamo, I've noticed that IE4 seems to have a problem with calls made to CGI scripts returning that HTTP header (Content-type: multipart/x-mixed-replace).  Rather, I just can't get IE4 to work  when it calls these CGI scripts.  Is this true for you to?  

All versions of Netscape seem to work and so it makes me wonder that if Netscape 2.0 can read/understand such a header why can't IE4?  Then again Microsoft and their patented rushing methods...
0
 
LVL 6

Expert Comment

by:alamo
ID: 1830854
It doesn't work for me on IE3, I have never used IE4. x-types are by definition nonstandard, though many are commonplace. Try looking for a site which does streaming video like this  which works in IE4, maybe a different x-type will work.
0

Featured Post

Maximize Your Threat Intelligence Reporting

Reporting is one of the most important and least talked about aspects of a world-class threat intelligence program. Here’s how to do it right.

Join & Write a Comment

Preface This is the third article about the EE Collaborative Login Project. A Better Website Login System (http://www.experts-exchange.com/A_2902.html) introduces the Login System and shows how to implement a login page. The EE Collaborative Logi…
SASS allows you to treat your CSS code in a more OOP way. Let's have a look on how you can structure your code in order for it to be easily maintained and reused.
Viewers will learn one way to get user input in Java. Introduce the Scanner object: Declare the variable that stores the user input: An example prompting the user for input: Methods you need to invoke in order to properly get  user input:
The viewer will learn how to count occurrences of each item in an array.

760 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

20 Experts available now in Live!

Get 1:1 Help Now