First off I need to explain that the srt support comes from converting the .srt file into .xml
The xml structure that must be achieved is the following:
<optionContainer>
<que sec="15" duration="3">
<data>
<value>At the left we can see...</value>
</data>
</que>
<que sec="18" duration="2">
<data>
<value>At the right we can see the...</value>
</data>
</que>
</optionContainer
full file sample at the end of page.
And now on to the hard part:
First we need to make a call to download the subtitles XML and parse them into an array:
public function readXML(src:String){
xmlLoader.load(new URLRequest(src));
xmlLoader.addEventListener(Event.COMPLETE,readXMLData,false,0,true);
}
private var xml_options:Array = new Array();
private function readXMLData(e:Event):void
{
xmlLoader.removeEventListener(Event.COMPLETE,readXMLData,false);
try{
var xmlData = new XML(e.target.data);
var counter:Number = 0;
for each(var item in xmlData.que)
{
var totalItems:Number = item.data.length();
xml_options['que_'+item.@sec] = {'time':Number(item.@sec),
'duration':Number(item.@duration),
data:[{'title':String(item.data[0].value[0])}
]
};
counter += 1;
}
}
catch(err:Error){
trace(err.message);
}
addCues();
}
Now we have an array filled with our subtitles and timings.
At this point we add the addCues function what this function does is to add cue points to the video stream and create a timelineMetaData object, when each entry point of a cue is due time an event will fire, we also create our label here (color is not pure white in order to be visible on white background)
private var subtext:TextField = new TextField();
private function addCues():void
{
player.currentTimeUpdateInterval = 100;
timelineMetaData = new TimelineMetadata(player.media);
timelineMetaData.addEventListener(TimelineMetadataEvent.MARKER_TIME_REACHED, onCuePointHandler, false, 0, true);
timelineMetaData.addEventListener(TimelineMetadataEvent.MARKER_DURATION_REACHED, removeCuePoint,false,0,true);
var cuePoint:CuePoint;
var counter = 0;
for each(var item in xml_options){
// add a cuepoint below:
cuePoint = new CuePoint(CuePointType.ACTIONSCRIPT, item.time, "CuePoint"+item.time, [item.data[0].title],item.duration);
timelineMetaData.addMarker(cuePoint);
counter += 1;
}
subtext.selectable = false;
subtext.setTextFormat(format);
subtext.defaultTextFormat = format;
subtext.text = '';
subtext.textColor = 0xFCF5D1;
subtext.width = _stage.stageWidth/2;
subtext.height = 22;
subtext.x = _stage.stageWidth/2-subtext.textWidth;
subtext.y = _stage.stageHeight-60;
subtext.wordWrap = true;
subtext.name = 'subtext';
this.addChild(subtext);
SubItem = this.getChildByName('subtext'); //for easy reference
}
At this point we have our cues loaded into the media and the event listeners ready to fire.
So lets create the corresponding functions the first one will handle the showcasing of the subtitle (we add a timer in order to remove idle subtitles when their time is passed, at this point I will mention that the duration reached event does not fire as it should and has a delay thus not removing the subtitle as it is supposed to, this solution is custom):
var timer:Timer = new Timer(4000,0); // 4secs or 4000ms is the minimum time the human eye can read 2-line subtitles.
private function onCuePointHandler(e:TimelineMetadataEvent):void
{
if(timer.running){
timer.stop();
timer.removeEventListener(TimerEvent.TIMER,removeCue,false);
}
timer = new Timer((Number(e.marker.duration)+100)*1000,0);
timer.start();
timer.addEventListener(TimerEvent.TIMER,removeCue,false,0,true);
var params = e.marker;
SubItem.text = '';
SubItem.text = String(params.parameters[0]);
SubItem.x = _stage.stageWidth/2-SubItem.textWidth/2;
}
//Removes the cue after 2.1 secs of idleness
private function removeCuePoint(e):void
{
timer.stop();
timer.removeEventListener(TimerEvent.TIMER,removeCue,false);
timer = new Timer(2100,0);
timer.start();
timer.addEventListener(TimerEvent.TIMER,removeCue,false,0,true);
}
//the actual removal function
private function removeCue(e)
{
timer.stop();
timer.removeEventListener(TimerEvent.TIMER,removeCue,false);
SubItem.text = '';
}
Now simply call the readXML function after the media has been initialized on SMP put it at the end of the loadMedia(…_) function.
So this is it now you have subtitles on your videos, again this is a custom solution and not the typical OSMF Plugin. But it works and it is simple enough to implement.
The video I used is this: http://mediapm.edgesuite.net/osmf/content/test/manifest-files/dynamic_Streaming.f4m
and the source XML is here: sample.xml
If I can convince my friend that did the conversion script from .srt to XML to release his code I will post it here too. But it should not be difficult just make sure to convert frames into seconds. (Flowplayer captions plugin source code can help a lot with this).
Enjoy!