Here's one I made earlier.
This simple Player uses the new FLV Captioning Component in Flash CS3 (note: Flash CS3 is currently available as part of some of the new CS3 Suites. The standalone product will follow). It's a simple demo but you got to admit that it's pretty neat - consider also that the captions are read from an external file.
No sources this time (sorry) as this is part of a commercial project I'm working on. However it will be easy to recreate once you got Flash CS3.
This simple Player uses the new FLV Captioning Component in Flash CS3 (note: Flash CS3 is currently available as part of some of the new CS3 Suites. The standalone product will follow). It's a simple demo but you got to admit that it's pretty neat - consider also that the captions are read from an external file.
No sources this time (sorry) as this is part of a commercial project I'm working on. However it will be easy to recreate once you got Flash CS3.


(firefox 2.003 flash 9.0.16)
subtitle-horse.org is an online subtitle creator tool for flv videos. you don`t need to have a software installed and you can
also transform different formats like srt to timedtext (e.g.)
And the styling part in the xml file has no effect.
Can you please tell how you did that?
Thanks
I created my own custom movieclip to display the captions and set the background of that to semi transparent. Check the Flash docs for details on how to use Movieclips as a target for the caption display. You can make it look any way you want.
I'm not seeing anythhing like that for AS3.
http://kb.adobe.com/selfservice/viewContent.do?ext...
I'm trying to find the code to check when the CC button is clicked. Do you know this?
I created a backgound for the captions and want to make it visible/invisble everytime you click on the CC button.
Thanks,
import fl.video.VideoEvent;
// listen for when the skin has loaded into the
// FLVPlayback component (myFLVPB). When that
// happens call the skinLoaded handler
myFLVPB.addEventListener(VideoEvent.SKIN_LOADED, skinLoaded);
// The skinLoaded event handler will set showCaptions
// to false after the FLVPlaybackCaptions component (myFLVCP)
// has associated itself with the CaptionButton in the skin function
skinLoaded(event:VideoEvent):void {
myFLVCP.showCaptions = false;
}
Can someone help please?
Thanks.
Carol
thank you!
The xml file is here http://www.parature.com/videos/parature_implementa...
And part of the code I use is the following one:
import fl.video.FLVPlayback;
import fl.video.FLVPlaybackCaptioning;
import fl.video.MetadataEvent;
import fl.video.VideoEvent;
import fl.video.CaptionChangeEvent;
import flash.events.Event;
var vid_demo:FLVPlayback = new FLVPlayback();
var vid_caption:FLVPlaybackCaptioning = new FLVPlaybackCaptioning();
var myCaptionBgr:caption_bgr = new caption_bgr();
addChildAt(vid_demo, 0);
addChildAt(vid_caption, 1);
addChildAt(myCaptionBgr, 2);
myCaptionBgr.x = 0;
myCaptionBgr.y = 455;
myCaptionBgr.visible = false;
...other lines...
vid_caption.addEventListener(CaptionChangeEvent.CAPTION_CHANGE, caption_listener);
vid_caption.addEventListener(Event.COMPLETE, caption_complete);
vid_demo.addEventListener(MouseEvent.CLICK, caption_click);
function caption_listener (eventObject: CaptionChangeEvent):void
{
myCaptionBgr.visible = true;
//trace("caption change" );
}
function caption_complete (eventObject: Event):void
{
//trace("caption complete");
}
function caption_click (eventObject: MouseEvent):void
{
//trace(eventObject.target.name);
if ( eventObject.target.name == "instance185")
myCaptionBgr.visible = true; //CC ON
if ( eventObject.target.name == "instance172")
myCaptionBgr.visible = false; //CC OFF
}
stop();
If you send me your email, I can send you the FLA file and you'll see the whole code and frames. I don't have a problem sharing the source. If you know a way to optimize, I'm open to suggestions.
Yesi
Carol
also, have you figured out carol's problem? captioning in a playlist? i'm still trying to find a solution to that.
suggestions appreciated!
many thanks.
Thanks for your comment. I just sent you the FLA and XML file. Please let me know if you have a problem opening it. It's a Flash CS3.
Sorry but I haven't worked with playlists and captions at the same time. Just in case, if you don't know there is a really good flash player that deals with everything (captions, skins, one final link, etc). It's here http://www.jeroenwijering.com/?item=JW_FLV_Media_P... I used it a lot when I have an FLV video to include. I couldn't use it for the project I'm attaching because I needed an extra final flash slide with multiple call of actions, so I couldn't integrate it. Otherwise, I would use it. You can see samples and a wizard where you can see what you can do with the player http://www.jeroenwijering.com/?page=wizard
I have projects on my site using this player: http://www.parature.com/customers.aspx The red icon on the right, "Customer video clips - Watch now", use a playlist and the single "Video Clip" links next to the customer quotes (right side), play a single video.
Good luck!
Yesi
I can't believe there isn't someone out there who knows how to create closed captioning for a playlist AND who can write a step-by-step tutorial for newbies.
Yoo hoo... we're willing to pay good money for such a tutorial.
Any takers?
While I'm asking for things, does anyone know how to loop videos in an flv playlist that's controlled by XML? I'd like to add a Loop button that would continuously play all the videos in the playlist, without stopping unless the user closed down the player.
I'd also like to see a tutorial on how to create a user-generated playlist.
I've downloaded Jeroen Wijering's player and read tutorials, but it will be a while yet before they'll do closed captioning on their most recent playlist player. It's a good system, but sometimes they don't realize that a lot of their following doesn't have a lot of experience and we need more handholding.
Carol
I'm not sure if you have been able to solve this problem yet, but I created an flv playlist controlled by xml that can do exactly what you want. it will autoplay through all the nodes in the xml with a simple change.
As for the user input data to write the xml, I pulled in C# dev to handle that :-p.
view it here http://www.joycemeyer.org/ourministries/broadcast/...
var myVar:Number = 0;
// I am using a query as the controller below
if(root.loaderInfo.parameters.myVar > 0)
{
myVar = root.loaderInfo.parameters.myVar;
}
var flvControl:FLVPlayback = new FLVPlayback();
var caption_grp.captionControl:FLVPlaybackCaptioning = new FLVPlaybackCaptioning();
/* ... other code ... */
flvControl.addEventListener( VideoEvent.COMPLETE, nextMovie );
function nextMovie(event:Event):void
{
if (flvControl.playing == false)
{
myVar++;
if (myVar == videoList.length)
{
myVar = 0;
}
flvControl.source = (videoList[ myVar ]);
caption_grp.captionControl.source = vidCaption[ myVar ];
}
}
I hope this helps :-)
import fl.video.*;
import flash.display.*;
import flash.events.Event;
import flash.text.TextField;
var flvControl = vid_mc.myVid;
var videoList:Array = [];
var vidCover:Array = [];
var vidCaption:Array = [];
var xmlLocation:String = "";
var b:Number = 0;
var myVar:Number = 0;
// I am using the browser to query videos and to control other .swf files that relate to this player
if(root.loaderInfo.parameters.myVar > 0)
{
myVar = root.loaderInfo.parameters.myVar;
}
// load a variable xml file ***<item><xmlFile><url>YOUR_XML.xml</url></xmlFile></item>
var settingsXML:String = "settings.xml";
var loadSettings:URLLoader = new URLLoader();
var requestSettings:URLRequest = new URLRequest(settingsXML);
loadSettings.load(requestSettings);
loadSettings.addEventListener(Event.COMPLETE , settingsLoaded );
function settingsLoaded(event:Event):void
{
var theSettings:XML = new XML (loadSettings.data);
xmlLocation = theSettings.xmlFile.url;
// what to do with the requested xml file
var xmlURLLoader:URLLoader = new URLLoader();
var xmlURLRequest:URLRequest = new URLRequest(xmlLocation);
xmlURLLoader.load(xmlURLRequest);
xmlURLLoader.addEventListener(Event.COMPLETE , dataLoaded );
function dataLoaded(event:Event):void
{
var theXMLData:XML = new XML (xmlURLLoader.data);
var a:Number = theXMLData.videoData.video_path.length();
while (b < a)
{
//display videos in these date ranges
var startDate = new Date(Date.parse(theXMLData.videoData.videoStartDate[b]));
var endDate = new Date(Date.parse(theXMLData.videoData.videoEndDate[b]));
var today = new Date();
if(startDate <= today && today <= endDate)
{
// video location
videoList.push( theXMLData.videoData.video_path[b] );
// still image for video
vidCover.push( theXMLData.videoData.video_cover[b] );
// xml file location for video
vidCaption.push( theXMLData.videoData.video_caption[b] );
}
b++;
}
// set up flvControl
flvControl.autoPlay = false; // set to true if you want it to loop
flvControl.source = videoList[ myVar ];
flvControl.skin = "SkinUnderPlaySeekCaption.swf"; // use the skin of your choice
flvControl.skinBackgroundColor = 0x000000;
flvControl.skinBackgroundAlpha = 1;
flvControl.skinAutoHide = false;
//flvControl.skinScaleMaximum = 2.5; // I do not fully understand
flvControl.addEventListener(VideoEvent.SKIN_LOADED, skinLoaded);
// set up captionControl
with(caption_grp)
{
captionControl.flvPlayback = flvControl;
captionControl.source = vidCaption[ myVar ];
captionControl.autoLayout = false;
captionControl.addEventListener(CaptionChangeEvent.CAPTION_CHANGE, onCaptionChange);
}
function onCaptionChange(event:CaptionChangeEvent):void
{
var caption_sprite:* = event.target.captionTarget;
var flvControl:FLVPlayback = event.target.flvPlayback;
// move caption_sprite
caption_sprite.y = 180;
caption_sprite.x = 10;
}
function skinLoaded(event:VideoEvent)
{
caption_grp.captionControl.showCaptions = false;
}
// set up cover
var coverIMGPathVar:String = vidCover[ myVar ];
var CILdr:Loader = new Loader();
var CIURLReq:URLRequest = new URLRequest ( coverIMGPathVar );
CILdr.load( CIURLReq );
CILdr.contentLoaderInfo.addEventListener(Event.COMPLETE , CILoaded);
function CILoaded(event:Event):void
{
coverIMGbox.addChild( CILdr.content );
}
}
}
flvControl.stop();
flvControl.volume = 1;
coverVar.buttonMode = true;
coverVar.useHandCursor = true;
coverVar.addEventListener(MouseEvent.CLICK, playRemove);
function playRemove(event:MouseEvent):void
{
flvControl.play();
coverVar.visible = false;
coverIMGbox.visible = false;
// comment for testing
var gaTracker:String = "javascript: pageTracker._trackPageview(" + vidCover[myVar] + ");";
var trackGA:URLRequest = new URLRequest( gaTracker );
navigateToURL ( trackGA, "_self");
}
// gets rid of covers
flvControl.addEventListener( VideoEvent.PLAYING_STATE_ENTERED, playingMovie );
function playingMovie(event:Event):void
{
flvControl.play();
coverVar.visible = false;
coverIMGbox.visible = false;
}
// next movie events
flvControl.addEventListener( VideoEvent.COMPLETE, nextMovie );
function nextMovie(event:Event):void
{
if (flvControl.playing == false)
{
myVar++;
coverVar.visible = true;
coverIMGbox.visible = true;
if (myVar == videoList.length)
{
myVar = 0;
}
flvControl.source = (videoList[ myVar ]);
flvControl.seek(0);
caption_grp.captionControl.source = vidCaption[ myVar ];
}
}
// update time
this.addEventListener (Event.ENTER_FRAME, updateNP);
function updateNP(event:Event):void
{
// time code code...
var totalSeconds:Number = flvControl.playheadTime;
var totalSeconds2:Number = flvControl.totalTime;
var minutes:Number = Math.floor(totalSeconds /60);
var minutes2:Number = Math.floor(totalSeconds2 /60);
var seconds = Math.floor (totalSeconds) % 60;
var seconds2 = Math.floor (totalSeconds2) % 60;
if (seconds < 10)
{
seconds = "0" + seconds;
}
if (seconds2 < 10)
{
seconds2 = "0" + seconds2;
}
timeBox.text = minutes + ":" + seconds;
timeBox2.text = minutes2 + ":" + seconds2;
}
Please let me know if anyone has questions.
1. Create an .xml document that looks like this (example).
2. In your FLA file, add this code... in this area...
If you're interested in creating a full solution for people (and get paid for it!), you might want to check out becoming a provider at Flash Den (www.flashden.net/page/author_program). Check out some of their flv players.
In the meantime, if you have the time (and desire) to be more step-by-step for me (and the other needy folks on this site), I'd sure appreciate it.
Thanks again.
Carol
Do you have a sample XML file you can post for us?
Thanks.
Carol
settings.xml:
<?xml version="1.0" encoding="utf-8"?>
<settings>
<xmlFile>
<!-- allows you to change the location of the xml file w/o changing your Flash file -->
<url>sample.xml</url>
</xmlFile>
</settings>
sample.xml:
<?xml version="1.0" encoding="utf-8"?>
<videos>
<videoData>
<video_cover>YOUR_VIDEO_COVER.jpg</video_cover>
<video_caption>YOUR_VIDEO_CAPTIONS.xml</video_caption>
<video_path>YOUR_VIDEO_PATH.flv</video_path>
<videoStartDate>02/02/2009</videoStartDate>
<videoEndDate>12/31/2009</videoEndDate>
</videoData>
<!-- THE NEXT VIDEO -->
<videoData>
<video_cover>YOUR_VIDEO_COVER.jpg</video_cover>
<video_caption>YOUR_VIDEO_CAPTIONS.xml</video_caption>
<video_path>YOUR_VIDEO_PATH.flv</video_path>
<videoStartDate>02/01/2009</videoStartDate>
<videoEndDate>12/31/2009</videoEndDate>
</videoData>
<!-- THE NEXT VIDEO -->
<videoData>
<video_cover>YOUR_VIDEO_COVER.jpg</video_cover>
<video_caption>YOUR_VIDEO_CAPTIONS.xml</video_caption>
<video_path>YOUR_VIDEO_PATH.flv</video_path>
<videoStartDate>01/31/2009</videoStartDate>
<videoEndDate>12/31/2009</videoEndDate>
</videoData>
</videos>
captions0.xml:
<?xml version="1.0" encoding="UTF-8"?>
<tt xmlns="http://www.w3.org/2006/04/ttaf1" xmlns:tts="http://www.w3.org/2006/04/ttaf1#styling" target="_blank">http://www.w3.org/2006/04/ttaf1#styling" xml:lang="en">
<head>
<styling>
<style id="defaultSpeaker" tts:fontSize="24" tts:fontFamily="Arial" tts:fontWeight="normal" tts:fontStyle="normal" tts:textDecoration="none" tts:color="white" tts:backgroundColor="black" tts:textAlign="center" />
<style id="defaultCaption" tts:fontSize="14" tts:fontFamily="Arial" tts:fontWeight="normal" tts:fontStyle="normal" tts:textDecoration="none" tts:color="white" tts:backgroundColor="black" tts:textAlign="center" />
</styling>
</head>
<body style="defaultCaption" id="thebody">
<div xml:lang="en">
<p begin="00:00:00.03" end="00:00:01.47" tts:textAlign="left">Some text would go here</p>
<p begin="00:00:1.47" end="00:28:32.00" tts:textAlign="left">This is the end of the captions. It will stay here until the movie is over because I want it to :-p</p>
</div>
</body>
</tt>
I will upload and post the src files tomorrow, but I hope this would make a good starting point :-).
I'll have time in a day or two to give this a whirl. Thanks in advance for posting the files for us.
Standing ovation, my friend.
Carol
http://www.toddvaughn.com/video_tuts.zip
you can see it work here:
http://www.toddvaughn.com/video_tuts/xml_video_cc....
if anyone has questions don't hesitate to give me a shout. unfortunately I haven't had time to do a tut, but maybe that will come in the near future.
The Flash/XML I created here is a standard I use for all Flash/XML projects; video, photo, MP3. Photo is very similar to video, but MP3 players are a different animal. I will help with if anyone has questions on any of these.
I try your link but I receive:
Error 500 - Internal server error
Please reupload your interesting player.
a fully functioning version of the above mentioned can be downloaded here:
http://www.toddvaughn.com/video_tuts.zip
you can see it work here:
http://www.toddvaughn.com/video_tuts/xml_video_cc....
http://www.joycemeyer.org/ourministries/broadcast/...
The users on the website I'm working on need to be able to see all the videos, select one and then play it--I basically need a similar setup as you have on joycemeyer.org but including captions.
Do you happen to have the source file to include the playlist?
Thank you!
embed you flash player with this:
function QueryString(key)
{
var value = null;
for (var i=0;i<QueryString.keys.length;i++)
{
if (QueryString.keys[i]==key)
{
value = QueryString.values[i];
break;
}
}
return value;
}
QueryString.keys = new Array();
QueryString.values = new Array();
function QueryString_Parse()
{
var query = window.location.search.substring(1);
var pairs = query.split("&");
for (var i=0;i<pairs.length;i++)
{
var pos = pairs[i].indexOf('=');
if (pos >= 0)
{
var argname = pairs[i].substring(0,pos);
var value = pairs[i].substring(pos+1);
QueryString.keys[QueryString.keys.length] = argname;
QueryString.values[QueryString.values.length] = value;
}
}
}
QueryString_Parse();
function writeVideo()
{
var width = '340'
var height = '280'
var src = 'video.swf'
var queries = '?v='+QueryString('v')
var l1 = '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/...=9,0,115,0" width="'+width+'" height="'+height+'">';
var l2 = '<param name="movie" value="'+src+queries+'" />';
var l3 = '<param name="quality" value="high" />';
var l4 = '<param name="wmode" value="transparent" />';
var l5 = '<param name="allowFullScreen" value="true" />';
var l6 = '<embed src="'+src+queries+'" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" allowFullScreen="true" wmode="transparent" type="application/x-shockwave-flash" width="'+width+'" height="'+height+'"></embed>';
var l7 = '</object>'
document.write(l1+l2+l3+l4+l5+l6+l7)
}
else
{
// flash is too old or we can't detect the plugin
var alternateContent = "This content requires the Adobe Flash Player. "
+ "<a href=http://www.adobe.com/go/getflash/>Get Flash</a>";
document.write(alternateContent); // insert non-flash content
}
I usually put this in a .js and call it in the html to reduce cluster:
<script lanuage="javascript" src="folder/your_swf.js"></script>
The links (rather flash or HTML) should include the query of the node you want displayed i.e. - http://yourdomain.com/video_page.html?v=2 would show the 3rd video (remember that in code your count starts at 0).
Hope this helps, let me know if it does not and I will upload and post a working example... i may do that anyway - stay tuned :-)
I'm still in the process of getting more comfortable w/ ActionScript and a working example is very helpful. Thank you again, Todd, providing this code is very generous of you!!
What I'm trying to build is a playlist for the videos, so a user can then pick one and watch. The screen will also need to show a preview image on the load of the page.
So I don't think I'd be querying separate components for that. My player and playlist would function similarly to [but look a little bit different] what you have on: http://www.joycemeyer.org/ourministries/broadcast/...
Visually, my playlist will look more like the one on www.cnn.com They display a list of videos in the "Next Up" box along w/ a thumbnail, Title and time of the video.
Thanks lots! Lorie
http://www.toddvaughn.com/sample.zip
I will not keep this file online so please let me know when you have downloaded it :-)