Thursday, December 23. 2010Send/Receive messages from Javascript to Flash
I needed to send and receive messages from javascript to a flash movie built in haXe.
Googling showed references to Haxe's remoting class, but there's a much simpler (and possibly less robust!) way using flash's ExternalInterface class. First your going to need a reference to your flash movie. If you've embedded it using flashembed (and you are using flashembed, aren't you?), you can do it like this:
var movieObj;
$(document).ready(function() {
var api = flashembed('background', {src: 'vid.swf', wmode: 'opaque', allowScriptAccess: 'always'});
movieObj = document.getElementById(api.getApi().id);
});
movieObj now contains a reference to the flash movie's DOM element. We can now send messages to the flash movie like this: movieObj.pause(); OK, so far so good. Now we need to tell the flash movie what to do with these messages. In the flash actionscript, register the message with ExternalInterface, something like this:
import flash.external.ExternalInterface;
class Foo {
public function new(){
...
ExternalInterface.addCallback( 'pause', doPause );
}
function doPause() {
trace('got pause()');
}
public static function main() {
new Foo();
}
}
Et voilá. Now to get it working the other way around, you can call any javascript function (your own, or a built-in function) like this:
ExternalInterface.call('jsFunctionName', 'argument');
// eg:
// ExternalInterface.call('alert', 'Foo!');
Sunday, December 12. 2010Full page flash video background
One of my favourite clients — Crush Creative — recently asked me if I could add a full page video background to a website.
Obviously, it was going to have to be built in Flash due to the lack of support for the <video> tag in IE. But I hate working in Flash. Don't get me wrong: I don't hate Flash itself, it's just that I hate the pointy-clicky-where-the-hell-should-I-put-the-code stuff. I guess that if I put my mind to it I could learn the Flash authoring environment, but it just doesn't really suit my development style, and I don't even have a licence for Flash and my evaluation period has expired. But I do have access to haXe, which is a programming environment which lets you write code to target the Flash Player plugin. And it's a 'proper' programming environment: you type in text and compile it. Lovely. So I knocked up a proof-of-concept background flash video player in haXe, and it turned out to be remarkably simple. Here's the code: import flash.Lib;
import flash.display.Stage;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
import flash.events.Event;
import flash.events.NetStatusEvent;
import flash.display.LoaderInfo;
class Vid {
private var mc : flash.display.MovieClip;
private var myVideo : Video;
private static var stage : Stage;
private static var myNetStream : NetStream;
// flashvars
private static var movieUrl : String;
private static var movieWidth : Int;
private static var movieHeight : Int;
private static var bufferTime : Int;
public function new(){
mc = flash.Lib.current;
stage = mc.stage;
// get flashvars describing movie we're going to play
movieUrl = mc.loaderInfo.parameters.movieUrl;
movieWidth = Std.parseInt(mc.loaderInfo.parameters.movieWidth);
movieHeight = Std.parseInt(mc.loaderInfo.parameters.movieHeight);
bufferTime = Std.parseInt(mc.loaderInfo.parameters.bufferTime);
// set up the stage
stage.align = StageAlign.TOP_LEFT;
stage.scaleMode = StageScaleMode.NO_SCALE;
myVideo = new Video();
myVideo.smoothing = true;
var myNetConnect : NetConnection = new NetConnection();
myNetConnect.connect(null);
myNetStream = new NetStream(myNetConnect);
myNetStream.bufferTime = bufferTime;
myNetStream.addEventListener(NetStatusEvent.NET_STATUS, checkNetstreamEvent);
myVideo.attachNetStream(myNetStream);
mc.addChild(myVideo);
myNetStream.play(movieUrl);
stage.addEventListener(Event.RESIZE, ResizeAndPosition);
ResizeAndPosition(null);
}
function checkNetstreamEvent(e:NetStatusEvent) {
// if we've got to the end of the video, rewind it (ie, loop the video)
if (e.info.code == "NetStream.Play.Stop") {
myNetStream.seek(0);
}
}
function ResizeAndPosition(e:Event) {
// resize and position the video to fill the stage without distortion
var stageAspectRatio = stage.stageWidth / stage.stageHeight;
var videoAspectRatio = movieWidth / movieHeight;
if (stageAspectRatio > videoAspectRatio) {
// stage wider than video
myVideo.width = stage.stageWidth;
myVideo.height = (myVideo.width / videoAspectRatio);
// so we need to crop some height
myVideo.y = -((myVideo.height - stage.stageHeight)/2);
myVideo.x = 0;
} else {
// stager taller than video (or same)
myVideo.height = stage.stageHeight;
myVideo.width = (myVideo.height * videoAspectRatio);
// so we need to crop some width
myVideo.x = -((myVideo.width - stage.stageWidth)/2);
myVideo.y = 0;
}
}
public static function main()
{
new Vid();
}
}
When you embed the Flash movie, you need to pass the movie url and dimensions in the flashVars, something like this:
<html>
<script type='text/javascript' src='http://cdn.jquerytools.org/1.2.5/full/jquery.tools.min.js'></script>
<style type='text/css'>
body {
margin: 0;
padding; 0;
background-color: #ddddd;
}
#background {
width: 100%;
height: 100%;
z-index: 1;
}
</style>
<script type='text/javascript'>
$(document).ready(function() {
flashembed('background', {src: 'vid.swf', wmode: 'transparent'}, {
movieUrl: 'ink.flv', // url to movie
movieWidth: '640',
movieHeight: '480',
bufferTime: '10', // secs of video to buffer before starting to play
wmode: 'transparent' // need to set wmode to allow you to float html over the top
});
});
</script>
<body>
<div id='background'></div>
</body>
</html>
Note that you won't be able to float HTML over the Flash movie on Android due to a limitation in the Android Flash Player plugin: "Flash Content is always displayed on top of all HTML content"
(Page 1 of 1, totaling 2 entries)
|
QuicksearchArchivesSyndicate This Blog |

