Jul. 03, 2008Matt
I've customized the player a bit to support text overlays on the video clip. I've got the code in working order to support multiple text overlays. You can give it a location in pixels, percents or direction (left, middle, right, top, bottom). The text get repositioned and resized proportionately when the video is resized (or a new video gets loaded with different dimensions). The code is pretty rough right now, but I even have it hooked into javascript, so you can add/update the overlays through js as you need to. I figured I'd share it with you, since I've seen some people request such features. Here are the directions and code to use this:
1. Open the mediaplayer.fla file.
2. (Adding the font to use allowing transparency) Right-click in the Library area and select "New Font...". Name the font "OverlayFont" and select whatever font you want to use for the overlays. Check the "Bold" box. Click "OK". Right-click the new "OverlayFont" item in the library and select "Linkage...". Check the boxes for "Export for ActionScript" and "Export in first frame". Make sure the Identifier is set to "OverlayFont". Click "OK".
3. (Setup overlay code in first from of .fla file) Click the first frame of the script layer and press F9. Add the following code after the line that reads "com.jeroenwijering.players.MediaPlayer.main();":
var overlayBaseSize = (infoBase == undefined) ? 300 : parseInt(infoBase); // Base text size
var overlayPadding = (infoBuffer == undefined) ? 0 : parseInt(infoBuffer); // Padding around overlays
var overlayAlpha = (infoAlpha == undefined) ? 60 : parseInt(infoAlpha); // Transparency
// Text overlays
var textOverlays = new Array();
// Font style
var overlayFontFormat:TextFormat = new TextFormat();
overlayFontFormat.bold = true;
overlayFontFormat.font = "OverlayFont";
overlayFontFormat.color = 0xFFFFFF;
overlayFontFormat.size = 8;
// Position an overlay on the video
function setOverlay(idx, txt, alignment)
{
var overlayFound = false;
// See if overlay exists
for(var i in textOverlays)
{
if(textOverlays[i].idx == idx)
{
// Update existing overlay
overlayFound = true;
if(txt != "")
{
textOverlays[i].txtField.text = txt;
textOverlays[i].txtField.setTextFormat(overlayFontFormat);
}
if(alignment != "") textOverlays[i].alignment = alignment;
}
}
// Overlay not found, create it
if(!overlayFound)
{
var tmpObj = {};
var tmpTF = _root.createTextField("tmp", 100+textOverlays.length, 0, 0, 0, 0);
tmpTF.embedFonts = true;
tmpTF._visible = false;
tmpTF.autoSize = true;
tmpTF._alpha = overlayAlpha;
tmpTF.text = txt;
tmpTF.setTextFormat(overlayFontFormat);
tmpObj.idx = idx;
tmpObj.txtField = tmpTF;
tmpObj.alignment = alignment;
textOverlays[textOverlays.length] = tmpObj;
}
}
// Optimal width for movie
var alphaWidth = overlayBaseSize;
// Initialize overlays
var lastVidWidth = -1;
function initTextOverlays()
{
if(Stage.width == lastVidWidth) return;
lastVidWidth = Stage.width;
for(var i in textOverlays)
{
// Scale text depending on size
var scale = 100 * Math.round(_root.player.display.video._width / alphaWidth);
textOverlays[i].txtField._xscale = textOverlays[i].txtField._yscale = scale;
// Make sure we have a proper alignment
var coords = textOverlays[i].alignment.split(",");
if(coords.length != 2)
{
coords[0] = "l";
coords[1] = "t";
}
// Set horizontal position
switch(coords[0].toLowerCase())
{
case "l":
textOverlays[i].txtField._x = _root.player.display.video._x + overlayPadding;
break;
case "m":
textOverlays[i].txtField._x = _root.player.display.video._x + ((_root.player.display.video._width - textOverlays[i].txtField._width) / 2);
break;
case "r":
textOverlays[i].txtField._x = _root.player.display.video._x + _root.player.display.video._width - textOverlays[i].txtField._width - overlayPadding;
break;
default:
var hBasePos = _root.player.display.video._x;
var hMultiple = 1;
if(coords[0].indexOf("*") > -1)
{
// Start from the right of the video
hBasePos = _root.player.display.video._x + _root.player.display.video._width;
coords[0] = coords[0].strreplace("*", "");
hMultiple = -1;
}
// Something else, like number/percent coordinates
var hAdjust = 0;
var numVal = coords[0].strreplace("%", "");
if(coords[0] != numVal)
{
// Percentage value
numVal = numVal / 100;
hAdjust = _root.player.display.video._width * numVal;
//textOverlays[i].txtField._x = _root.player.display.video._x + (_root.player.display.video._width * numVal);
}
else
{
// Number val
hAdjust = numVal;
//textOverlays[i].txtField._x = _root.player.display.video._x + numVal;
}
// Position overlay
textOverlays[i].txtField._x = hBasePos + (hAdjust * hMultiple);
break;
}
// Set vertical position
switch(coords[1].toLowerCase())
{
case "t":
textOverlays[i].txtField._y = _root.player.display.video._y;
break;
case "b":
textOverlays[i].txtField._y = (_root.player.display.video._y + _root.player.display.video._height) - textOverlays[i].txtField._height;
break;
default:
var vBasePos = _root.player.display.video._y;
var vMultiple = 1;
var vAdjust = -1 * textOverlays[i].txtField._height;
if(coords[1].indexOf("*") > -1)
{
// Start from the bottom of the video
vBasePos = _root.player.display.video._y + _root.player.display.video._height;
coords[1] = coords[1].strreplace("*", "");
vMultiple = -1;
vAdjust = 0;
}
// Something else, like number/percent coordinates
var numVal = coords[1].strreplace("%", "");
if(coords[1] != numVal)
{
// Percentage value
numVal = numVal / 100;
vAdjust += _root.player.display.video._height * numVal;
}
else
{
// Number val
vAdjust += numVal;
}
// Position overlay
textOverlays[i].txtField._y = vBasePos + (vAdjust * vMultiple);
break;
}
// Make sure text isn't out of bounds
if(textOverlays[i].txtField._x < _root.player.display.video._x + overlayPadding) textOverlays[i].txtField._x = _root.player.display.video._x + overlayPadding;
if(textOverlays[i].txtField._x + textOverlays[i].txtField._width > _root.player.display.video._x + _root.player.display.video._width - overlayPadding) textOverlays[i].txtField._x = _root.player.display.video._x + _root.player.display.video._width - textOverlays[i].txtField._width - overlayPadding;
if(textOverlays[i].txtField._y < _root.player.display.video._y + overlayPadding) textOverlays[i].txtField._y = _root.player.display.video._y + overlayPadding;
if(textOverlays[i].txtField._y + textOverlays[i].txtField._height > _root.player.display.video._y + _root.player.display.video._height - overlayPadding) textOverlays[i].txtField._y = _root.player.display.video._y + _root.player.display.video._height - textOverlays[i].txtField._height - overlayPadding;
textOverlays[i].txtField._visible = true;
}
}
String.prototype.strreplace = function(pattern, replacement)
{
return this.split(pattern).join(replacement);
}
4a. (Reposition overlays when a new video starts) Open the FLVModel.as file. At the end of the the setStart() function after the line that reads "loadedInterval = setInterval(this,"updateLoaded",100);" add the following code:
// Reset overlays when a new video starts
_root.lastVidWidth = 0;
4b. At the end of the updatePosition() function right before the line that reads "};" add the following code:
if(currentPosition > 0) _root.initTextOverlays();
5. (Allowing the overlays to change size) Open the DisplayView.as file. At the end of the scaleClip() function after the line that reads "tgt.mc.gotoAndPlay(tcf);" add the following code:
// Reset size of overlays
_root.lastVidWidth = 0;
6. (Sending javascript event for overly) Open the AbstractView.as file. Add the following function at the end of the file just before the last line that reads "}":
/** Add/update overlay **/
private function overlaySetInfo(idx:String,txt:String,alignment:String) {
_root.setOverlay(idx, txt, alignment);
};
7. (Adding the javascript callback) Open the JavascriptView.js file. Add the following code after the line that reads "ExternalInterface.addCallback("sendEvent",this,sendEvent);":
ExternalInterface.addCallback("setOverlay",this,overlaySetInfo);
That's it for the setup. Sorry for the length of steps. I know the code is still a little junked up. If anyone has suggestions on better places to put this code, please let me know. I just did the bulk of it from the script layer on the first frame for speed of develpment time. The main function we'll be working with is the newly created setOverlay() function:
setOverlay(idx, txt, alignment) - Takes 3 parameters:
idx - The id assigned to the overlay so you can reference it later
txt - The value of the text to overlay
alignment - The position of the overlay
The alignment is any comma separated combination of the following in the form "x,y":
directions (l/m/r,t/b) - These translate to left/middle/right, top/bottom
examples of directions:
"l,t" - Top left corner
"m,b" - Bottom middle
"r,t" - Top right corner
pixel values (x) - Any integer value for location coordinates
examples of pixel values:
"0,0" - Top left corner of the video
"100,0" - 100px from the left side at the top of the video
"50,50" - 50px down and 50px to the right
percentage values (x%) - Any percentage value for location
examples of percentage values:
"50%,50%" - Positions halfway vertically and horizontally
"10%,80%" - 10% from the left, 80% from the top
ANY combination of these values will work. Here are some more examples of possible alignments:
"l,50%" - Halfway vertically on the left side of video
"50,b" - 50px to from the left and on the bottom
An additional * may be used to indication that the supplied value should start from the right or bottom of the video. Here are some examples:
"l,*50" - Left of the video 50px from the bottom
"*30%,*10" - 30% from the right of the video and 10px from the bottom
"*25,*25" - 25px from the right and 25px from the bottom
So the alignment setting is VERY versitile in terms of the coordinates it can accepts. Here are some methods to using the overlays on your videos:
Method 1: (Adding/updating overlay by hard-coding the .fla file) Add this code to the first frame in the script layer:
setOverlay("overlay1", "Hello World", "l,t");
setOverlay("overlay2", "More text", "m,*20");
This will position "Hello World" in the top left corner of the video and "More text" in the center 20px from the bottom. You can change the "Hello World" text using this:
setOverlay("overlay1", "Some new text", "");
This keeps the same placement location of the overlay and just changes the text that is displayed. You can also change the placement of the overlay like this:
setOverlay("overlay1", "", "r,b");
This moves the overlay to the bottom right and keeps the text it was previously displaying.
Method 2: (Adding/updating overly using javascript) You can using this same code inside javascript on a page to add/update overlays. Here's how:
thisMovie('yourSWF').setOverlay('overlay1', 'Hello World', 'l,t');
The javascript calls can be used the same way as the ActionScript shown above.
Hopefully you aren't too scared of the length of this setup/tutorial. Let me know if you have problems getting this to work. I'll try to setup an example page sometime soon. I'll post back when I get one up.
Jul. 03, 2008comedian
VERY nice! Thanks for sharing.
Jul. 03, 2008Matt
I just got a sample/testing page up. You can see and try it out here:
http://sweetphp.com/jw_player/
Let me know what you think...
Jul. 03, 2008comedian
An AWESOME addition would be the ability to place an image ( read "logo" ) so users could easily place their logo and other "stuff" anywhere that they wanted.
Jul. 05, 2008Jimb
@Matt,
I really have to thank you as well. Yours is a very useful tweak to Jeroen's 3.16 Player and I look forward to using it. I've also made a few changes, most of which are unique to how I use the player but, here is one I've heard others ask how to impliment. It's for those that have a need to make the player's background transparent so that they can display an flv encoded with a transparent alpha channel over the top of a web page. It lets them easily create a web spokesman on the page. I didn't do anything to the FLA as I just use CSS to place the player DIV where I want it. Those that wish to use it should be aware that doing this disables the players FullScreen option when they set the "transparent parameter" to "true".
I needed to be able to toggle transparency and the visibility of the controlbar on and off so I inserted these two new parameters immediately after line 78 of the MediaPlayer.as file.
transparent:"false",
showcontrols:"true",
I inserted these lines of code immediately after line 201 of the ControlbarView.as file.
if(config["showcontrols"] == "false") {
tgt._visible = false;
}
I replaced the public function onMouseMove() located between the private function hideBar() and public function onFeedUpdate() in the ControlbarView.as file. These functions are the last 3 functions in the ControlbarView.as file.
public function onMouseMove() {
Mouse.show();
if((config["displayheight"] == config["height"]-config['searchbar'] ||
Stage["displayState"] == "fullScreen") &&
config["showcontrols"] != "false") {
Animations.fadeIn(config['clip'].controlbar);
clearInterval(hideInt);
if(!config["clip"].controlbar.hitTest(_root._xmouse,_root._ymouse)) {
hideInt = setInterval(this,"hideBar",2000);
}
}
};
I inserted these lines of code immediately after line 53 of the DisplayView.as file.
if(config["transparent"] == "true"){
tgt._alpha = 0;
config["clip"].display.back._alpha = 0;
}
Some here may find it useful and I hope the thread you started attracts a few more nifty contributions.
Regards - Jimb
Jul. 06, 2008Jimb
I took a few minutes to put a short demo together too.
http://www.pmbsg.com/vmo.htm?id=demo.flv&tv=comments.flv
The the volume for the video in the main panel was set very low so you could hear the comments being played in the transparent player.
Jul. 06, 2008basic
@Jimb,
Very nice demo. Now I just have to figure out how to make the transparent video...
I can see having some nice overlays, like all that junk the sports channels put on your TV screen showing stats, a real-time news ticker, etc. Video generated on-the-fly, superimposed over the main video.
May also be a great alternative for advertising (you've opened Pandora's box here).
Jul. 07, 2008Jimb
@basic,
Looks like the post I made yesterday is missing so I'll try again to give you a bit of information on how to create transparent files. It's a common technique used in the movie and television industries commonly called Chroma Keying so you'll need a piece of software that includes the keying effect. I use several products for video that have it (Adobe - Ultra, Adobe - After Effects, Adobe - Premier Pro, Newtek - Speededit).
Basically the way it works is you import your source video or still images into the keying software and select the color(s) you want replaced with transparency, after you've applied the effect you output video as a 32 bit uncompressed avi with an alpha channel or still images as png's with transparency. If you're working with video the next step is to create your final output file. I prefer to create both an Flash FLV and a Quicktime MOV. I use Flash CS3 to create the FLV's and Apple Quicktime Pro for the MOV's. When you output your final file from Flash or Quicktime you need to make sure you select the encode alpha channel option. In my experience the Quicktime H264/AAC files are usually smaller and sharper than the Flash files but I use the Flash files as a Fallback for folks that have an older Flash Plugin installed in their browser.
If you don't have any keying software you can download a 30 day trial copy of Adobe's Ultra 3.
I suspect this will get you headed in the right direction but if you have questions I'll be happy to tell you more.
Regards - Jimb
Jul. 24, 2008Hello
I've found , temporarely maybe, that solution but it stay heavy ('lourd', in french) with the CPU :
html...
head...
<script type="text/javascript" src="swfobject.js"></script>
/head...
(it's the 1.5 vers for the SWFObject )
body...
<div style="z-index:4;position:absolute;left:0px;top:15px" >
<div id="bloc13" style="width:320px;height:154px;filter:alpha(opacity=50)";> (50 or everything else...)
</div>
<script type="text/javascript">
var so = new SWFObject('mediaplayer.swf','mpl','100%','100%','8');
so.addParam('allowscriptaccess','always');
.......................................
so.addParam('wmode','transparent');
......................................
.......................................
....................................
.........................................
........................................
so.write('bloc13');
</script>
</div>
good day.
Jul. 24, 2008Hello
And by the way, you can play, by example, with blendtrans.js (... blendtrans on the web) and let the user change on the fly the opacity of the 'bloc 13' with some function as that one :
<div >
<img src=".....jpg" onclick="opacity('bloc13',85,50,3000)">
</div>
<div >
<img src=".....jpg" onclick="opacity('bloc13',50,85,3000)">
</div>
or create a simple function as that one :
<script type="text/javascript">
function opa(id)
{
document.getElementById('bloc13').style.filter = "";
}
</script>
and call it from a button
<div >
<img src=".....jpg" onclick="opa()">
</div>
to disable the opacity ( i'm talking about the style:filter ).
good day;
Aug. 13, 2008Ben Smith
Hey all, that looks like great work on the overlay!
Is anyone able to provide a download location for the .as and .fla files? I don't have a flash editor so can't follow through the instructions given at the top of this page.
Aug. 14, 2008patrice
Hello,
I don't know anything about flash (and about many others things...:-) ) but i've downloaded two weeks ago the demo version ( but all the features are there...for one month) of the new Adobe program CSS3. I've learn by trys and errors some basics things with it and made a SWPlayer at my hand, for javascript interaction and transparency (without the back clip and, for my use, some others). You will have to register, indeed. For the fla and the as, you will find them there :
http://code.longtailvideo.com/trac/browser/tags
Good day
patrice
Oct. 19, 2008Ay
@Jimb,
Any chance to port the "transparent" to the latest player?? appreciate your guidance.
Feb. 11, 2009Jake
I haven't tried this yet but the sample test page (http://sweetphp.com/jw_player/) looks exactly like what I need!
Will this work on v4.2 or 4.3?
Also, I need to make two (minor?) changes. The actual text will be user/pass and the overlay location will randomly change every 'x' seconds. I have zero experience with this kinda thing. I'm mostly good at c&p and following directions. I'm happy to pay someone to make the necessary changes.
Thanks in advance!
Jake
Oct. 26, 2009Michael
Where can I find mediaplayer.fla file??
Oct. 26, 2009hobbs
@Michael,
See: http://developer.longtailvideo.com/trac/browser/tags
Click on the mediaplayer version that you want the mediaplayer.fla file for.
Oct. 26, 2009Ethan LongTail
Hi Michael,
This is Ethan from LongTail here to help you.
You can get the fla here - http://www.longtailvideo.com/players/jw-flv-player/commercial-license/
Please email me directly at ethan [at] longtailvideo [dot] com to follow up if you have any other questions, thank you.
Best Regards,
-Ethan
Here are some helpful links to learn more about the JW Player™:
Earn money with ads from LongTail's AdSolution. Watch our demos and sign up now!
If you don’t buy a commercial license, you cannot use a JW Player™ on (i) a site that has ads; (ii) a corporate site; or a (iii) CMS. Our licenses are very inexpensive, so what are you waiting for? Buy a license today.