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:
<script type='text/javascript' src='//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>
<div id="background"> </div>
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"