For the latest approach to subtitling videos using the Brightcove Player APIs, read Displaying DFXP Captions for a Video instead.
This customized player shows what I believe to be the simplest and most effective approach to a basic implementation of subtitling (or captioning) in normal and full screen mode.
Cue point definitions are not required. Instead, this example uses the video progression index and standard subtitling text formats. This means it's really easy to use this with videos for which you have the subtitling text and time indexes available in a standard format like .srt.
The article also shows how to use a free subtitling tool to create subtitle files you can use with this approach.
The subtitling text size will automatically switch when in player or full screen mode. Click here to see the player I've created using this methodology. And here's how you do it . . .
There are several standards for subtitle text files. What they all have in common is a combination of time codes and the text to display. In this rudimentary example, I'll be using a plain text format, which is widely used and has the advantage of having free subtitle editing tools available.
I often use a free tool called SubCreator, which you can download here. It's a basic subtitle editor with nifty keyboard shortcuts that saves your subtitles in easily readable text files. I recommend you use Windows Media Player (WMP) as the viewer and download the FLV codec for WMP from the same site. That way, you can view Flash Streaming Video files from WMP and also in the subtitle editor.
The text file for the movie shown above looks something like this:
00:00:23.0:My Son 00:00:25.5:The day you were born - 00:00:26.7:the very forests of Lordaeron whispered the name - 00:00:34.0:Arthas. 00:01:21.0:My child 00:01:24.0:I watched with pride as you grew into a weapon - 00:01:29.5:Of righteousness. 00:01:39.0:Remember - our line has always ruled 00:01:43.0:with wisdom, and strength. 00:01:48.5:And I know you will show restraint 00:01:51.6:when exercising your great power. 00:02:46.3:But the truest victory, my son, 00:02:49.7:is stirring the hearts of your people. 00:03:01.4:I tell you this 00:03:04.0:for when my days have come to an end, 00:03:08.4:You shall be king.
Pretty straightforward. So now let's get down to integrating this with a Brightcove player.
The basics for this are already covered in the documentation, so here's just a quick rundown:
Then add the standard code to embed the player into your Flash project:
import BrightcovePlayer;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
Security.allowDomain("*");
var bcp:BrightcovePlayer = new BrightcovePlayer();
bcp.addEventListener("templateLoaded", templateLoaded);
addChild(bcp);
var mPlayer:Object;
var mContent:Object;
var mExp:Object;
function templateLoaded(evt:Event):void
{
mPlayer = bcp.getModule("videoPlayer");
mContent = bcp.getModule("content");
mExp = bcp.getModule("experience");
mExp.addEventListener("templateReady", templateReady);
}
Since this is a basic example, I'll just insert the text code into an array of strings, but if you extend on the principle, the subtitle file could be served by a web server dynamically.
var subtitles:Array = new Array(16); subtitles[0] = "00:00:23.0:My Son"; subtitles[1] = "00:00:25.5:The day you were born -"; ...
We'll be creating two overlays: for normal and full screen display. For this purpose, I've created two simple movieclips that contain a dynamic TextField with the appropriate font and color settings, and added these to the library. Why don't I put them right into the Flash movie in a separate layer? Because the Brightcove player is created dynamically and placed in the movie with the addChild() function. This puts the player on the top visible layer in your Flash movie and thus obscures everything that was created statically. So we'll create the subtitle movieclips dynamically as well – after we've created the Brightcove player. (Don't forget to expose your movieclips with Linkage.)
We'll also need to know which text is displaying, and how long it's been on the screen, so we can set a timeout.
The last thing we need is to know the timecode of the movie playing. Fortunately, all we need to do is add a mediaProgress event listener for the Brightcove Player.
var cursub:String = "";
var secs:int = 0;
var st:Subtitle = new Subtitle();
addChild(st);
st.visible = false;
st.x = 0;
st.y = 360;
var ft:FSTitle = new FSTitle();
addChild(ft);
ft.visible = false;
mPlayer.addEventListener("mediaProgress", mediaProgress);
And now all we need to do is code the mediaProgress event handler. This will check the time code and the state of the player (normal or full screen), and display the corresponding subtitle movieclip, while making the subtitle movieclip for the other player state invisible. To do so, we simply compare the time code of the stream to the timecode in the text. If they correspond, we set the Caption of the visible subtitle movieclip and start a countdown of 4 seconds:
function mediaProgress(evt:Object):void
{
var time : Number = evt.position;
var seconds : int = time % 60;
var minutes : int = ( time / 60 ) % 60;
var hours : int = (time / 3600 ) % 3600;
var sText:String = addLeading( "0", String( hours ), 2 ) + ":"
+ addLeading( "0", String( minutes ), 2 )
+ ":" + addLeading( "0", String( seconds ), 2 );
for(var i:int = 0; i < 16; i++)
{
var ws:String = subtitles[i];
if( ws.indexOf(sText) == 0 )
{
cursub = ws;
secs = 0;
break;
}
}
secs++;
if (secs >= 100 )
{
cursub = "";
}
st.Caption.text = cursub.substr(11,255);
ft.Caption.text = st.Caption.text;
if( stage.displayState == StageDisplayState.FULL_SCREEN)
{
ft.x = 0;
ft.y = stage.stageHeight - 120;
ft.Caption.width = stage.stageWidth;
st.visible = false;
ft.visible = true;
}
else
{
st.visible = true;
ft.visible = false;
}
}
That's it!