This guide will introduce you to the fundamentals of player scripting using an array of source code examples.
The JW Player for Flash can be controlled with an extensive JavaScript API (Application Programming Interface) which exposes much of the player's core functionality to the JavaScript developer. Many of the player's events are made available as JavaScript events, and player customization and behavior can be configured/controlled as well.
Ultimately, it serves to make both the player and surrounding page aware of each other, allowing for richer and more interactive webpages.
1. You must have the Adobe Flash Player browser plug-in installed. You can check the Flash plug-in version at this page: Adobe Flash Version Test
Sometimes it is best to uninstall an old (faulty) Flash plug-in, before upgrading to the new version. This Adobe page provides uninstall help: Adobe Flash uninstall
Keep your Flash plug-in updated at all times. Adobe releases new versions often, introducing new features and, more importantly, new security upgrades. These security upgrades are extremely important, so, again, always make sure to update.
2. JavaScript must be enabled in your web browser. If not, you should look in to the browser options and check "Enable JavaScript".
3. The player will play in any Flash-enabled web browser, but you must have access to a web page or a server to use the API. The JavaScript API only works online on a web page on a server. This is a security feature of the Flash plug-in, and cannot be changed.
More Adobe information on security: Flash Player 10 security white paper.
By now you have probably downloaded the JW Player for Flash package and unpacked the mediaplayer.zip file into a folder. It should contain the following files:
If you open the readme.html in your favorite web browser, you should see a page with the JW Player for Flash showing the preview.jpg. If you click the player, it should start playing the video.flv.
You can test it by uploading the above files to your online folder. If you can show the readme.html from your web address, and the video plays, you are ready to start experimenting with the JW Player for Flash.
The examples use the SWFObject 2.x JavaScript for the embedding of the player, and to detect if your visitors have the right Flash plug-in (and JavaScript) installed. Set the minimum Flash version in the SWFObject code. In these examples it is set to "9.0.115." Flash ActionScript3 requires at least "9" and various improvements of the plugin have been made since.
For the handling of the player you will use HTML, CSS and JavaScript syntax:
Here is the code for a minimal HTML page:
Try this: JW_API_xmpl_0-0-0-0.html
<html>
<head>
<title>JW API Example 0-0-0-0 - minimal HTML</title>
</head>
<body>
Hello World
</body>
</html>
In the <head> there is the <title> that will be shown in the browser's title bar, and in the <body> of the page, some text content: Hello World
Next, add some CSS to control the layout of the page content:
Try this: JW_API_xmpl_0-0-0.html
<html>
<head>
<title>JW API Example 0-0-0 - minimal HTML/CSS</title>
<style type="text/css">
#wrapper { position:absolute; left:64px; top:128px; background-color:#CCCC00; }
</style>
</head>
<body>
<div id="wrapper">Hello Stylesheet World</div>
</body>
</html>
In the head, a style sheet is defined with the ID "wrapper" and has an absolute position of 64,128. The content in the page body is wrapped in the <div> container with the "wrapper" ID.
The document now has several places that allow the addition of JavaScript code. However, not all the places are equally well suited. A test will show the differences. Note the sequence of the messages that show during the execution of the following page.
Try this: JW_API_xmpl_0-0.html
<html>
<head>
<title>JW API Example 0-0 - minimal JavaScriptt</title>
<style type="text/css">
#wrapper { position:absolute; left:64px; top:128px; background-color:#CCCC00; }
</style>
<script type="text/JavaScript">
alert('A - Hello World from the head');
</script>
</head>
<body onload="alert('C - hello world from onload');">
Hello World<br>
<script type="text/JavaScript">
alert('B - Hello World from the body');
</script>
<a href="JavaScript:alert('Hello World from link');">click for link alert</a>
<div id="wrapper" onclick="alert('Hello World from onclick');">Click this stylesheet for onclick alert</div>
</body>
</html>
To permit the page rendering to proceed uninterrupted, it is necessary to use the "onload" handler. The onload event is triggered last, after the page layout has finished rendering. By enclosing the alert in a function definition, the command will not be executed until the function is explicitly called. This also allows for the transfer of variable values to the function via the call. Note here how the function doSomething is (re)used by the onload handler and the clicks on the page, and how the different messages are transferred to the function for display in the alert box.
Try this: JW_API_xmpl_0.html
<html>
<head>
<title>JW API Example 0 - JavaScript function</title>
<style type="text/css">
#wrapper { position:absolute; left:64px; top:128px; background-color:#CCCC00; }
</style>
<script type="text/JavaScript">
function doSomething(theValue) {
alert('Hello World ' + theValue);
}
</script>
</head>
<body onload="doSomething('from onload');">
Hello World<br>
<a href="JavaScript:doSomething('from link');">click for link alert</a>
<div id="wrapper" onclick="doSomething('from onclick');">Click this stylesheet for onclick alert</div>
</body>
</html>
This is the general page and script structure of almost all the collected examples.
To include the player in your web page we need to make use of the SWFObject JavaScript library by including swfobject.js in the head of the page. Place the loading call to swfobject.js first, and then another script block with the rest of the player-creating script.
The commands to create the player are placed inside the function createPlayer, and the onload handler is set to call this function when page layout has completed. Most of the examples will be based on this code pattern.
Make sure all references to files are set correctly after you copy-paste the code by navigating to them in your browser.
Look for "swfobject.js", "video.flv" and "player.swf" and make sure they are in the correct place.
Try this: JW_API_xmpl_1-1-1-0.html
<html>
<head>
<title>JW API Example 1-1-1-0 - JW FLV Media Player</title>
<style type="text/css">
#wrapper { position:absolute; left:64px; top:128px; width:320px; height:196px; background-color:#CCCC00; }
</style>
<script type="text/JavaScript" src="swfobject.js"></script>
<script type="text/JavaScript">
function createPlayer() {
var flashvars = {
file:"video.flv",
autostart:"true"
}
var params = {
allowfullscreen:"true",
allowscriptaccess:"always"
}
var attributes = {
id:"player1",
name:"player1"
}
swfobject.embedSWF("player.swf", "placeholder1", "320", "196", "9.0.115", false, flashvars, params, attributes);
}
</script>
<head>
<body onload="createPlayer();">
<div id="wrapper">
<div id="placeholder1"></div>
</div>
</body>
</html>
"placeholder1" is the id of the position where the script creates the player. The "wrapper" CSS class is defined with the same width and height as the player in order to reserve space for the player on the page itself during page rendering.
If you care for standards, and want to make the player validate as strict XHTML - you can place the JavaScript functions in a CDATA tag and comments.
Try this: JW_API_xmpl_1-2-0-0.html
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title>JW API Example 1-2-0-0 - XHTML Validating JW FLV Media Player</title>
<style type="text/css">
#wrapper { position:absolute; left:64px; top:128px; width:320px; height:196px; background-color:#CCCC00; }
</style>
<script type="text/JavaScript" src="swfobject.js"></script>
<script type="text/JavaScript">
/* <![CDATA[ */
function createPlayer() {
var flashvars = {
file:"video.flv",
autostart:"true"
}
var params = {
allowfullscreen:"true",
allowscriptaccess:"always"
}
var attributes = {
id:"player1",
name:"player1"
}
swfobject.embedSWF("player.swf", "placeholder1", "320", "196", "9.0.115", false, flashvars, params, attributes);
}
/* ]]> */
</script>
</head>
<body onload="createPlayer();">
<div id="wrapper">
<div id="placeholder1"></div>
</div>
</body>
</html>
While we recommend swfobject.js for embedding the player, since it generates the embed code for you, it is possible to embed the player without it. In this case you will have to write the embed code yourself.
Try this: JW_API_xmpl_1-3-1-0.html
<html>
<head>
<title>JW API Example 1-3-1-0 - Object/Embed code</title>
<style type="text/css">
#wrapper { position:absolute; left:64px; top:128px; width:320px; height:240px; background-color:#FFFFFF; }
</style>
</head>
<body>
<div id="wrapper">
<object id="player1"
classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9.0.115"
width="320" height="240">
<param name=bgcolor value="#FFFFFF">
<param name=movie value="player.swf">
<param name=allowfullscreen value="true">
<param name=allowscriptaccess value="always">
<param name="flashvars" value="file=video.flv&fullscreen=true&controlbar=bottom">
<embed name="player1"
type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer"
width="320" height="240"
bgcolor="#FFFFFF"
src="player.swf"
allowfullscreen="true"
allowscriptaccess="always"
flashvars="file=video.flv&fullscreen=true&controlbar=bottom">
</embed>
</object>
</div>
</body>
</html>
Some systems will not accept anything but the embed code. So as a last resort you can try the following. Note you have to place both the "name" and the "id" in the embed code when using the player this way.
Try this: JW_API_xmpl_1-3-2-0.html
<html>
<head>
<title>JW API Example 1-3-2-0 - only Embed code</title>
</head>
<body>
<embed name="player1" id="player1"
type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer"
width="320" height="240"
bgcolor="#FFFFFF"
src="player.swf"
allowfullscreen="true"
allowscriptaccess="always"
flashvars="file=video.flv&fullscreen=true&controlbar=bottom">
</embed>
</body>
</html>
Please also see the Embedding Flash Tutorial for more embedding info, the Adobe page about Flash Object and Embed tag syntax, and the page about the Flash Object and Embed tag attributes.
In particular, note the "wmode" parameter. It can sometimes be useful to set this to "opaque" or "transparent" in order to mask the player or have menus that cover it. (See: JW_API_xmpl_7-1-1-0.html for an example of the former.)
Assigning values to the FlashVars allows you to customize player functionality and layout. This implies that they can only be set while creating the player. Instantiating and then changing the value of a FlashVar is possible by replacing the existing player.
The file FlashVar must be set to a file name. This can be an absolute URL of a media file or a playlist that points to media files. (See JW_API_xmpl_3-1-1-1.html for an example of the changing of the file FlashVar.)
The remaining FlashVars are optional and are used for things like autostart, hiding the ControlBar or placing the playlist to the right of or below the display. (See JW_API_xmpl_3-4-1-0.html for an example of the changing of the skin FlashVar.)
Please make sure to see the wiki page with the list of all the flashvars and their possible values: http://developer.longtailvideo.com/trac/wiki/FlashVars.
You can also try some experiments with the Wizard. It has the added bonus of providing example embed code for the flashvars you have configured.
The first few examples of the Example Collection show the various basic layouts of the player.
Several of the other examples look very similar when looking at the page. But all the examples are coded to work slightly differently. So make sure to try out, and view and compare the source of the examples. In most cases, it is helpful to experiment and change a few of the variables to see what happens.
When the browser has finished executing the creation script, the player calls the playerReady function if provided. This gives you the opportunity to set a player variable to contain a reference to player for later use.
In its simplest form this can look like the following:
var player = null;
function playerReady(thePlayer) { player = window.document[thePlayer.id]; }
Now all it takes is the following command to toggle the start/pause of the player:
Try this: JW_API_xmpl_5-1-0-0.html
<a href="JavaScript:player.sendEvent('PLAY')">play/pause toggle</a>
A call to the command player.getPlaylist() returns the data of the full playlist.
The following code shows the playlist data on the page. This is done by looping through the playlist items one by one, and assembling a text string with the data formatted as a html list, which is then displayed on the page.
Try this: JW_API_xmpl_4-2-2-0.html
var player = null;
function playerReady(thePlayer) {
player = document.getElementById(thePlayer.id);
printPlaylistData();
};
function printPlaylistData() {
var plst = null;
plst = player.getPlaylist();
if (plst) {
var txt = '';
for (var itm in plst) {
txt += '' + itm + ': ';
txt += '' + plst[itm].title + '';
txt += '' + plst[itm].author + '';
txt += '' + plst[itm].file + '';
txt += '
';
}
var tmp = document.getElementById("plstDat");
if (tmp) {
tmp.innerHTML = txt;
}
} else {
setTimeout("printPlaylistData()", 100);
}
};
By including the following function addListeners() and calling it from playerReady - it is possible to tell the player to send data to functions in the script. The listeners come in three groups and are invoked with their own unique command:
Make sure to see the complete list of commands in the JavaScript API. Here the "STATE" data from the ModelListener group are assigned to be sent to the stateListener function.
var player = null;
function playerReady(thePlayer) {
player = document.getElementById(thePlayer.id);
addListeners();
}
function addListeners() {
if (player) {
player.addModelListener("STATE", "stateListener");
} else {
setTimeout("addListeners()",100);
}
}
This function can then do what ever is required in response to the changing states of the player. The following code shows the current and previous states on the page and redirects to a new page when the playing has finished.
Try this: JW_API_xmpl_4-3-2-0.html
function stateListener(obj) { //IDLE, BUFFERING, PLAYING, PAUSED, COMPLETED
currentState = obj.newstate;
previousState = obj.oldstate;
var tmp = document.getElementById("stat");
if (tmp) {
tmp.innerHTML = "current state: " + currentState +
"<br>previous state: " + previousState;
}
if ((currentState == "COMPLETED")&&(previousState == "PLAYING")) {
document.location.href="http://www.longtailvideo.com/players/jw-flv-player/";
}
}
(Possible states are: IDLE, BUFFERING, PLAYING, PAUSED, COMPLETED )
Some of the simple sendEvent calls that the player understands are quite self explanatory, such as the commands to "PLAY", "MUTE" or "STOP."
The example uses a link. It could also be an image, a button or a call from a function.
Try this: JW_API_xmpl_5-1-0-0.html
<a href="JavaScript:player.sendEvent('MUTE')">mute/sound toggle</a>
Others commands like "LOAD" take an argument. In this case it is a filename.
(but it is also possible to load a playlist as well: JW_API_xmpl_5-2-4-0.html.
Try this: JW_API_xmpl_5-2-1-0.html
<a href="JavaScript:player.sendEvent('LOAD', 'video.flv')">load a video</a>
The commands "VOLUME" and "SEEK" also take arguments. In the case of "SEEK" it requires the position.
Try this: JW_API_xmpl_5-1-0-0.html
<a href="JavaScript:player.sendEvent('SEEK', 10)">seek absolute position (10th. second)</a>
Please note: When seeking/scrubbing in videos:
The player can only stop where the file contains keyframes.
For more info on this, please see the tutorial on Web Video Compression.
Keeping track of listener values makes it simple to make dynamic volume controls or position scrubbers. If a volumeListener is assigned and a global variable currentVolume is set with the volume value, then the global variable can be used directly in the call. It can then be added to or subtracted from as required.
Try this: JW_API_xmpl_6-1-0-0.html
var currentVolume = 80;
var player = null;
function playerReady(thePlayer) {
player = window.document[thePlayer.id];
addListeners();
}
function addListeners() {
if (player) { player.addControllerListener("VOLUME", "volumeListener"); }
else { setTimeout("addListeners()",100); }
}
function volumeListener(obj) { currentVolume = obj.percentage; }
And this is how the code for the dynamic volume control call will look.
<a href="JavaScript:player.sendEvent('VOLUME', currentVolume+10)">set current volume +10%</a>
Combining a call to getPlaylist() with the ability of the player to load a playlist from memory gives you some powerful playlist manipulation and editing possibilities. (load a playlist from memory - JW_API_xmpl_5-2-4-0.html )
Here the playlist is read into the variable currentPlaylist and shown on the page, along with a checkbox for each item. When the link "Load selected Items only" is clicked, the variable currentPlaylist is then read by a loop, the selected items are added to a temporary playlist in memory, and then subsequently read into the player with the "LOAD" command. (If the loop counts down the playlist is reversed.)
Try this: JW_API_xmpl_6-2-0-0.html
function getPlaylistData() {
var plst = null;
plst = player.getPlaylist();
if (plst) {
currentPlaylist = plst;
var txt = '';
for(var i in currentPlaylist) {
txt += '<input type="checkbox" id="cb' + i + '" checked="checked" /> ';
txt += currentPlaylist[i].title;
txt += '<br />';
}
var tmp = document.getElementById("plstDat");
if (tmp) { tmp.innerHTML = txt; }
}
}
function loadCheckedPlaylistData() {
if (currentPlaylist) {
var j = 0;
var lst = new Array();
for(var i in currentPlaylist) {
if(document.getElementById('cb' + i).checked) {
lst[j] = {
author:currentPlaylist[i].author,
description:currentPlaylist[i].description,
duration:currentPlaylist[i].duration,
file:currentPlaylist[i].file,
link:currentPlaylist[i].link,
image:currentPlaylist[i].image,
start:currentPlaylist[i].start,
title:currentPlaylist[i].title,
type:currentPlaylist[i].type
}
j++;
}
}
if(lst.length > 0) { player.sendEvent('LOAD', lst); }
}
}
For more support regarding the JavaScript API, please check the JavaScript section of this site's forum. If you have made any cool demos you want to share, please post those as well!