b-log – betriebsraum weblog

Software Development, Human-Computer Interaction, Projects…

Flash Video Tip 2: Syncing a FLV between two SWFs

February 28, 2007

Here’s the next flash video tip: It’s about how to synchronize a flv file between two separate swf files. First question is: Why would you want to do this? Honestly I can’t think of too many cases where you would do this but there’s one case where it can be appropriate (and coincidentally it has happened in one of our last projects ;):

Flipping book applications – you certainly know what I mean with flipping book applications (they seem to be quite popular with lots of companies): Online magazines where you can interactively turn pages by dragging the book corners to flip through the pages. Most of them consist of two separate swf files for the left and right page and it can be quite challenging to load / initialize / time things if you have much communication and interactivity going on between the two pages.

What options are there if you want to show a flv that runs synchronously on separate swfs (or in the special flipping book case: the left half of the flv runs on the left page and the right half on the right page)?

  1. Embed the flv into the swf files: Split the video into separate flvs (with your video encoding tool), import the first half into a movieclip in the first swf, the second half into a movieclip in the second swf, preload the two swfs and then start the two movieclip timelines. This could be a simple solution for very short videos (embedding is not recommended for long videos).
  2. Load the flv externally: Split the video into two separate flvs, load the respective flv file in each swf externally and try to synchronize the flvs. »Try to synchronize« means: I haven’t tried it but probably this is a bit of a hassle as you have to stop one flv if the other one is buffering etc., and maybe they won’t run perfectly synchronously. You could preload the complete video into cache first but usually you want to use progressive download (or streaming).
  3. Split the flv at runtime: Load the flv file externally in one of the swfs, capture the video as bitmap data and »project« one half on the first swf and the other half onto the second.

Option 3 seems to be the most interesting and you don’t have to make two separate flvs. By using the Flash 8 BitmapData class you can make a snapshot of the video (or one part of the video) each frame – the actual flv runs invisible and off screen.

Demo (click on the video to start the split-version…).

Get Adobe Flash player

(The example file uses just one swf file but the technique is the same for two separate swfs. The difference is that you have to wait until both swfs are loaded and then call a method to set the second BitmapData object in the second swf).

Here’s the code of the example above:

Stage.scaleMode = "noScale";
 
import flash.display.*;
import flash.geom.*;
import mx.utils.Delegate;
 
var snapBmdL:BitmapData;
var snapBmdR:BitmapData;
var matrixL:Matrix;
var matrixR:Matrix;
var rect:Rectangle;
var snapL_mc:MovieClip;
var snapR_mc:MovieClip;
 
function capture():Void {
	snapBmdL.draw(fp, matrixL, null, null, rect);
	snapBmdR.draw(fp, matrixR, null, null, rect);
}
 
function onFlvRelease():Void {
	fp._visible = false;
	fp._x = -2000;
	fp._y = -2000;
	fp.play();
	this.onEnterFrame = Delegate.create(this, capture);
}
 
function initFlvPlayback():Void {
	fp.autoPlay = false;
	fp.contentPath = "trusted_computing.flv";
 
	fp.onRelease = Delegate.create(this, onFlvRelease);
}
 
function initBitmaps():Void {
	snapBmdL = new BitmapData(fp.width/2, fp.height, true, 0x00000000);
	snapBmdR = new BitmapData(fp.width/2, fp.height, true, 0x00000000);
 
	matrixL = new Matrix();
	matrixR = new Matrix();
	matrixR.translate(-fp.width/2, 0);
 
	rect = new Rectangle(0, 0, fp.width/2, fp.height);
 
	snapL_mc = this.createEmptyMovieClip("snapL_mc", 1);
	snapL_mc._x = 0;
	snapL_mc.attachBitmap(snapBmdL, 0, "auto", true);
	snapR_mc = this.createEmptyMovieClip("snapR_mc", 2);
	snapR_mc._x = Stage.width - fp.width/2;
	snapR_mc.attachBitmap(snapBmdR, 0, "auto", true);
}
 
function init():Void {
	initFlvPlayback();
	initBitmaps();
}
 
init();

There are two BitmapData objects that capture parts of the video pixels. In the case of two swfs, the first swf would setup a BitmapData object in the second swf and reference it in the capture() method. The rest would be the same. The region is defined by a rectangle object (half the size of the video) and a translation matrix shifts the pixels for the second region to the left. In the onEnterFrame event, the video data is drawn into the same BitmapData objects each time. I’ve tested it with a 800×400 video and it still runs smoothly. Just make sure to dispose() all BitmapData if you remove the video.

Download the example files.

(The test video is again the “Trusted Computing” movie, see Flash Video Tip 1…)

Filed under: Flex/AS3

4 Responses to “Flash Video Tip 2: Syncing a FLV between two SWFs”

  1. Dustin Senos says:

    Wow. thanks for the heads up, I haven’t had to sync video yet, but this has been bookmarked for when the time comes.

    One of the big uses for this would be the banner ads that you see that are synced up.

  2. Me says:

    I was looking for flipping book source
    found some here:
    flipping book fla source

  3. Colin says:

    Hi,

    I have tried everything I could think of to get this to work but have hit the wall. Perhaps you could spare a moment and help me before I have no hair left. If you go to the web site I have the Flip book up with links to all the files should you need to look at them.

    Cheers, Colin

  4. great piece. very informative. Thank You!

Add a comment

Follow comments to this post by subscribing to the comment feed.