 |
During my preparation for the Flash CS4 workshop that I’m doing I started to look at a new Flash video format called F4V. So what is the F4V format? Basically it is Adobe’s wrapper for H.264 video. So why do we need this wrapper for an open standard like H.264? Well it turns out the answer is to overcome some of the limitations of H.264 like the inability to embed cue points. I can imagine in the future that we may try to add alpha channel support which H.264 also doesn’t support. |
So this proprietary wrapping makes total sense but unfortunately the cue point functionality doesn’t really work. When encoding a video in Adobe Media Encoder I chose the F4V format and then added an event cue point just like I would with FLV. When I then imported the video into Flash and loaded it into the FLVPlayback component I even saw the event cue point in the component inspector. At this point I was really happy. But then I wrote the standard cue point event handler but the event never fired when it hit the cue point.
Rich Shupe saw one of my tweets about it and emailed a way to actually respond to the cue point. The solution was to respond to the XMP data event of the NetStream class. The code sample is listed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| package {
import flash.display.Sprite;
import flash.media.Video;
import flash.net.NetConnection;
import flash.net.NetStream;
public class F4VCuePoints extends Sprite {
private var _vid:Video = new Video();
public function F4VCuePoints():void {
var nc:NetConnection = new NetConnection();
nc.connect(null);
var ns:NetStream = new NetStream(nc);
ns.client = this;
addChild(_vid);
_vid.width = 200;
_vid.height = 140;
_vid.attachNetStream(ns);
ns.play("scaly.f4v");
}
public function onMetaData(info:Object):void {
}
public function onXMPData(info:Object):void {
var xmpXML:XML = new XML(info.data);
// parse using Namespaces
var xmpDM:Namespace = new Namespace("http://ns.adobe.com/xmp/1.0/DynamicMedia/");
var rdf:Namespace = new Namespace("http://www.w3.org/1999/02/22-rdf-syntax-ns#");
var cueFrameRateString:String = xmpXML..xmpDM::Tracks..rdf::Description.@xmpDM::frameRate;
var cueFrameRate:Number = Number(cueFrameRateString.substr(1,cueFrameRateString.length));
trace("frameRate for DVA Ticks divisor:", cueFrameRate);
var cuePointList:XMLList = xmpXML..xmpDM::markers.rdf::Seq.rdf::li;
var len:int = cuePointList.length();
trace("number of cuePoints:", len);
for (var i:int=0; i < len; i++) {
var cueXML:XML = cuePointList[i];
trace("\tname:", cueXML.@xmpDM::name);
trace("\ttype:", cueXML.@xmpDM::cuePointType);
trace("\tstartTime:", cueXML.@xmpDM::startTime/cueFrameRate, "\n");
}
}
}
} |
Big thanks to Rich for passing this along. It is ridiculous that we have to write that amount of code to respond to F4V cue points. I am hoping that this implementation is not quite finished and we are planning to make it easier in the future.
Update: I have confirmed from an internal source that if you create a navigation cue point on an F4V file, it does not add a keyframe into the video file at that point. Until this is fixed I would advice simply using regular H.264 files with AS cue points.
Lee