using ming to create flash files for viewing events

Support and queries relating to all previous versions of ZoneMinder
Locked
teddy
Posts: 15
Joined: Sat Mar 26, 2005 6:05 pm

using ming to create flash files for viewing events

Post by teddy »

Instead of using java or mpeg video, I want to try out flash to view streaming video. I installed the php ming module (ming.sf.net). I created a flash video from some archived events, but I had to use my own PHP script to generate the flash file. It looks good.

I want to know how to alter the ZM code to accept a third method of streaming: flash (or ming).
teddy
Posts: 15
Joined: Sat Mar 26, 2005 6:05 pm

Post by teddy »

OK, I setup ming to view events in flash SWF format. It looks GREAT!! It is faster than using Java (on the client side). It is better looking over the web (IMHO).

The flash file will resize or scale for zoom in / zoom out effect. The rate does not work yet. So you cannot speed up or slow down yet. My cameras capture at 4 frames per second. So this looks like real time viewing for me. You can also toggle play/pause playback by clicking the mouse inside the image.

Here is some code I used:
I edited the zm_html_view_event.php file on line 329 to include this code:

Code: Select all

# this is place to add a flash based viewer.
        elseif ("true")
        {
$slideshow_image_path = ZM_DIR_EVENTS.'/'.$event['MonitorId'].'/'.$event['Id'].'/';
$slideshow_width=reScale($event['Width']);
$slideshow_height=reScale($event['Height']);
$slideshow_rate=$rate;
$slideshow_scale="100";
include("ming_funcs.php");
event_to_swf($slideshow_image_path,$slideshow_width,$slideshow_height,$slideshow_rate,$slideshow_scale);
?>
<embed type="flash/swf"
src="swf/slideshow.swf"
width="<?= reScale( $event['Width'], $scale ) ?>"
height="<?= reScale( $event['Height'], $scale ) ?>"
loop="0">
</embed>
<?php
        }
In pure laziness, the first line "elseif("true")" simply evaluates to true in order to activate this streaming method. A real install would look this up in a database or config file.

As you can see, the code above includes this page, which I created, called "ming_funcs.php", with this code:

Code: Select all

<?php
function event_to_swf($path,$width,$height,$rate,$scale) {
// just put the directories with the jpgs here and compile
$pathtojpgs= array();
$pathtojpgs[0]= $path;
$slide_show_width = $width;
$slide_show_height = $height;

// some typical movie variables
Ming_setScale((20.00000000)*($scale/100));
ming_useswfversion(6);
$movie=new SWFMovie();
$movie->setBackground(33,33,33);
$movie->setRate((4)*($rate/100));
$movie->setDimension($slide_show_width,$slide_show_height);

// basic actionscript control of playback using mouse
$strAction="
if(!init){
        init=true;
        stopped=false;
        controls = {
                onMouseDown: function () {
                        if(!stopped){
                                stop();
                                stopped=true;
                        }else{
                                play();
                                stopped=false;
                        }
                }
        };
        Mouse.addListener(controls);
}
";

$movie->add(new SWFAction($strAction));

// grab the jpgs
$f = array();
for($i=0;$i<count($pathtojpgs);$i++){
        $f[$i] = array();
        if ($handle = opendir($pathtojpgs[$i])) {
                while (false !== ($file = readdir($handle))) {
                        $tmp = explode(".",$file);
                        if( ($tmp[1]=="jpg") && (substr($tmp[0],((strlen($tmp[0]))-7),strlen($tmp[0]))=="capture") ) {
                                array_push ($f[$i],$pathtojpgs[$i] . $file);
                        }
                }
        }
        sort($f[$i]);
}
closedir($handle);

// add the jpgs to the movie with basic fade in/out
$movie->nextFrame();
for($i=0;$i<count($f);$i++){
        for($k=0;$k<count($f[$i]);$k++){
                $img = new SWFBitmap(fopen($f[$i][$k],"rb"));
                $pic=$movie->add($img);
                $pic->moveTo( ((($slide_show_width)/2)-$img->getwidth()/2),((($slide_show_height)/2)-$img->getheight()/2));
                $movie->nextFrame();
                $movie->remove($pic);
        }
}
$movie->nextFrame();
// save the movie
$movie->save("swf/slideshow.swf",9);
}
?>
The code that creates the SWF file is a modified version of sample code at a link off the http://ming.sf.net website. This is the site with the original code: http://www16.brinkster.com/gazb/ming/index.html . The sample code is called "jpg slideshow version 2.0".

I also created a folder called "swf" that user apache owns has write access to. It will store a SWF file called "slideshow.swf".

Installing ming is tough. You have to use the CVS version (that is what I use). You need some packages installed before compiling: php-devel, ungif-devel, bison, flex, and some others. Read the documentation.

I hope everyone enjoys this.
SyRenity
Posts: 301
Joined: Mon Jan 24, 2005 2:43 pm

Post by SyRenity »

Hello.

Sounds interesting! I will try it for sure - thanks for the contribution.

Have you tried to use the FFMPEG to generate the Flash movies from the stored events? You can do so by changing the output file asf extension to swf. For some reason, I have only 1 frame displayed, but perhaps it will work for you.

P.S.: Do you think it is possible to stream the live feed via Flash?
Last edited by SyRenity on Mon Apr 25, 2005 1:26 pm, edited 1 time in total.
teddy
Posts: 15
Joined: Sat Mar 26, 2005 6:05 pm

Post by teddy »

Actually, the rate feature DOES work. The problem is that the entire flash file has to be downloaded first before it will playback at an accelerated rate. When the file is being streamed over the web, it transfers at a rate that is slower than playback speed.

My Zoneminder server can generate SWF files on the fly in less time than it takes to load the cambalooza applet. The SWF files instantly begin playing as the remainder is being streamed. The flash client has a built in zoom feature, high/medium/low quality, and a play/rewind/stop option.

I need to figure out how to stream the live video footage into flash next.
User avatar
zoneminder
Site Admin
Posts: 5215
Joined: Wed Jul 09, 2003 2:07 pm
Location: Bristol, UK
Contact:

Post by zoneminder »

This is interesting stuff. I'd be keen to see a demo of it in action if you ever have one to show.

Phil
teddy
Posts: 15
Joined: Sat Mar 26, 2005 6:05 pm

Post by teddy »

I improved this some so that the SWF file is outputted directly to the web browser. It is not written to a temporary directory.

I created another custom page called "ming_out.php". Here is the code from that page:

Code: Select all

<?php
                                  
$pathtojpgs= array();
#$pathtojpgs[0]= ZM_DIR_EVENTS.'/'.$mid.'/'.$eid.'/';
$pathtojpgs[0]= 'events/'.$mid.'/'.$eid.'/';
$slide_show_width = $width;
$slide_show_height = $height;
                                                                                                                             
// some typical movie variables
Ming_setScale(20.00000000);
ming_useswfversion(6);
$movie=new SWFMovie();
$movie->setBackground(33,33,33);
$movie->setRate((4)*($rate/100));
$movie->setDimension($slide_show_width,$slide_show_height);
                                                                                                                             
// basic actionscript control of playback using mouse
$strAction="
if(!init){
        init=true;
        stopped=false;
        controls = {
                onMouseDown: function () {
                        if(!stopped){
                                stop();
                                stopped=true;
                        }else{
                                play();
                                stopped=false;
                        }
                }
        };
        Mouse.addListener(controls);
}
";
                                                                                                                             
$movie->add(new SWFAction($strAction));
                                                                                                                             
// grab the jpgs
$f = array();
for($i=0;$i<count($pathtojpgs);$i++){
        $f[$i] = array();
        if ($handle = opendir($pathtojpgs[$i])) {
                while (false !== ($file = readdir($handle))) {
                        $tmp = explode(".",$file);
                        if( ($tmp[1]=="jpg") && (substr($tmp[0],((strlen($tmp[0]))-7),strlen($tmp[0]))=="capture") ) {
                                array_push ($f[$i],$pathtojpgs[$i] . $file);
                        }
                }
        }
        sort($f[$i]);
}
closedir($handle);
                                                                                                                             
// add the jpgs to the movie with basic fade in/out
$movie->nextFrame();
for($i=0;$i<count($f);$i++){
        for($k=0;$k<count($f[$i]);$k++){
                $img = new SWFBitmap(fopen($f[$i][$k],"rb"));
                $pic=$movie->add($img);
                $pic->moveTo( ((($slide_show_width)/2)-$img->getwidth()/2),((($slide_show_height)/2)-$img->getheight()/2));
                $movie->nextFrame();
                $movie->remove($pic);
        }
}
$movie->nextFrame();

header('Content-type: application/x-shockwave-flash');
$movie->output();
?>
I also changed the zm_html_view_event.php file around lines 330:

Code: Select all

# this is place to add a flash based viewer.
        elseif (true)
        {
$slideshow_mid=$event['MonitorId'];
$slideshow_eid=$event['Id'];
$slideshow_width=reScale($event['Width']);
$slideshow_height=reScale($event['Height']);
$slideshow_rate=$rate;
$slideshow_scale="100";
$slideshow_src='ming_out.php?mid=' . $slideshow_mid . '&eid=' . $slideshow_eid . '&width=' . $slideshow_width . '&height=' . $slideshow_height . '&rate=' . $slideshow_rate . '&scale=' . $slideshow_scale ;
?>
<EMBED src="<?php echo $slideshow_src; ?>"
width="<?= reScale( $event['Width'], $scale ) ?>"
height="<?= reScale( $event['Height'], $scale ) ?>"
pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash"
LOOP=FALSE>
<?php if($rate>100) {
echo 'quality="low"';
}
?>
</EMBED>
        }
        else
        { 
SyRenity
Posts: 301
Joined: Mon Jan 24, 2005 2:43 pm

Post by SyRenity »

Hi.

Have you got any luck with storing the events in the Flash format? It would be really nice if, if there was some possibility of archiving the events in Flash, thus freeing the disk space considerably.
teddy
Posts: 15
Joined: Sat Mar 26, 2005 6:05 pm

flash filesize

Post by teddy »

Actually, the flash files generated using this method are approximately equal in size to that of all the single jpeg images that makeup an event.

I have not considered storing the events in flash file format. It would make more sense to have ffmpeg generate a .flv file. The .flv file actually uses some sort of compression that flash understands. To learn how to insert a .flv into a .swf file using ming, goto ming.sf.net and look for sample code.
Locked