|
package { |
|
import com.longtailvideo.jwplayer.events.ViewEvent; |
|
import com.longtailvideo.jwplayer.events.MediaEvent; |
|
import com.longtailvideo.jwplayer.events.PlayerStateEvent; |
|
import com.longtailvideo.jwplayer.events.PlaylistEvent; |
|
import com.longtailvideo.jwplayer.player.IPlayer; |
|
import com.longtailvideo.jwplayer.player.PlayerState; |
|
import com.longtailvideo.jwplayer.plugins.IPlugin; |
|
import com.longtailvideo.jwplayer.plugins.PluginConfig; |
|
import com.longtailvideo.jwplayer.utils.Logger; |
|
import com.longtailvideo.jwplayer.utils.Configger; |
|
|
|
import com.jeroenwijering.parsers.*; |
|
|
|
import flash.display.MovieClip; |
|
import flash.display.Bitmap; |
|
import flash.events.MouseEvent; |
|
import flash.events.Event; |
|
import flash.text.TextField; |
|
import flash.text.TextFormat; |
|
import flash.net.*; |
|
import flash.filters.DropShadowFilter; |
|
|
|
public class Captions2 extends MovieClip implements IPlugin { |
|
|
|
|
|
|
|
[Embed(source="controlbar.png")] |
|
private const ControlbarIcon:Class; |
|
[Embed(source="dock.png")] |
|
private const DockIcon:Class; |
|
|
|
/** Configuration list of the plugin. **/ |
|
private var pluginConf:PluginConfig; |
|
|
|
/** Reference to the JW Player API. **/ |
|
private var api:IPlayer; |
|
|
|
/** List with configuration settings. **/ |
|
public var config:Object = { |
|
back:false, |
|
file:undefined, |
|
fontsize:20, |
|
state:true, |
|
margin:0 |
|
}; |
|
|
|
/** XML connect and parse object. **/ |
|
private var loader:URLLoader; |
|
/** Icon for the controlbar. **/ |
|
private var icon:Bitmap; |
|
/** Reference to the textfield. **/ |
|
public var field:TextField; |
|
/** Reference to the background graphic. **/ |
|
private var back:MovieClip; |
|
/** The array the captions are loaded into. **/ |
|
private var captions:Array; |
|
/** Textformat entry for the captions. **/ |
|
private var format:TextFormat; |
|
/** Currently active caption. **/ |
|
private var current:Number; |
|
/** Reference to the dock button. **/ |
|
private var button:MovieClip; |
|
|
|
public function Captions2() { |
|
loader = new URLLoader(); |
|
loader.addEventListener(Event.COMPLETE,loaderHandler); |
|
}; |
|
|
|
/** This function is automatically called by the player after the plugin has loaded. **/ |
|
public function initPlugin(player:IPlayer, conf:PluginConfig):void { |
|
api = player; |
|
pluginConf = conf; |
|
if(conf['file']) |
|
config['file'] = conf['file']; |
|
if(conf['margin']) |
|
config['margin'] = conf['margin']; |
|
if(conf['fontsize']) |
|
config['fontsize'] = conf['fontsize']; |
|
if(conf['state'] == true) |
|
config['state'] = true; |
|
else |
|
config['state'] = false; |
|
|
|
drawClip(); |
|
|
|
api.addEventListener(PlaylistEvent.JWPLAYER_PLAYLIST_ITEM,itemHandler); |
|
api.addEventListener(ViewEvent.JWPLAYER_VIEW_REDRAW, resizeHandler); |
|
api.addEventListener(MediaEvent.JWPLAYER_MEDIA_TIME,timeHandler); |
|
api.addEventListener(PlayerStateEvent.JWPLAYER_PLAYER_STATE,stateHandler); |
|
api.addEventListener(MediaEvent.JWPLAYER_MEDIA_META,metaHandler); |
|
mouseEnabled = false; |
|
mouseChildren = false; |
|
Logger.log('initializing','captions2'); |
|
if(api.config.dock) { |
|
button = api.controls.dock.addButton(new DockIcon(),'is on',clickHandler); |
|
} else { |
|
icon = new ControlbarIcon(); |
|
api.controls.controlbar.addButton(icon,'captions',clickHandler); |
|
} |
|
|
|
hide(config['state']); |
|
} |
|
|
|
/** Clicking the hide button. **/ |
|
private function clickHandler(evt:MouseEvent):void { |
|
hide(!config['state']); |
|
Configger.saveCookie("captions2.state", config.state); |
|
}; |
|
|
|
/** Show/hide the captions **/ |
|
public function hide(stt:Boolean):void { |
|
config['state'] = stt; |
|
visible = config['state']; |
|
if(config['state']) { |
|
if(button) { |
|
button.field.text = 'is on'; |
|
} else { |
|
icon.alpha = 1; |
|
} |
|
} else { |
|
if(button) { |
|
button.field.text = 'is off'; |
|
} else { |
|
icon.alpha = 0.3; |
|
} |
|
} |
|
|
|
}; |
|
|
|
/** This should be a unique, lower-case identifier (e.g. "myplugin") **/ |
|
public function get id():String { |
|
return "captions2"; |
|
} |
|
|
|
/** Called when the player has resized. The dimensions of the plugin are passed in here. **/ |
|
public function resizeHandler(evt:ViewEvent=undefined):void { |
|
// Lay out plugin here, if necessary. |
|
field.y = (api.config['height']-field.height)-config['margin']; |
|
//back.y = (view.config['height']-height)-config['margin']; |
|
|
|
field.x = (api.config['width']-field.width)/2; |
|
} |
|
|
|
public function resize(wid:Number, hei:Number):void |
|
{ |
|
} |
|
|
|
|
|
private function drawClip():void { |
|
back = new MovieClip(); |
|
back.graphics.beginFill(0x000000,0.75); |
|
back.graphics.drawRect(0,0,400,20); |
|
addChild(back); |
|
format = new TextFormat(); |
|
format.color = 0xFFFFFF; |
|
format.size = config['fontsize']; |
|
format.align = "center"; |
|
format.font = "_sans"; |
|
format.leading = 4; |
|
field = new TextField(); |
|
field.width = 400; |
|
field.height = 10; |
|
field.y = 5; |
|
field.autoSize = "center"; |
|
field.selectable = false; |
|
field.multiline = true; |
|
field.wordWrap = true; |
|
field.defaultTextFormat = format; |
|
addChild(field); |
|
if(config['back'] == false) { |
|
back.alpha = 0; |
|
field.filters = new Array(new DropShadowFilter(0,45,0,1,2,2,10,3)); |
|
} |
|
}; |
|
|
|
/** Captions are loaded; now display them. **/ |
|
private function loaderHandler(evt:Event):void { |
|
Logger.log('Loader Handler called', 'captions2'); |
|
var ext:String = config['file'].substr(-3); |
|
if(ext == 'srt' || ext == 'txt') { |
|
captions = SRTParser.parseCaptions(String(evt.target.data)); |
|
} else { |
|
captions = TTParser.parseCaptions(XML(evt.target.data)); |
|
} |
|
if(captions.length == 0) { |
|
Logger.log('Not a valid TimedText or SRT file.','captions'); |
|
} |
|
}; |
|
|
|
/** Check for captions with a new item. **/ |
|
private function itemHandler(evt:PlaylistEvent=null):void { |
|
Logger.log('Item Handler called','captions2'); |
|
current = 0; |
|
captions = new Array(); |
|
pluginConf['file'] = undefined; |
|
field.htmlText = ''; |
|
// drop metadata caption support |
|
var file:String; |
|
if (api.playlist.currentItem['captions.file']) { |
|
file = api.playlist.currentItem['captions.file']; |
|
} else if (api.playlist.currentItem['captions']) { |
|
file = api.playlist.currentItem['captions']; |
|
} else if (config['file']) { |
|
file = config['file']; |
|
} |
|
|
|
Logger.log('Attempting to load file' , 'captions2'); |
|
Logger.log(pluginConf['file'] , 'captions2'); |
|
|
|
if(file) { |
|
pluginConf['file'] = file; |
|
try { |
|
loader.load(new URLRequest(pluginConf['file'])); |
|
} catch (err:Error) { |
|
Logger.log(err.message,'captions2'); |
|
} |
|
} |
|
}; |
|
|
|
|
|
/** Check timing of the player to sync captions. **/ |
|
private function timeHandler(evt:MediaEvent):void { |
|
var pos:Number = evt.position; |
|
if(captions && captions.length > 0 && ( |
|
captions[current]['begin'] > pos || |
|
(captions[current+1] && captions[current+1]['begin'] < pos))) { |
|
setCaption(pos); |
|
} |
|
}; |
|
|
|
|
|
|
|
/** Check timing of the player to sync captions. **/ |
|
private function stateHandler(evt:PlayerStateEvent):void { |
|
if((evt.newstate == 'PLAYING' || |
|
evt.newstate == 'PAUSED') && config['state']) { |
|
visible = true; |
|
} else { |
|
visible = false; |
|
} |
|
}; |
|
|
|
|
|
/** Check for captions in metadata. **/ |
|
private function metaHandler(evt:MediaEvent):void { |
|
var txt:String; |
|
var fnd:Boolean = false; |
|
if (evt.metadata.type == 'caption') { |
|
txt = evt.metadata.captions; |
|
fnd = true; |
|
} else if (evt.metadata.type == 'textdata') { |
|
txt = evt.metadata.text; |
|
fnd = true; |
|
} |
|
if (fnd == true) { |
|
field.htmlText = txt+' '; |
|
resizeHandler(); |
|
} |
|
}; |
|
|
|
|
|
/** Set a caption on screen. **/ |
|
private function setCaption(pos:Number):void { |
|
for(var i:Number=0; i<captions.length; i++) { |
|
if(captions[i]['begin'] < pos && (i == captions.length - 1 || captions[i+1]['begin'] > pos)) { |
|
current = i; |
|
field.htmlText = captions[i]['text']; |
|
resizeHandler(); |
|
Logger.log(captions[i]['text'],'caption'); |
|
return; |
|
} |
|
} |
|
}; |
|
|
|
} |
|
} |