r59717 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r59716‎ | r59717 | r59718 >
Date:00:40, 4 December 2009
Author:dale
Status:deferred
Tags:
Comment:
* moved embedVideo to embedPlayer ( more embedPlayer clean up remains to be done )
* fixed a few more remoteSearchDriver bugs from r59439
* updated associated embed libraries and class paths

= renamed =
inheritEmbedObj -> inheritEmbedPlayer
embedVideo -> embedPlayer
getTimeReq -> getTimeRange
updateThumbTimeNTP -> updateThumbTimeNPT
Modified paths:
  • /branches/js2-work/phase3/js2/mwEmbed/libAddMedia/remoteSearchDriver.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libClipEdit/mvClipEdit.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer (added) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/embedPlayer.js (added) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/embedVideo.js (deleted) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/flowplayerEmbed.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/htmlEmbed.js (replaced) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/javaEmbed.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/kplayerEmbed.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/nativeEmbed.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/omtkEmbed.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libEmbedVideo (deleted) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libSequencer/mvPlayList.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/libTimedText/mvTextInterface.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/mv_embed.js (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/php/languages/mwEmbed.i18n.php (modified) (history)
  • /branches/js2-work/phase3/js2/mwEmbed/skins/ctrlBuilder.js (modified) (history)
  • /branches/js2-work/phase3/js2/remoteMwEmbed.js (modified) (history)

Diff [purge]

Index: branches/js2-work/phase3/js2/remoteMwEmbed.js
@@ -69,7 +69,7 @@
7070 }
7171 }
7272 if ( vidIdList.length > 0 ) {
73 - var jsSetVideo = [ 'embedVideo', '$j.ui', 'ctrlBuilder', '$j.cookie', '$j.ui.slider', 'kskinConfig' ];
 73+ var jsSetVideo = [ 'embedPlayer', '$j.ui', 'ctrlBuilder', '$j.cookie', '$j.ui.slider', 'kskinConfig' ];
7474 // Quick sniff use java if IE and native if firefox
7575 // ( other browsers will run detect and get on-demand )
7676 if (navigator.userAgent.indexOf("MSIE") != -1)
@@ -79,7 +79,7 @@
8080 jsSetVideo.push( 'nativeEmbed' );
8181
8282 mwr_load_mv_embed( jsSetVideo, function() {
83 - mvJsLoader.embedVideoCheck( function() {
 83+ mvJsLoader.embedPlayerCheck( function() {
8484 // Do utility rewrite of OggHandler content:
8585 rewrite_for_OggHandler( vidIdList );
8686 } );
Index: branches/js2-work/phase3/js2/mwEmbed/php/languages/mwEmbed.i18n.php
@@ -342,7 +342,7 @@
343343 'mwe-credit-title' => 'Title: $1',
344344
345345 /*
346 - * js file: /libEmbedVideo/embedVideo.js
 346+ * js file: /libEmbedPlayer/embedPlayer.js
347347 */
348348 'mwe-loading_plugin' => 'loading plugin ...',
349349 'mwe-select_playback' => 'Set playback preference',
Index: branches/js2-work/phase3/js2/mwEmbed/skins/ctrlBuilder.js
@@ -3,12 +3,12 @@
44 _global['dismissNativeWarn'] = false;
55
66 /**
7 -* Msg text is inherited from embedVideo
 7+* Msg text is inherited from embedPlayer
88 */
99
1010 /**
1111 * ctrlBuilder object
12 -* @param the embedVideo element we are targeting
 12+* @param the embedPlayer element we are targeting
1313 */
1414 var ctrlBuilder = function( embedObj, options ) {
1515 return this.init( embedObj, options );
@@ -198,7 +198,7 @@
199199 $j( id + ' .play-btn-large' ).fadeOut( 'fast' );
200200 // If playlist always start at 0
201201 embedObj.start_time_sec = ( embedObj.instanceOf == 'mvPlayList' ) ? 0:
202 - npt2seconds( embedObj.getTimeReq().split( '/' )[0] );
 202+ npt2seconds( embedObj.getTimeRange().split( '/' )[0] );
203203 },
204204 slide: function( event, ui ) {
205205 var perc = ui.value / 1000;
@@ -494,7 +494,7 @@
495495 'time_display': {
496496 'w':90,
497497 'o':function( ctrlObj ) {
498 - return '<div class="ui-widget time-disp">' + ctrlObj.embedObj.getTimeReq() + '</div>';
 498+ return '<div class="ui-widget time-disp">' + ctrlObj.embedObj.getTimeRange() + '</div>';
499499 }
500500 },
501501 /*
Index: branches/js2-work/phase3/js2/mwEmbed/mv_embed.js
@@ -132,15 +132,15 @@
133133
134134 "mvClipEdit" : "libClipEdit/mvClipEdit.js",
135135
136 - "embedVideo" : "libEmbedVideo/embedVideo.js",
137 - "flowplayerEmbed" : "libEmbedVideo/flowplayerEmbed.js",
138 - "kplayerEmbed" : "libEmbedVideo/kplayerEmbed.js",
139 - "genericEmbed" : "libEmbedVideo/genericEmbed.js",
140 - "htmlEmbed" : "libEmbedVideo/htmlEmbed.js",
141 - "javaEmbed" : "libEmbedVideo/javaEmbed.js",
142 - "nativeEmbed" : "libEmbedVideo/nativeEmbed.js",
143 - "quicktimeEmbed" : "libEmbedVideo/quicktimeEmbed.js",
144 - "vlcEmbed" : "libEmbedVideo/vlcEmbed.js",
 136+ "embedPlayer" : "libEmbedPlayer/embedPlayer.js",
 137+ "flowplayerEmbed" : "libEmbedPlayer/flowplayerEmbed.js",
 138+ "kplayerEmbed" : "libEmbedPlayer/kplayerEmbed.js",
 139+ "genericEmbed" : "libEmbedPlayer/genericEmbed.js",
 140+ "htmlEmbed" : "libEmbedPlayer/htmlEmbed.js",
 141+ "javaEmbed" : "libEmbedPlayer/javaEmbed.js",
 142+ "nativeEmbed" : "libEmbedPlayer/nativeEmbed.js",
 143+ "quicktimeEmbed" : "libEmbedPlayer/quicktimeEmbed.js",
 144+ "vlcEmbed" : "libEmbedPlayer/vlcEmbed.js",
145145
146146 "mvPlayList" : "libSequencer/mvPlayList.js",
147147 "mvSequencer" : "libSequencer/mvSequencer.js",
@@ -1167,9 +1167,9 @@
11681168 }
11691169 } );
11701170 },
1171 - embedVideoCheck:function( callback ) {
 1171+ embedPlayerCheck:function( callback ) {
11721172 var _this = this;
1173 - js_log( 'embedVideoCheck:' );
 1173+ js_log( 'embedPlayerCheck:' );
11741174 // Make sure we have jQuery
11751175 _this.jQueryCheck( function() {
11761176 // set class videonojs to loading
@@ -1178,7 +1178,7 @@
11791179 var depReq = [
11801180 [
11811181 '$j.ui',
1182 - 'embedVideo',
 1182+ 'embedPlayer',
11831183 'ctrlBuilder',
11841184 '$j.cookie'
11851185 ],
@@ -1283,11 +1283,12 @@
12841284 }
12851285 }
12861286 // Load libs and process videos
1287 - mvJsLoader.embedVideoCheck( function() {
1288 - // Run any queued global events:
1289 - mv_video_embed( function() {
 1287+ mvJsLoader.embedPlayerCheck( function() {
 1288+ // Convert all supported elements into embed players:
 1289+ $j.embedPlayers( function(){
 1290+ // Run any queued global events:
12901291 mvJsLoader.runQueuedFunctions();
1291 - } );
 1292+ });
12921293 } );
12931294 } else {
12941295 mvJsLoader.runQueuedFunctions();
@@ -1314,7 +1315,7 @@
13151316 function rewrite_by_id( vid_id, ready_callback ) {
13161317 js_log( 'f:rewrite_by_id: ' + vid_id );
13171318 // Force a re-check of the DOM for playlist or video elements:
1318 - mvJsLoader.embedVideoCheck( function() {
 1319+ mvJsLoader.eembedPlayerheck( function() {
13191320 mv_video_embed( ready_callback, vid_id );
13201321 } );
13211322 }
@@ -1456,7 +1457,7 @@
14571458 loadExternalCss( mv_embed_path + 'skins/' + mw.conf['skin_name'] + '/mv_sequence.css' );
14581459 // Make sure we have the required mv_embed libs (they are not loaded when no video
14591460 // element is on the page)
1460 - mvJsLoader.embedVideoCheck( function() {
 1461+ mvJsLoader.eembedPlayerheck( function() {
14611462 // Load the playlist object and then the jQuery UI stuff:
14621463 mvJsLoader.doLoadDepMode( [
14631464 [
Index: branches/js2-work/phase3/js2/mwEmbed/libTimedText/mvTextInterface.js
@@ -54,7 +54,7 @@
5555 _this.getParseTimedText_rowReady();
5656 }
5757 } else {
58 - if ( this.pe.media_element.checkForTextSource() ) {
 58+ if ( this.pe.media_element.textSourceExists() ) {
5959 _this.getParseTimedText_rowReady();
6060 } else {
6161 js_log( 'no roe data or timed text sources' );
Index: branches/js2-work/phase3/js2/mwEmbed/libAddMedia/remoteSearchDriver.js
@@ -1005,7 +1005,7 @@
10061006 break;
10071007 }
10081008 }
1009 - }
 1009+ },
10101010
10111011 /**
10121012 * checkForCopyURLPermission:
@@ -1695,15 +1695,15 @@
16961696 // normally this meta should be provided in the search result
16971697 // (but archive.org has another query for more media meta)
16981698 resource.pSobj.addResourceInfoCallback( resource, function() {
1699 - // Make sure we have the embedVideo libs:
 1699+ // Make sure we have the embedPlayer libs:
17001700 var runFlag = false;
1701 - mvJsLoader.embedVideoCheck( function() {
 1701+ mvJsLoader.embedPlayerCheck( function() {
17021702 // Strange concurrency issue with callbacks
17031703 // @@todo try and figure out why this callback is fired twice
17041704 if ( !runFlag ) {
17051705 runFlag = true;
17061706 } else {
1707 - js_log( 'Error: embedVideoCheck run twice' );
 1707+ js_log( 'Error: embedPlayerCheck run twice' );
17081708 return false;
17091709 }
17101710 var embedHtml = resource.pSobj.getEmbedHTML( resource,
@@ -2341,9 +2341,7 @@
23422342 resource.mime.indexOf( 'video' ) != -1 ||
23432343 resource.mime.indexOf( '/ogg' ) != -1 )
23442344 {
2345 - mvJsLoader.embedVideoCheck( function() {
2346 - mv_video_embed();
2347 - } );
 2345+ mvJsLoader.embedPlayerCheck();
23482346 }
23492347 }
23502348
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/omtkEmbed.js
@@ -0,0 +1,65 @@
 2+var omtkEmbed = {
 3+ instanceOf:'omtkEmbed',
 4+ supports: {
 5+ 'pause':true,
 6+ 'time_display':true
 7+ },
 8+ getEmbedHTML : function () {
 9+ var embed_code = this.getEmbedObj();
 10+ // Need omtk to fire an onReady event.
 11+ setTimeout( '$j(\'#' + this.id + '\').get(0).postEmbedJS()', 2000 );
 12+ return this.wrapEmebedContainer( embed_code );
 13+ },
 14+ getEmbedObj:function() {
 15+ var player_path = mv_embed_path + 'libEmbedPlayer/binPlayers/omtk-fx/omtkp.swf';
 16+ // player_path = 'omtkp.swf';
 17+ js_log( "player path: " + player_path );
 18+ return '<object id="' + this.pid + '" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="1" height="1">' +
 19+ '<param name="movie" value="' + player_path + '" />' + "\n" +
 20+ '<!--[if !IE]>-->' + "\n" +
 21+ '<object id="' + this.pid + '_ie" type="application/x-shockwave-flash" data="' + player_path + '" width="1" height="1">' + "\n" +
 22+ '<!--<![endif]-->' + "\n" +
 23+ '<p>Error with Display of Flash Plugin</p>' + "\n" +
 24+ '<!--[if !IE]>-->' + "\n" +
 25+ '</object>' + "\n" +
 26+ '<!--<![endif]-->' + "\n" +
 27+ '</object>';
 28+ },
 29+ postEmbedJS:function() {
 30+ this.getOMTK();
 31+ // play the url:
 32+ js_log( "play: pid:" + this.pid + ' src:' + this.src );
 33+
 34+ this.omtk.play( this.src );
 35+
 36+ this.monitor();
 37+ // $j('#omtk_player').get(0).play(this.src);
 38+ // $j('#'+this.pid).get(0).play( this.src );
 39+ },
 40+ pause:function() {
 41+ this.stop();
 42+ },
 43+ monitor:function() {
 44+ if ( this.omtk.getPosition )
 45+ this.currentTime = this.omtk.getPosition() / 1000;
 46+
 47+ this.parent_monitor();
 48+ },
 49+ getOMTK : function () {
 50+ this.omtk = $j( '#' + this.pid ).get( 0 );
 51+ if ( !this.omtk.play )
 52+ this.omtk = $j( '#' + this.pid + '_ie' ).get( 0 );
 53+
 54+ if ( this.omtk.play ) {
 55+ // js_log('omtk obj is missing .play (probably not omtk obj)');
 56+ }
 57+ },
 58+}
 59+
 60+function OMTK_P_complete() {
 61+ js_log( 'OMTK_P_complete' );
 62+}
 63+
 64+function OMTK_P_metadataUpdate() {
 65+ js_log( 'OMTK_P_metadataUpdate' );
 66+}
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/omtkEmbed.js
___________________________________________________________________
Added: svn:eol-style
167 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/embedPlayer.js
@@ -0,0 +1,3038 @@
 2+/*
 3+* embedPlayer is the base class for html5 video tag javascript abstraction library
 4+* embedPlayer include a few subclasses:
 5+*
 6+* mediaPlayer Media player embed system ie: java, vlc or native.
 7+* mediaElement Represents source media elements
 8+* ctrlBuilder Handles skinning of the player controls
 9+*
 10+*/
 11+
 12+loadGM( {
 13+ "mwe-loading_plugin" : "loading plugin ...",
 14+ "mwe-select_playback" : "Set playback preference",
 15+ "mwe-link_back" : "Link back",
 16+ "mwe-error_swap_vid" : "Error: mv_embed was unable to swap the video tag for the mv_embed interface",
 17+ "mwe-add_to_end_of_sequence" : "Add to end of sequence",
 18+ "mwe-missing_video_stream" : "The video file for this stream is missing",
 19+ "mwe-play_clip" : "Play clip",
 20+ "mwe-pause_clip" : "Pause clip",
 21+ "mwe-volume_control" : "Volume control",
 22+ "mwe-player_options" : "Player options",
 23+ "mwe-closed_captions" : "Closed captions",
 24+ "mwe-player_fullscreen" : "Fullscreen",
 25+ "mwe-next_clip_msg" : "Play next clip",
 26+ "mwe-prev_clip_msg" : "Play previous clip",
 27+ "mwe-current_clip_msg" : "Continue playing this clip",
 28+ "mwe-seek_to" : "Seek $1",
 29+ "mwe-paused" : "paused",
 30+ "mwe-download_segment" : "Download selection:",
 31+ "mwe-download_full" : "Download full video file:",
 32+ "mwe-download_right_click" : "To download, right click and select <i>Save link as...<\/i>",
 33+ "mwe-download_clip" : "Download video",
 34+ "mwe-download_text" : "Download text (<a style=\"color:white\" title=\"cmml\" href=\"http:\/\/wiki.xiph.org\/index.php\/CMML\">CMML<\/a> xml):",
 35+ "mwe-download" : "Download",
 36+ "mwe-share" : "Share",
 37+ "mwe-credits" : "Credits",
 38+ "mwe-clip_linkback" : "Clip source page",
 39+ "mwe-chose_player" : "Choose video player",
 40+ "mwe-share_this_video" : "Share this video",
 41+ "mwe-video_credits" : "Video credits",
 42+ "mwe-menu_btn" : "Menu",
 43+ "mwe-close_btn" : "Close",
 44+ "mwe-ogg-player-vlc-player" : "VLC player",
 45+ "mwe-ogg-player-videoElement" : "Native Ogg video",
 46+ "mwe-ogg-player-oggPlugin" : "Generic Ogg plugin",
 47+ "mwe-ogg-player-quicktime-mozilla" : "QuickTime plugin",
 48+ "mwe-ogg-player-quicktime-activex" : "QuickTime ActiveX",
 49+ "mwe-ogg-player-cortado" : "Java Cortado",
 50+ "mwe-ogg-player-flowplayer" : "Flowplayer",
 51+ "mwe-ogg-player-kplayer" : "Kaltura player",
 52+ "mwe-ogg-player-selected" : "(selected)",
 53+ "mwe-ogg-player-omtkplayer" : "OMTK Flash Vorbis",
 54+ "mwe-generic_missing_plugin" : "You browser does not appear to support the following playback type: <b>$1<\/b><br \/>Visit the <a href=\"http:\/\/commons.wikimedia.org\/wiki\/Commons:Media_help\">Playback Methods<\/a> page to download a player.<br \/>",
 55+ "mwe-for_best_experience" : "For a better video playback experience we recommend:<br \/><b><a href=\"http:\/\/www.mozilla.com\/en-US\/firefox\/upgrade.html?from=mwEmbed\">Firefox 3.5<\/a>.<\/b>",
 56+ "mwe-do_not_warn_again" : "Dismiss for now.",
 57+ "mwe-playerselect" : "Players",
 58+ "mwe-read_before_embed" : "<a href=\"http:\/\/mediawiki.org\/wiki\/Security_Notes_on_Remote_Embedding\" target=\"_new\">Read this<\/a> before embedding.",
 59+ "mwe-embed_site_or_blog" : "Embed on a page",
 60+ "mwe-related_videos" : "Related videos",
 61+ "mwe-seeking" : "seeking",
 62+ "mwe-copy-code" : "Copy code",
 63+ "mwe-video-h264" : "H.264 video",
 64+ "mwe-video-flv" : "Flash video",
 65+ "mwe-video-ogg" : "Ogg video",
 66+ "mwe-video-audio" : "Ogg audio"
 67+} );
 68+
 69+/*
 70+* The default video attributes supported by embedPlayer
 71+*/
 72+var default_video_attributes = {
 73+ /*
 74+ * Base html element attributes:
 75+ */
 76+
 77+ // id: Auto-populated if unset
 78+ "id" : null,
 79+
 80+ // Class: used to set the player "skin"
 81+ "class" : null,
 82+
 83+ // Style: used to set player width and height
 84+ "style" : null,
 85+
 86+ // Width: alternate to "style" to set player width
 87+ "width" : null,
 88+
 89+ // Height: alternative to "style" to set player height
 90+ "height" : null,
 91+
 92+ /*
 93+ * Base html5 video element attributes / states
 94+ * also see: http://www.whatwg.org/specs/web-apps/current-work/multipage/video.html
 95+ */
 96+
 97+ // Media src URI, can be relative or absolute URI
 98+ "src" : null,
 99+
 100+ // Poster attribute for displaying a place holder image before loading or playing the video
 101+ "poster": null,
 102+
 103+ // Autoplay if the media should start playing
 104+ "autoplay" : false,
 105+
 106+ // If the player controls should be displayed
 107+ "controls" : true,
 108+
 109+ // Video starts "paused"
 110+ "paused" : true,
 111+
 112+ // ReadyState an attribute informs clients of video loading state:
 113+ // see: http://www.whatwg.org/specs/web-apps/current-work/#readystate
 114+ "readyState" : 0,
 115+
 116+ // Loading state of the video element
 117+ "networkState" : 0,
 118+
 119+ // Current playback position
 120+ "currentTime" :0,
 121+
 122+ // Media duration: Value is populated via
 123+ // custom durationHint attribute or via the media file once its played
 124+ "duration" :null,
 125+
 126+ // Mute state
 127+ "muted" : false,
 128+
 129+ /*
 130+ * Custom attributes for embedPlayer player:
 131+ * (not part of the html5 video spec)
 132+ */
 133+
 134+ // Start time of the clip
 135+ "start" : 0,
 136+
 137+ // End time of the clip
 138+ "end" : null,
 139+
 140+ // A wikiTitleKey for looking up subtitles, credits and related videos
 141+ "wikiTitleKey" : null,
 142+
 143+ // ROE url ( for xml based metadata )
 144+ // also see: http://wiki.xiph.org/ROE
 145+ "roe" : null,
 146+
 147+ // If roe includes metadata tracks we can expose a link to metadata
 148+ "show_meta_link" : true,
 149+
 150+ // If serving an ogg_chop segment use this to offset the presentation time
 151+ // ( for some plugins that use ogg page time rather than presentaiton time )
 152+ "startOffset" : null,
 153+
 154+ //If we should display the play button
 155+ "play_button" : true,
 156+
 157+ // Thumbnail (same as poster)
 158+ "thumbnail" : null,
 159+
 160+ // Source page for media asset ( used for linkbacks in remote embedding )
 161+ "linkback" : null,
 162+
 163+ // If the download link should be shown
 164+ "download_link" : true,
 165+
 166+ // Content type of the media
 167+ "type" : null
 168+};
 169+
 170+/**
 171+ * The base source attribute checks
 172+ */
 173+var default_source_attributes = new Array(
 174+ // source id
 175+ 'id',
 176+
 177+ // media url
 178+ 'src',
 179+
 180+ // api url ( used for timed text sources )
 181+ 'apisrc',
 182+
 183+ // titleKey ( used for api lookups )
 184+ 'titleKey',
 185+
 186+ // Title string for the source asset
 187+ 'title',
 188+
 189+ // boolean if we support temporal url requests on the source media
 190+ 'URLTimeEncoding',
 191+
 192+ // Media has a startOffset ( used for plugins that
 193+ // display ogg page time rather than presentation time
 194+ 'startOffset',
 195+
 196+ // A hint to the duration of the media file so that duration
 197+ // can be displayed in the player without loading the media file
 198+ 'durationHint',
 199+
 200+ // Media start time
 201+ 'start',
 202+
 203+ // Media end time
 204+ 'end',
 205+
 206+ // If the source is the default source
 207+ 'default',
 208+
 209+ // Language key used for subtitle tracks
 210+ 'lang'
 211+);
 212+
 213+// set the dismissNativeWarn flag:
 214+_global['dismissNativeWarn'] = false;
 215+
 216+/**
 217+* Adds jQuery binding for embedPlayer
 218+*/
 219+( function( $ ) {
 220+
 221+ /**
 222+ * The base embedPlayers function converts all
 223+ * video, audio, playlist tags into javascript player interfaces
 224+ *
 225+ * @param {Object} attributes Attributes applied to all players
 226+ * @param [ Optional ] {Function} callback Function to be called once player interfaces are ready
 227+ */
 228+ $.embedPlayers = function( attributes, callback ){
 229+ $( 'video,audio,playlist' ).embedPlayer( attributes, callback );
 230+ }
 231+
 232+ /**
 233+ * Selector based embedPlayer jQuery binding
 234+ *
 235+ * Rewrites all tags via a given selector
 236+ *
 237+ * @param [ Optional ] {Object} attributes The embedPlayer options for the given video interface.
 238+ * Attributes Object can inclue any key value pair that would otherwise be
 239+ * an attribute in the html element.
 240+ *
 241+ * also see: default_video_attributes
 242+ *
 243+ * @param [ Optional ] {Function} callback Function to be called once video interfaces are ready
 244+ *
 245+ */
 246+ $.fn.embedPlayer = function( attributes, callback ){
 247+
 248+ //Handle optional include of attributes argument:
 249+ if( typeof attributes == 'function' && typeof( callback ) != 'function' )
 250+ callback = attributes;
 251+
 252+ // Create the Global Embed Player Manager ( if not already created )
 253+ if( ! mw.playerManager )
 254+ mw.playerManager = new EmbedPlayerManager();
 255+
 256+ //Add the current callback
 257+ if( typeof callback == 'function' )
 258+ mw.playerManager.addCallback( callback );
 259+
 260+ // Pointer to Selector:
 261+ var j_selector = this.selector;
 262+
 263+ // Process selected elements:
 264+ // ie8 does not play well with the jQuery video,audio,playlist selector use native:
 265+ if ( $.browser.msie && $j.browser.version >= 8 ) {
 266+ var ie_compatible_selector = '';
 267+ var jtags = j_selector.split( ',' );
 268+ var coma = '';
 269+ for ( var i = 0; i < jtags.length; i++ ) {
 270+ if ( jtags[i] === 'video' ||
 271+ jtags[i] === 'audio' ||
 272+ jtags[i] === 'playlist' ) {
 273+ // Use native ElementsByTagName selector
 274+ $( document.getElementsByTagName( jtags[i] ) ).each( function() {
 275+ mw.playerManager.addElement( this, attributes);
 276+ } );
 277+ }else{
 278+ ie_compatible_selector += coma + jtags[i]
 279+ coma = ',';
 280+ }
 281+ }
 282+ //Set the selector to IE compatible set and continue processing
 283+ j_selector = ie_compatible_selector;
 284+ }
 285+ // Run the selector
 286+ $j( j_selector ).each( function() {
 287+ mw.playerManager.addElement( this, attributes);
 288+ } );
 289+
 290+ // Once we are done adding new players start to check if players are ready:
 291+ mw.playerManager.waitPlayersReadyCallback();
 292+
 293+ }
 294+
 295+} )( jQuery );
 296+
 297+/**
 298+* EmbedPlayerManager
 299+*
 300+* Mannages calls to embed video interfaces
 301+*/
 302+var EmbedPlayerManager = function( ) {
 303+ // Create a Player Manage
 304+ return this.init( );
 305+};
 306+EmbedPlayerManager.prototype = {
 307+
 308+ // Functions to run after the video interface is ready
 309+ callbackFunctions : null,
 310+
 311+ // A list of players being managed by the EmbedPlayerManager
 312+ playerList : null,
 313+
 314+ /**
 315+ * Constructor initialises callbackFunctions and playerList
 316+ */
 317+ init: function( ) {
 318+ this.callbackFunctions = new Array();
 319+ this.playerList = new Array();
 320+ },
 321+
 322+ /**
 323+ * Adds a callback to the callbackFunctions list
 324+ */
 325+ addCallback: function( callback ) {
 326+ this.callbackFunctions.push( callback );
 327+ },
 328+
 329+ /**
 330+ * Adds an Element for the embedPlayer to rewrite
 331+ *
 332+ * uses embedPlayer interface on audio / video elements
 333+ * uses mvPlayList interface on playlist elements
 334+ *
 335+ * @param {Element} element DOM element to be swaped
 336+ * @param [ Optional ] {Object} attributes Extra attributes to apply to the player interface
 337+ */
 338+ addElement: function( element, attributes ) {
 339+ if ( $j( element ).attr( "id" ) == '' ) {
 340+ $j( element ).attr( "id", 'v' + this.playerList.length );
 341+ }
 342+ js_log( "mvEmbed::rewrite:: " + $j( element ).attr( "id" ) + ' tag: ' + element.tagName.toLowerCase() );
 343+
 344+ // Add the element id to playerList
 345+ this.playerList.push( $j( element ).attr( "id" ) );
 346+
 347+ switch( element.tagName.toLowerCase() ) {
 348+ case 'video':
 349+ case 'audio':
 350+ var playerInterface = new embedPlayer( element , attributes);
 351+ this.swapEmbedPlayerElement( element, playerInterface );
 352+ break;
 353+ case 'playlist':
 354+ // Make sure we have the necessary playlist libs loaded:
 355+ mvJsLoader.doLoad( [
 356+ 'mvPlayList',
 357+ '$j.ui', // Include dialog for pop-ing up things
 358+ '$j.ui.dialog'
 359+ ], function() {
 360+ // Create playlist player interface
 361+ var playlistPlayer = new mvPlayList( element, attributes );
 362+ // Swap in playlist player interface
 363+ mvEmbed.swapEmbedPlayerElement( element, playlistPlayer );
 364+ // Add playlistPlayer title height
 365+ var added_height = playlistPlayer.pl_layout.title_bar_height + playlistPlayer.pl_layout.control_height;
 366+
 367+ // Wrap a blocking display container with height + controls + title height:
 368+ $j( '#' + playlistPlayer.id ).wrap(
 369+ '<div style="display:block;' +
 370+ 'height:' + ( playlistPlayer.height + added_height ) + 'px;">' +
 371+ '</div>'
 372+ );
 373+ } );
 374+ break;
 375+ }
 376+ },
 377+
 378+ /**
 379+ * swapEmbedPlayerElement
 380+ *
 381+ * Takes a video element as input and swaps it out with
 382+ * an embed player interface
 383+ *
 384+ * @param {Element} targetElement Element to be swapped
 385+ * @param {Object} playerInterface Interface to swap into the target element
 386+ */
 387+ swapEmbedPlayerElement: function( targetElement, playerInterface ) {
 388+
 389+ // Create a new element to swap the player interface into
 390+ var swapPlayerElement = document.createElement( 'div' );
 391+
 392+ // Make sure the new swapPlayerElement has height / width set:
 393+ $j( swapPlayerElement ).css( {
 394+ 'width' : playerInterface.width,
 395+ 'height' : playerInterface.height
 396+ } )
 397+ .html( mv_get_loading_img() );
 398+
 399+ // Apply the Player interface to the DOM element
 400+ for ( var method in playerInterface ) { // for in loop oky in Element context
 401+ if ( method != 'readyState' ) { // readyState crashes IE ( don't include )
 402+ if ( method == 'style' ) {
 403+ swapPlayerElement.setAttribute( 'style', playerInterface[method] );
 404+ } else if ( method == 'class' ) {
 405+ if ( $j.browser.msie )
 406+ swapPlayerElement.setAttribute( "className", playerInterface['class'] );
 407+ else
 408+ swapPlayerElement.setAttribute( "class", playerInterface['class'] );
 409+ } else {
 410+ // Normal interface method:
 411+ swapPlayerElement[method] = playerInterface[method];
 412+ }
 413+ }
 414+ // String -> Boolean:
 415+ if ( swapPlayerElement[method] == "false" )
 416+ swapPlayerElement[method] = false;
 417+
 418+ if ( swapPlayerElement[method] == "true" )
 419+ swapPlayerElement[method] = true;
 420+ }
 421+
 422+ // Now Swap out the video element for the embed_video obj:
 423+ $j( targetElement )
 424+ // Put the swapPlayerElement after the targetElement
 425+ .after( swapPlayerElement )
 426+ // Remove the targetElement
 427+ .remove();
 428+
 429+ // Issue the checkPlayerSources call to the player interface:
 430+ swapPlayerElement.checkPlayerSources();
 431+
 432+ return true;
 433+ },
 434+
 435+ /**
 436+ * Runs the callback functions once players are ready
 437+ *
 438+ * Will run all the functions in the this.callbackFunctions array
 439+ * Once all the player in this.playerList are ready
 440+ */
 441+ waitPlayersReadyCallback : function() {
 442+ var _this = this;
 443+ // js_log('checkClipsReady');
 444+ var is_ready = true;
 445+ for ( var i = 0; i < this.playerList.length; i++ ) {
 446+ if ( $j( '#' + this.playerList[i] ).length != 0 ) {
 447+ var player = $j( '#' + this.playerList[i] ).get( 0 );
 448+
 449+ // Check if the current video is ready
 450+ is_ready = ( player.ready_to_play ) ? is_ready : false;
 451+
 452+ if ( !is_ready && player.load_error ) {
 453+ is_ready = true;
 454+ // Update the player with its load error:
 455+ $j( player ).html( player.load_error );
 456+ }
 457+ }
 458+ }
 459+ if ( is_ready ) {
 460+ // Run queued functions
 461+ while ( this.callbackFunctions.length ) {
 462+ this.callbackFunctions.shift()();
 463+ }
 464+ } else {
 465+ // Continue checking the playerList
 466+ setTimeout( function(){
 467+ _this.waitPlayersReadyCallback();
 468+ }, 25 );
 469+ }
 470+ }
 471+}
 472+
 473+/**
 474+ * mediaSource class represents a source for a media element.
 475+ * @param {Element} element: MIME type of the source.
 476+ * @constructor
 477+ */
 478+function mediaSource( element ) {
 479+ this.init( element );
 480+}
 481+
 482+mediaSource.prototype = {
 483+ // MIME type of the source.
 484+ mime_type:null,
 485+
 486+ // URI of the source.
 487+ uri:null,
 488+
 489+ // Title of the source.
 490+ title:null,
 491+
 492+ // True if the source has been marked as the default.
 493+ marked_default:false,
 494+
 495+ // True if the source supports url specification of offset and duration
 496+ URLTimeEncoding:false,
 497+
 498+ // Start offset of the requested segment
 499+ start_offset:null,
 500+
 501+ // Duration of the requested segment (0 if not known)
 502+ duration:0,
 503+
 504+ // Is the source playable
 505+ is_playable: null,
 506+
 507+ // source id
 508+ id: null,
 509+
 510+ // Start time in npt format
 511+ start_npt: null,
 512+
 513+ // End time in npt format
 514+ end_npt: null,
 515+
 516+ /**
 517+ * MediaSource constructor:
 518+ */
 519+ init : function( element ) {
 520+ // js_log('adding mediaSource: ' + element);
 521+ this.src = $j( element ).attr( 'src' );
 522+ this.marked_default = false;
 523+ if ( element.tagName.toLowerCase() == 'video' )
 524+ this.marked_default = true;
 525+
 526+ // Set default URLTimeEncoding if we have a time url:
 527+ // not ideal way to discover if content is on an oggz_chop server.
 528+ // should check some other way.
 529+ var pUrl = mw.parseUri ( this.src );
 530+ if ( typeof pUrl[ 'queryKey' ][ 't' ] != 'undefined' ) {
 531+ this[ 'URLTimeEncoding' ] = true;
 532+ }
 533+ for ( var i = 0; i < default_source_attributes.length; i++ ) { // array loop:
 534+ var attr = default_source_attributes[ i ];
 535+ if ( $j( element ).attr( attr ) ) {
 536+ this[ attr ] = $j( element ).attr( attr );
 537+ }
 538+ }
 539+
 540+
 541+ if ( $j( element ).attr( 'type' ) )
 542+ this.mime_type = $j( element ).attr( 'type' );
 543+ else if ( $j( element ).attr( 'content-type' ) )
 544+ this.mime_type = $j( element ).attr( 'content-type' );
 545+ else
 546+ this.mime_type = this.detectType( this.src );
 547+
 548+ this.parseURLDuration();
 549+ },
 550+
 551+ /**
 552+ * Update Source title via Element
 553+ * @param Element:
 554+ */
 555+ updateSource:function( element ) {
 556+ // for now just update the title:
 557+ if ( $j( element ).attr( "title" ) )
 558+ this.title = $j( element ).attr( "title" );
 559+ },
 560+
 561+ /**
 562+ * Updates the src time and start & end
 563+ * @param {String} start_time: in NPT format
 564+ * @param {String} end_time: in NPT format
 565+ */
 566+ updateSrcTime:function ( start_npt, end_npt ) {
 567+ // js_log("f:updateSrcTime: "+ start_npt+'/'+ end_npt + ' from org: ' + this.start_npt+ '/'+this.end_npt);
 568+ // js_log("pre uri:" + this.src);
 569+ // if we have time we can use:
 570+ if ( this.URLTimeEncoding ) {
 571+ // make sure its a valid start time / end time (else set default)
 572+ if ( !npt2seconds( start_npt ) )
 573+ start_npt = this.start_npt;
 574+
 575+ if ( !npt2seconds( end_npt ) )
 576+ end_npt = this.end_npt;
 577+
 578+ this.src = getURLParamReplace( this.src, {
 579+ 't': start_npt + '/' + end_npt
 580+ });
 581+
 582+ // update the duration
 583+ this.parseURLDuration();
 584+ }
 585+ },
 586+
 587+ /**
 588+ * Sets the duration and sets the end time if unset
 589+ * @param {Float} duration: in seconds
 590+ */
 591+ setDuration:function ( duration ) {
 592+ this.duration = duration;
 593+ if ( !this.end_npt ) {
 594+ this.end_npt = seconds2npt( this.start_offset + duration );
 595+ }
 596+ },
 597+
 598+ /**
 599+ * MIME type accessor function.
 600+ * @return {String} the MIME type of the source.
 601+ */
 602+ getMIMEType : function() {
 603+ return this.mime_type;
 604+ },
 605+
 606+ /** URI function.
 607+ * @param {Number} seek_time_sec Int: Used to adjust the URI for url based seeks)
 608+ * @return {String} the URI of the source.
 609+ */
 610+ getURI : function( seek_time_sec ) {
 611+ if ( !seek_time_sec || !this.URLTimeEncoding ) {
 612+ return this.src;
 613+ }
 614+ if ( !this.end_npt ) {
 615+ var endvar = '';
 616+ } else {
 617+ var endvar = '/' + this.end_npt;
 618+ }
 619+ return getURLParamReplace( this.src,
 620+ {
 621+ 't': seconds2npt( seek_time_sec ) + endvar
 622+ }
 623+ );
 624+ },
 625+
 626+ /** Title accessor function.
 627+ @return Title of the source.
 628+ @type String
 629+ */
 630+ getTitle : function() {
 631+ if( this.title )
 632+ return this.title;
 633+
 634+ // Return a Title based on mime type:
 635+ switch( this.mime_type ){
 636+ case 'video/h264' :
 637+ return gM( 'mwe-video-h264' );
 638+ break;
 639+ case 'video/x-flv' :
 640+ return gM( 'mwe-video-flv' );
 641+ break;
 642+ case 'video/ogg' :
 643+ return gM( 'mwe-video-ogg' );
 644+ break;
 645+ case 'audio/ogg' :
 646+ return gM( 'mwe-video-audio' );
 647+ break;
 648+ }
 649+
 650+ // Return the mime type string if not known type.
 651+ return this.mime_type;
 652+ },
 653+
 654+ /** Index accessor function.
 655+ @return the source's index within the enclosing mediaElement container.
 656+ @type Integer
 657+ */
 658+ getIndex : function() {
 659+ return this.index;
 660+ },
 661+
 662+ /**
 663+ *
 664+ * Gets Duration of the media in milliseconds from the source url.
 665+ *
 666+ * Supports media_url?t=ntp_start/ntp_end url request format
 667+ */
 668+ parseURLDuration : function() {
 669+ // check if we have a URLTimeEncoding:
 670+ if ( this.URLTimeEncoding ) {
 671+ var annoURL = mw.parseUri( this.src );
 672+ if ( annoURL.queryKey['t'] ) {
 673+ var times = annoURL.queryKey['t'].split( '/' );
 674+ this.start_npt = times[0];
 675+ this.end_npt = times[1];
 676+ this.start_offset = npt2seconds( this.start_npt );
 677+ this.duration = npt2seconds( this.end_npt ) - this.start_offset;
 678+ } else {
 679+ // look for this info as attributes
 680+ if ( this.startOffset ) {
 681+ this.start_offset = this.startOffset;
 682+ this.start_npt = seconds2npt( this.startOffset );
 683+ }
 684+ if ( this.duration ) {
 685+ this.end_npt = seconds2npt( parseInt( this.duration ) + parseInt( this.start_offset ) );
 686+ }
 687+ }
 688+ }
 689+ },
 690+
 691+ /**
 692+ * Attempts to detect the type of a media file based on the URI.
 693+ * @param {String} uri URI of the media file.
 694+ * @returns {String} The guessed MIME type of the file.
 695+ * @type String
 696+ */
 697+ detectType:function( uri ) {
 698+ // @@todo if media is on the same server as the javascript
 699+ // we can issue a HEAD request and read the mime type of the media...
 700+ // ( this will detect media mime type independently of the url name)
 701+ // http://www.jibbering.com/2002/4/httprequest.html
 702+ var end_inx = ( uri.indexOf( '?' ) != -1 ) ? uri.indexOf( '?' ) : uri.length;
 703+ var no_param_uri = uri.substr( 0, end_inx );
 704+ switch( no_param_uri.substr( no_param_uri.lastIndexOf( '.' ), 4 ).toLowerCase() ) {
 705+ case '.mp4':
 706+ return 'video/h264';
 707+ break;
 708+ case '.flv':
 709+ return 'video/x-flv';
 710+ break;
 711+ case '.ogg':
 712+ case '.ogv':
 713+ return 'video/ogg';
 714+ break;
 715+ case '.oga':
 716+ return 'audio/ogg';
 717+ break;
 718+ case '.anx':
 719+ return 'video/ogg';
 720+ break;
 721+ }
 722+ }
 723+};
 724+
 725+/**
 726+* A media element corresponding to a <video> element.
 727+*
 728+* It is implemented as a collection of mediaSource objects. The media sources
 729+* will be initialized from the <video> element, its child <source> elements,
 730+* and/or the ROE file referenced by the <video> element.
 731+* @param {element} video_element <video> element used for initialization.
 732+* @constructor
 733+*/
 734+function mediaElement( element )
 735+{
 736+ this.init( element );
 737+};
 738+
 739+mediaElement.prototype = {
 740+ // The array of mediaSource elements.
 741+ sources:null,
 742+ // flag for ROE data being added.
 743+ addedROEData:false,
 744+
 745+ // Selected mediaSource element.
 746+ selected_source:null,
 747+
 748+ // Media element thumbnail
 749+ thumbnail:null,
 750+
 751+ // Media element linkback
 752+ linkback:null,
 753+
 754+ /**
 755+ * Media Element constructor
 756+ *
 757+ * @param {Element} video_element Element that has src attribute or has children source elements
 758+ */
 759+ init: function( video_element ) {
 760+ var _this = this;
 761+ js_log( 'Initializing mediaElement...' );
 762+ this.sources = new Array();
 763+ this.thumbnail = mv_default_thumb_url;
 764+
 765+ if ( $j( video_element ).attr( 'thumbnail' ) )
 766+ this.thumbnail = $j( video_element ).attr( 'thumbnail' );
 767+
 768+ if ( $j( video_element ).attr( 'poster' ) )
 769+ this.thumbnail = $j( video_element ).attr( 'poster' );
 770+
 771+ if ( $j( video_element ).attr( 'wikiTitleKey' ) )
 772+ this.wikiTitleKey = $j( video_element ).attr( 'wikiTitleKey' );
 773+
 774+ if ( $j( video_element ).attr( 'durationHint' ) ) {
 775+ this.durationHint = $j( video_element ).attr( 'durationHint' );
 776+ // convert duration hint if needed:
 777+ this.duration = npt2seconds( this.durationHint );
 778+ }
 779+
 780+ // Process the video_element as a source element:
 781+ if ( $j( video_element ).attr( "src" ) )
 782+ this.tryAddSource( video_element );
 783+
 784+ // Process all inner <source>, <text> & <itext> elements
 785+ $j( video_element ).find( 'source,text,itext' ).each( function( inx, inner_source ) {
 786+ _this.tryAddSource( inner_source );
 787+ } );
 788+ },
 789+
 790+ /**
 791+ * Updates the time request for all sources that have
 792+ * a standard time request argument (ie &t=start_time/end_time)
 793+ *
 794+ * @param {String} start_npt Start time in npt format
 795+ * @param {String} end_npt End time in npt format
 796+ */
 797+ updateSourceTimes:function( start_npt, end_npt ) {
 798+ var _this = this;
 799+ $j.each( this.sources, function( inx, mediaSource ) {
 800+ mediaSource.updateSrcTime( start_npt, end_npt );
 801+ } );
 802+ },
 803+
 804+ /**
 805+ * Check for Timed Text tracks
 806+ * @return {Boolean} true if text tracks exist, false if no text tracks are found
 807+ */
 808+ textSourceExists: function() {
 809+ for ( var i = 0; i < this.sources.length; i++ ) {
 810+ if ( this.sources[i].mime_type == 'text/cmml' ||
 811+ this.sources[i].mime_type == 'text/x-srt' )
 812+ return true;
 813+ };
 814+ return false;
 815+ },
 816+
 817+ /**
 818+ * Returns the array of mediaSources of this element.
 819+ *
 820+ * @param {String} mime_filter Filter criteria for set of mediaSources to return
 821+ * @return {Array} of mediaSource elements.
 822+ */
 823+ getSources:function( mime_filter ){
 824+ if ( !mime_filter )
 825+ return this.sources;
 826+ // apply mime filter:
 827+ var source_set = new Array();
 828+ for ( var i = 0; i < this.sources.length ; i++ ) {
 829+ if ( this.sources[i].mime_type.indexOf( mime_filter ) != -1 )
 830+ source_set.push( this.sources[i] );
 831+ }
 832+ return source_set;
 833+ },
 834+
 835+ /**
 836+ * Selects a source by id
 837+ * @param {String} source_id Id of the srouce to select.
 838+ * @return {MediaSource} The selected mediaSource or null if not found
 839+ */
 840+ getSourceById:function( source_id ) {
 841+ for ( var i = 0; i < this.sources.length ; i++ ) {
 842+ if ( this.sources[i].id == source_id )
 843+ return this.sources[i];
 844+ }
 845+ return null;
 846+ },
 847+
 848+ /**
 849+ * Selects a particular source for playback updating the "selected_source"
 850+ *
 851+ * @param {Number} index Index of source element to set as selected_source
 852+ */
 853+ selectSource:function( index )
 854+ {
 855+ js_log( 'f:selectSource:' + index );
 856+ var playable_sources = this.getPlayableSources();
 857+ for ( var i = 0; i < playable_sources.length; i++ ) {
 858+ if ( i == index ) {
 859+ this.selected_source = playable_sources[i];
 860+ // Update the user selected format:
 861+ embedTypes.players.userSelectFormat( playable_sources[i].mime_type );
 862+ break;
 863+ }
 864+ }
 865+ },
 866+
 867+ /**
 868+ * Selects the default source via cookie preference, default marked, or by id order
 869+ */
 870+ autoSelectSource:function() {
 871+ js_log( 'f:autoSelectSource:' );
 872+ // Select the default source
 873+ var playable_sources = this.getPlayableSources();
 874+ var flash_flag = ogg_flag = false;
 875+ // debugger;
 876+ for ( var source = 0; source < playable_sources.length; source++ ) {
 877+ var mime_type = playable_sources[source].mime_type;
 878+ if ( playable_sources[source].marked_default ) {
 879+ js_log( 'set via marked default: ' + playable_sources[source].marked_default );
 880+ this.selected_source = playable_sources[source];
 881+ return true;
 882+ }
 883+ // Set via user-preference
 884+ if ( embedTypes.players.preference['format_prefrence'] == mime_type ) {
 885+ js_log( 'set via preference: ' + playable_sources[source].mime_type );
 886+ this.selected_source = playable_sources[source];
 887+ return true;
 888+ }
 889+ }
 890+
 891+ // Set Ogg if client supports it
 892+ for ( var source = 0; source < playable_sources.length; source++ ) {
 893+ js_log( 'f:autoSelectSource:' + playable_sources[source].mime_type );
 894+ var mime_type = playable_sources[source].mime_type;
 895+ // set source via player
 896+ if ( mime_type == 'video/ogg' || mime_type == 'ogg/video' || mime_type == 'video/annodex' || mime_type == 'application/ogg' ) {
 897+ for ( var i = 0; i < embedTypes.players.players.length; i++ ) { // for in loop on object oky
 898+ var player = embedTypes.players.players[i];
 899+ if ( player.library == 'vlc' || player.library == 'native' ) {
 900+ js_log( 'set via ogg via order' );
 901+ this.selected_source = playable_sources[source];
 902+ return true;
 903+ }
 904+ }
 905+ }
 906+ }
 907+
 908+ // Set basic flash
 909+ for ( var source = 0; source < playable_sources.length; source++ ) {
 910+ var mime_type = playable_sources[source].mime_type;
 911+ if ( mime_type == 'video/x-flv' ) {
 912+ js_log( 'set via by player preference normal flash' )
 913+ this.selected_source = playable_sources[source];
 914+ return true;
 915+ }
 916+ }
 917+ // Set h264 flash
 918+ for ( var source = 0; source < playable_sources.length; source++ ) {
 919+ var mime_type = playable_sources[source].mime_type;
 920+ if ( mime_type == 'video/h264' ) {
 921+ js_log( 'set via playable_sources preference h264 flash' )
 922+ this.selected_source = playable_sources[source];
 923+ return true;
 924+ }
 925+ }
 926+ // Select first source
 927+ if ( !this.selected_source ){
 928+ js_log( 'set via first source:' + playable_sources[0] );
 929+ this.selected_source = playable_sources[0];
 930+ return true;
 931+ }
 932+ // No Source found so no source selected
 933+ return false;
 934+ },
 935+
 936+ /**
 937+ * Returns the thumbnail URL for the media element.
 938+ * @returns {String} thumbnail URL
 939+ */
 940+ getThumbnailURL:function()
 941+ {
 942+ return this.thumbnail;
 943+ },
 944+
 945+ /**
 946+ * Checks whether there is a stream of a specified MIME type.
 947+ * @param {String} mime_type MIME type to check.
 948+ * @return {Boolean} true if sources include MIME false if not.
 949+ */
 950+ hasStreamOfMIMEType:function( mime_type )
 951+ {
 952+ for ( source in this.sources )
 953+ {
 954+ if ( this.sources[source].getMIMEType() == mime_type )
 955+ return true;
 956+ }
 957+ return false;
 958+ },
 959+
 960+ /**
 961+ * Checks if media is a playable type
 962+ */
 963+ isPlayableType:function( mime_type )
 964+ {
 965+ if ( embedTypes.players.defaultPlayer( mime_type ) ) {
 966+ return true;
 967+ } else {
 968+ return false;
 969+ }
 970+ },
 971+
 972+ /**
 973+ * Adds a single mediaSource using the provided element if
 974+ * the element has a 'src' attribute.
 975+ * @param {Element} element <video>, <source> or <mediaSource> <text> element.
 976+ */
 977+ tryAddSource:function( element )
 978+ {
 979+ js_log( 'f:tryAddSource:' + $j( element ).attr( "src" ) );
 980+ if ( $j( element ).attr( "src" ) ) {
 981+ var new_src = $j( element ).attr( 'src' );
 982+ // make sure an existing element with the same src does not already exist:
 983+ for ( var i = 0; i < this.sources.length; i++ ) {
 984+ if ( this.sources[i].src == new_src ) {
 985+ // js_log('checking existing: '+this.sources[i].getURI() + ' != '+ new_src);
 986+ // can't add it all but try to update any additional attr:
 987+ this.sources[i].updateSource( element );
 988+ }
 989+ }
 990+ }
 991+ var source = new mediaSource( element );
 992+ // Inherit some properties from the parent <video> element if unset:
 993+ if ( !source.duration && this.duration )
 994+ source.duration = this.duration;
 995+
 996+ if ( !source.startOffset && this.startOffset )
 997+ source.startOffset = this.startOffset;
 998+
 999+
 1000+ this.sources.push( source );
 1001+ js_log( 'pushed source to stack' + source + 'sl:' + this.sources.length );
 1002+ },
 1003+
 1004+ /**
 1005+ * Gets playable sources
 1006+ *
 1007+ * @returns {Array} of playbale sources
 1008+ */
 1009+ getPlayableSources: function() {
 1010+ var playable_sources = new Array();
 1011+ for ( var i = 0; i < this.sources.length; i++ ) {
 1012+ if ( this.isPlayableType( this.sources[i].mime_type ) ) {
 1013+ playable_sources.push( this.sources[i] );
 1014+ } else {
 1015+ js_log( "type " + this.sources[i].mime_type + 'is not playable' );
 1016+ }
 1017+ };
 1018+ return playable_sources;
 1019+ },
 1020+
 1021+ /**
 1022+ * Imports media sources from ROE data.
 1023+ * @param roe_data ROE data.
 1024+ */
 1025+ addROE: function( roe_data ) {
 1026+ js_log( 'f:addROE' );
 1027+ this.addedROEData = true;
 1028+ var _this = this;
 1029+ if ( typeof roe_data == 'string' )
 1030+ {
 1031+ var parser = new DOMParser();
 1032+ js_log( 'ROE data:' + roe_data );
 1033+ roe_data = parser.parseFromString( roe_data, "text/xml" );
 1034+ }
 1035+ if ( roe_data ) {
 1036+ $j.each( roe_data.getElementsByTagName( 'mediaSource' ), function( inx, source ) {
 1037+ _this.tryAddSource( source );
 1038+ } );
 1039+ // set the thumbnail:
 1040+ $j.each( roe_data.getElementsByTagName( 'img' ), function( inx, n ) {
 1041+ if ( $j( n ).attr( "id" ) == "stream_thumb" ) {
 1042+ js_log( 'roe:set thumb to ' + $j( n ).attr( "src" ) );
 1043+ _this['thumbnail'] = $j( n ).attr( "src" );
 1044+ }
 1045+ } );
 1046+ // set the linkback:
 1047+ $j.each( roe_data.getElementsByTagName( 'link' ), function( inx, n ) {
 1048+ if ( $j( n ).attr( 'id' ) == 'html_linkback' ) {
 1049+ js_log( 'roe:set linkback to ' + $j( n ).attr( "href" ) );
 1050+ _this['linkback'] = $j( n ).attr( 'href' );
 1051+ }
 1052+ } );
 1053+ } else {
 1054+ js_log( 'ROE data empty.' );
 1055+ }
 1056+ }
 1057+};
 1058+
 1059+
 1060+/** base embedPlayer object
 1061+* @param {Element} element, the element used for initialization.
 1062+* @param {Object} customAttributes Attributes for the video interface
 1063+* that are not already element attributes
 1064+* @constructor
 1065+*/
 1066+var embedPlayer = function( element, customAttributes ) {
 1067+ return this.init( element, customAttributes );
 1068+};
 1069+
 1070+embedPlayer.prototype = {
 1071+ // The mediaElement object containing all mediaSource objects
 1072+ 'media_element' : null,
 1073+
 1074+ // Object that describes the supported feature set of the underling plugin / player
 1075+ 'supports': { },
 1076+
 1077+ // Preview mode flag,
 1078+ // some plugins don't seek accurately but in preview mode we need
 1079+ // accurate seeks so we do tricks like hide the image until its ready
 1080+ 'preview_mode' : false,
 1081+
 1082+ // Ready to play
 1083+ // NOTE: we should switch over to setting the html5 video ready state
 1084+ 'ready_to_play' : false,
 1085+
 1086+ // Stores the loading errors
 1087+ 'load_error' : false,
 1088+
 1089+ // Loading external data flag ( for delaying interface updates )
 1090+ 'loading_external_data' : false,
 1091+
 1092+ // Thumbnail updating flag ( to avoid rewriting an thumbnail thats already being updated)
 1093+ 'thumbnail_updating' : false,
 1094+
 1095+ // Thumbnail display flag
 1096+ 'thumbnail_disp' : true,
 1097+
 1098+ // Local variable to hold CMML meeta data about the current clip
 1099+ // for more on CMML see: http://wiki.xiph.org/CMML
 1100+ 'cmmlData': null,
 1101+
 1102+ // Stores the seek time request, Updated by the doSeek function
 1103+ 'seek_time_sec' : 0,
 1104+
 1105+ // If the embedPlayer is current 'seeking'
 1106+ 'seeking' : false,
 1107+
 1108+ // Percent of the clip buffered:
 1109+ 'bufferedPercent' : 0,
 1110+
 1111+ /**
 1112+ * embedPlayer constructor
 1113+ *
 1114+ * @param {Element} element DOM element that we are building the player interface for.
 1115+ * @param {Object} customAttributes Attributes supplied via argument (rather than applied to the element)
 1116+ */
 1117+ init: function( element, customAttributes ) {
 1118+
 1119+ // Set customAttributes if unset:
 1120+ if ( !customAttributes )
 1121+ customAttributes = { };
 1122+
 1123+ // Setup the player Interface from supported attributes:
 1124+ for ( var attr in default_video_attributes ) {
 1125+ if ( customAttributes[ attr ] ){
 1126+ this[ attr ] = customAttributes[ attr ];
 1127+ } else if ( element.getAttribute( attr ) ) {
 1128+ this[ attr ] = element.getAttribute( attr );
 1129+ } else {
 1130+ this[attr] = default_video_attributes[attr];
 1131+ }
 1132+ }
 1133+
 1134+ // Set the skin name from the class
 1135+ var sn = $j(element).attr( 'class' );
 1136+ if ( sn && sn != '' ) {
 1137+ for ( var n = 0; n < mw.valid_skins.length; n++ ) {
 1138+ if ( sn.indexOf( mw.valid_skins[n] ) !== -1 ) {
 1139+ this.skin_name = mw.valid_skins[ n ];
 1140+ }
 1141+ }
 1142+ }
 1143+
 1144+ // Set the default skin if unset:
 1145+ if ( !this.skin_name )
 1146+ this.skin_name = mw.conf.skin_name;
 1147+
 1148+ // Make sure startOffset is cast as an int
 1149+ if ( this.startOffset && this.startOffset.split( ':' ).length >= 2 )
 1150+ this.startOffset = npt2seconds( this.startOffset );
 1151+
 1152+ // Make sure offset is in float:
 1153+ this.startOffset = parseFloat( this.startOffset );
 1154+
 1155+ if ( this.duration && this.duration.split( ':' ).length >= 2 )
 1156+ this.duration = npt2seconds( this.duration );
 1157+
 1158+ // Make sure duration is in float:
 1159+ this.duration = parseFloat( this.duration );
 1160+ js_log( "duration is: " + this.duration );
 1161+
 1162+
 1163+ this.setDimSize( element, 'width' );
 1164+ this.setDimSize( element, 'height' );
 1165+
 1166+ // Set the plugin id
 1167+ this.pid = 'pid_' + this.id;
 1168+
 1169+ // Grab any innerHTML and set it to missing_plugin_html
 1170+ // @@todo we should strip source tags instead of checking and skipping
 1171+ if ( element.innerHTML != '' && element.getElementsByTagName( 'source' ).length == 0 ) {
 1172+ js_log( 'innerHTML: ' + element.innerHTML );
 1173+ this.user_missing_plugin_html = element.innerHTML;
 1174+ }
 1175+
 1176+ // Add the mediaElement object with the elements sources:
 1177+ this.media_element = new mediaElement( element );
 1178+
 1179+ // If we are displaying controls setup the ctrlBuilder
 1180+ if ( this.controls ) {
 1181+ // Set-up the local ctrlBuilder instance:
 1182+ this.ctrlBuilder = new ctrlBuilder( this );
 1183+ }
 1184+ // Load player skin css:
 1185+ loadExternalCss( mv_embed_path + 'skins/' + this.skin_name + '/playerSkin.css' );
 1186+ },
 1187+
 1188+ /**
 1189+ * Set width or height from css style attribute, html element attribute, or by default value
 1190+ */
 1191+ setDimSize:function( element, dim ){
 1192+ var dcss = parseInt( $j(element).css( dim ).replace( 'px' , '' ) );
 1193+ var dattr = parseInt( $j(element).attr( dim ) );
 1194+ this[ dim ] = ( dcss )? dcss : dattr;
 1195+ if( !this[ dim ] ){
 1196+ //special height default for audio tag:
 1197+ if( element.tagName.toLowerCase() == 'audio' && dim == 'height' )
 1198+ return this[ dim ] = 0;
 1199+ // Grab width/height from default value (for video)
 1200+ var dwh = mw.conf['video_size'].split( 'x' );
 1201+ this[ dim ] = ( dim == 'width' )? dwh[0] : dwh[1];
 1202+ }
 1203+ },
 1204+
 1205+ /**
 1206+ * Get the player pixle width
 1207+ */
 1208+ playerPixelWidth: function(){
 1209+ var player = $j( '#mv_embedded_player_' + this.id ).get( 0 );
 1210+ if ( typeof player != 'undefined' && player['offsetWidth'] )
 1211+ return player.offsetWidth;
 1212+ else
 1213+ return parseInt( this.width );
 1214+ },
 1215+
 1216+ /**
 1217+ * Get the player pixle height
 1218+ */
 1219+ playerPixelHeight: function(){
 1220+ var player = $j( '#mv_embedded_player_' + this.id ).get( 0 );
 1221+ if ( typeof player != 'undefined' && player['offsetHeight'] )
 1222+ return player.offsetHeight;
 1223+ else
 1224+ return parseInt( this.height );
 1225+ },
 1226+
 1227+ /**
 1228+ * Check player sources if we need to get media sources
 1229+ * form an external file that request is issued here
 1230+ */
 1231+ checkPlayerSources: function() {
 1232+ js_log( 'f:checkPlayerSources' );
 1233+ var _this = this;
 1234+ // Process the provided ROE file. If we don't yet have sources
 1235+ // ( the ROE file provides xml list of sources )
 1236+ if ( this.roe && this.media_element.sources.length == 0 ) {
 1237+ js_log( 'checkPlayerSources: loading external data' );
 1238+ this.loading_external_data = true;
 1239+ do_request( this.roe, function( data ){
 1240+ // Continue
 1241+ _this.media_element.addROE( data );
 1242+ js_log( 'added_roe::' + _this.media_element.sources.length );
 1243+
 1244+ js_log( 'set loading_external_data=false' );
 1245+ _this.loading_external_data = false;
 1246+
 1247+ _this.sourcesReadyInit();
 1248+ } );
 1249+ }else{
 1250+ _this.sourcesReadyInit();
 1251+ }
 1252+ },
 1253+
 1254+ /**
 1255+ * Sources Ready Innitialization
 1256+ *
 1257+ * issues autoSelectSource call
 1258+ *
 1259+ * Sets load error if no source is playable
 1260+ */
 1261+ sourcesReadyInit : function(){
 1262+ js_log( 'f:sourcesReadyInit' );
 1263+
 1264+ // Autoseletct the source
 1265+ this.media_element.autoSelectSource();
 1266+
 1267+ // Auto select player based on default order
 1268+ if ( !this.media_element.selected_source ){
 1269+ // check for parent clip:
 1270+ if ( typeof this.pc != 'undefined' ) {
 1271+ js_log( 'no sources, type:' + this.type + ' check for html' );
 1272+ // debugger;
 1273+ // do load player if just displaying innerHTML:
 1274+ if ( this.pc.type == 'text/html' ) {
 1275+ this.selected_player = embedTypes.players.defaultPlayer( 'text/html' );
 1276+ js_log( 'set selected player:' + this.selected_player.mime_type );
 1277+ }
 1278+ }
 1279+ } else {
 1280+ this.selected_player = embedTypes.players.defaultPlayer( this.media_element.selected_source.mime_type );
 1281+ }
 1282+ if ( this.selected_player ) {
 1283+ js_log( "Playback system: " + this.selected_player.library );
 1284+
 1285+ // Inherit the playback system of the selected player:
 1286+ this.inheritEmbedPlayer();
 1287+ } else {
 1288+ // No source's playable
 1289+ var missing_type = '';
 1290+ var or = '';
 1291+ for ( var i = 0; i < this.media_element.sources.length; i++ ) {
 1292+ missing_type += or + this.media_element.sources[i].mime_type;
 1293+ or = ' or ';
 1294+ }
 1295+ // Get from parent playlist if set:
 1296+ if ( this.pc )
 1297+ var missing_type = this.pc.type;
 1298+
 1299+ js_log( 'No player found for given source type ' + missing_type );
 1300+ this.load_error = this.getPluginMissingHTML( missing_type );
 1301+ }
 1302+ },
 1303+
 1304+ /**
 1305+ * Load and inherit methods from the selected player interface
 1306+ *
 1307+ * @param {Function} callback Function to be called once playback-system has been inherited
 1308+ */
 1309+ inheritEmbedPlayer: function( callback ) {
 1310+ js_log( "inheritEmbedPlayer:duration is: " + this.getDuration() );
 1311+
 1312+ // Clear out any non-base embedObj methods:
 1313+ if ( this.instanceOf ) {
 1314+ eval( 'tmpObj = ' + this.instanceOf );
 1315+ for ( var i in tmpObj ) { // for in loop oky for object
 1316+ if ( this['parent_' + i] ) {
 1317+ this[i] = this['parent_' + i];
 1318+ } else {
 1319+ this[i] = null;
 1320+ }
 1321+ }
 1322+ }
 1323+
 1324+ // Set up the new embedObj
 1325+ js_log( 'f: inheritEmbedPlayer: embedding with ' + this.selected_player.library );
 1326+ var _this = this;
 1327+
 1328+ // Load the selected player
 1329+ this.selected_player.load( function() {
 1330+
 1331+ // Get the selected Player embed interface
 1332+ eval( 'var embedPlayer = ' + _this.selected_player.library + 'Embed;' );
 1333+
 1334+ for ( var method in embedPlayer ) {
 1335+ if ( _this[method] )
 1336+ _this['parent_' + method] = _this[method];
 1337+ _this[method] = embedPlayer[method];
 1338+ }
 1339+
 1340+ _this.ready_to_play = true;
 1341+ _this.getDuration();
 1342+ _this.getHTML();
 1343+
 1344+ // Run the callback if provided
 1345+ if ( callback )
 1346+ callback();
 1347+ } );
 1348+ },
 1349+
 1350+ /**
 1351+ * Select a player playback system
 1352+ *
 1353+ * @param {Object} player Player playback system to be selected
 1354+ * player playback system include vlc, native, java etc.
 1355+ */
 1356+ selectPlayer:function( player ) {
 1357+ var _this = this;
 1358+ if ( this.selected_player.id != player.id ) {
 1359+ this.selected_player = player;
 1360+ this.inheritEmbedPlayer( function(){
 1361+ // Update the controls for the new selected player
 1362+ this.refreshControlsHTML();
 1363+ });
 1364+ }
 1365+ },
 1366+
 1367+ /**
 1368+ * Issue a warning to non-native playback systems
 1369+ * that they could improve the playback experience with a different browser
 1370+ */
 1371+ doNativeWarningCheck:function() {
 1372+ if ( $j.cookie( 'dismissNativeWarn' ) && $j.cookie( 'dismissNativeWarn' ) === true ) {
 1373+ return false;
 1374+ }
 1375+
 1376+ // See if we have native support for ogg:
 1377+ var supporting_players = embedTypes.players.getMIMETypePlayers( 'video/ogg' );
 1378+ for ( var i = 0; i < supporting_players.length; i++ ) {
 1379+ if ( supporting_players[i].id == 'videoElement' ) {
 1380+ return false;
 1381+ }
 1382+ }
 1383+ // See if we are using mv_embed without a ogg source in which case no point in promoting firefox :P
 1384+ if ( this.media_element && this.media_element.sources ) {
 1385+ var foundOgg = false;
 1386+ var playable_sources = this.media_element.getPlayableSources();
 1387+ for ( var sInx = 0; sInx < playable_sources.length; sInx++ ) {
 1388+ var mime_type = playable_sources[sInx].mime_type;
 1389+ if ( mime_type == 'video/ogg' ) {
 1390+ foundOgg = true;
 1391+ }
 1392+ }
 1393+ // no ogg src... no point in download firefox link
 1394+ if ( !foundOgg )
 1395+ return false;
 1396+
 1397+ }
 1398+ return true;
 1399+ },
 1400+
 1401+ /**
 1402+ * Gets a Time range from the media start and end time
 1403+ *
 1404+ * @return start_npt and end_npt time if present
 1405+ */
 1406+ getTimeRange: function(){
 1407+ var end_time = (this.ctrlBuilder.long_time_disp)? '/' + seconds2npt( this.getDuration() ) : '';
 1408+ var default_time_range = '0:00:00' + end_time;
 1409+ if ( !this.media_element )
 1410+ return default_time_range;
 1411+ if ( !this.media_element.selected_source )
 1412+ return default_time_range;
 1413+ if ( !this.media_element.selected_source.end_npt )
 1414+ return default_time_range;
 1415+ return this.media_element.selected_source.start_npt + this.media_element.selected_source.end_npt;
 1416+ },
 1417+ /**
 1418+ * Gets the duration of the embed media
 1419+ */
 1420+ getDuration:function() {
 1421+ // Update some local pointers for the selected source:
 1422+ if ( this.media_element && this.media_element.selected_source && this.media_element.selected_source.duration ) {
 1423+ this.duration = this.media_element.selected_source.duration;
 1424+ this.start_offset = this.media_element.selected_source.start_offset;
 1425+ this.start_npt = this.media_element.selected_source.start_npt;
 1426+ this.end_npt = this.media_element.selected_source.end_npt;
 1427+ }
 1428+ // Update start end_npt if duration !=0 (set from plugin)
 1429+ if ( !this.start_npt )
 1430+ this.start_npt = '0:0:0';
 1431+ if ( !this.end_npt && this.duration )
 1432+ this.end_npt = seconds2npt( this.duration );
 1433+ // Return the duration
 1434+ return this.duration;
 1435+ },
 1436+
 1437+ /**
 1438+ * wraps the embed code into a container to better support playlist function
 1439+ * (where embed element is swapped for next clip
 1440+ * (where plugin method does not support playlist)
 1441+ */
 1442+ wrapEmebedContainer:function( embed_code ) {
 1443+ // Check if parent clip is set( ie we are in a playlist so name the embed container by playlistID)
 1444+ var id = ( this.pc != null ) ? this.pc.pp.id:this.id;
 1445+ return '<div id="mv_ebct_' + id + '" style="width:' + this.width + 'px;height:' + this.height + 'px;">' +
 1446+ embed_code +
 1447+ '</div>';
 1448+ },
 1449+
 1450+ /**
 1451+ * Get the plugin embed html ( should be implemented by embed player interface )
 1452+ */
 1453+ getEmbedHTML : function() {
 1454+ return 'Error: function getEmbedHTML should be implemented by embed player interface ';
 1455+ },
 1456+
 1457+ /*
 1458+ * Seek function (should be implemented by embed player interface )
 1459+ */
 1460+ doSeek : function( perc ) {
 1461+ var _this = this;
 1462+ if ( this.supportsURLTimeEncoding() ) {
 1463+ // Make sure this.seek_time_sec is up-to-date:
 1464+ this.seek_time_sec = npt2seconds( this.start_npt ) + parseFloat( perc * this.getDuration() );
 1465+ js_log( 'updated seek_time_sec: ' + seconds2npt ( this.seek_time_sec ) );
 1466+ this.stop();
 1467+ this.didSeekJump = true;
 1468+ // Update the slider
 1469+ this.setSliderValue( perc );
 1470+ }
 1471+ // Do play request in 100ms ( give the dom time to swap out the embed player )
 1472+ setTimeout( function(){
 1473+ _this.play()
 1474+ }, 100 );
 1475+ },
 1476+ /**
 1477+ * Seeks to the requested time and issues a callback when ready
 1478+ * (should be overwritten by client that supports frame serving)
 1479+ */
 1480+ setCurrentTime:function( time, callback ) {
 1481+ js_log( 'Error: base embed setCurrentTime can not frame serve (override via plugin)' );
 1482+ },
 1483+
 1484+ doEmbedHTML:function() {
 1485+ js_log( 'f:doEmbedHTML' );
 1486+ js_log( 'thum disp:' + this.thumbnail_disp );
 1487+ var _this = this;
 1488+ this.closeDisplayedHTML();
 1489+
 1490+ // Set "loading" here
 1491+ $j( '#mv_embedded_player_' + _this.id ).html( '' +
 1492+ '<div style="color:black;width:' + this.width + 'px;height:' + this.height + 'px;">' +
 1493+ gM( 'mwe-loading_plugin' ) +
 1494+ '</div>'
 1495+ );
 1496+ // Schedule embedding after player library is loaded:
 1497+ this.selected_player.load( function() {
 1498+ js_log( 'performing embed for ' + _this.id );
 1499+ var embed_code = _this.getEmbedHTML();
 1500+ // js_log('shopuld embed:' + embed_code);
 1501+ $j( '#mv_embedded_player_' + _this.id ).html( embed_code );
 1502+ } );
 1503+ },
 1504+ relatedTitleKeySearch:function() {
 1505+ var _this = this;
 1506+ var reqObj = {
 1507+ 'action' : 'query',
 1508+ //normalize the File NS (ie sometimes its present in wikiTitleKey other times not
 1509+ 'titles' : 'File:' + this.wikiTitleKey.replace(/File:|Image:/,''),
 1510+ 'generator' : 'categories'
 1511+ };
 1512+ var req_categories = new Array();
 1513+ do_api_req( {
 1514+ 'url' : mw.commons_api_url,
 1515+ 'data' : reqObj
 1516+ }, function( data ) {
 1517+ req_categories = Array();
 1518+ if ( data.query && data.query.pages ) {
 1519+ for ( var pageid in data.query.pages ) {
 1520+ if ( data.query.pages[pageid].title )
 1521+ req_categories.push( data.query.pages[pageid].title );
 1522+ }
 1523+ _this.getRelatedFromCat( req_categories );
 1524+ } else {
 1525+ _this.doThumbnailHTML();
 1526+ }
 1527+ } );
 1528+ },
 1529+ getRelatedFromCat:function( catAry ) {
 1530+ js_log( 'getRelatedFromCat' );
 1531+ var _this = this;
 1532+ for ( var i = 0 ; i <= catAry.length ; i++ ) {
 1533+ if ( !catAry[i] )
 1534+ continue;
 1535+ var reqObj = {
 1536+ 'action' : 'query',
 1537+ 'generator' : 'categorymembers' ,
 1538+ 'gcmtitle' : catAry[i],
 1539+ 'prop' : 'imageinfo',
 1540+ 'iiprop' : 'url',
 1541+ 'iiurlwidth': '80'
 1542+ };
 1543+ do_api_req( {
 1544+ 'data':reqObj,
 1545+ 'url': mw.commons_api_url
 1546+ }, function( data ) {
 1547+ // empty the videos:
 1548+ $j( '#dc_' + _this.id + ' .related_vids ul' ).html( ' ' );
 1549+
 1550+ for ( var j in data.query.pages ) {
 1551+ // Setup poster default:
 1552+ var local_poster = "http://upload.wikimedia.org/wikipedia/commons/7/79/Wiki-commons.png";
 1553+ // Make sure it exists:
 1554+ var page = data.query.pages[j];
 1555+ if ( j > 0 && page && page['imageinfo'] ) {
 1556+ if ( page['imageinfo'][0].thumburl ) {
 1557+ local_poster = page['imageinfo'][0].thumburl;
 1558+ }
 1559+ var descriptionurl = page['imageinfo'][0].descriptionurl;
 1560+ var title_str = page.title.replace( /File:|.ogv$|.oga$|.ogg$/gi, "" );
 1561+ // only link to other videos:
 1562+ if ( descriptionurl.match( /\.ogg$|\.ogv$|\.oga$/gi ) != null) {
 1563+ var liout = '<li>' +
 1564+ '<a href="' + descriptionurl + '" >' +
 1565+ '<img src="' + local_poster + '">' +
 1566+ '</a>' +
 1567+ ' <a title="' + title_str + '" target="_blank" ' +
 1568+ 'href="' + descriptionurl + '">' + title_str + '</a>' +
 1569+ '</li>';
 1570+ $j( '#dc_' + _this.id + ' .related_vids ul' ).append( liout ) ;
 1571+ }
 1572+ }
 1573+ };
 1574+ } ); // end do_api_req
 1575+ };
 1576+ },
 1577+ onClipDone:function() {
 1578+ js_log( 'base:onClipDone' );
 1579+ // stop the clip (load the thumbnail etc)
 1580+ this.stop();
 1581+ this.seek_time_sec = 0;
 1582+ this.setSliderValue( 0 );
 1583+ var _this = this;
 1584+
 1585+ if ( this.width < 300 ) {
 1586+ return ;
 1587+ }
 1588+ this.thumbnail_disp = true;
 1589+
 1590+ // make sure we are not in preview mode( no end clip actions in preview mode)
 1591+ if ( this.preview_mode )
 1592+ return ;
 1593+
 1594+ $j( '#img_thumb_' + this.id ).css( 'zindex', 1 );
 1595+ $j( '#' + this.id + ' .play-btn-large' ).hide();
 1596+
 1597+ // add black background
 1598+ $j( '#dc_' + this.id ).append( '<div id="black_back_' + this.id + '" ' +
 1599+ 'style="z-index:-2;position:absolute;background:#000;' +
 1600+ 'top:0px;left:0px;width:' + parseInt( this.width ) + 'px;' +
 1601+ 'height:' + parseInt( this.height ) + 'px;">' +
 1602+ '</div>' );
 1603+
 1604+ if ( this.wikiTitleKey ) {
 1605+ $j( '#dc_' + this.id ).append(
 1606+ '<div class="related_vids" >' +
 1607+ '<h1>' + gM( 'mwe-related_videos' ) + '</h1>' +
 1608+ '<ul>' +
 1609+ '</ul>' +
 1610+ '</div>' );
 1611+ $j( '#img_thumb_' + this.id ).fadeOut( "fast" );
 1612+ $j( '#dc_' + _this.id + ' .related_vids ul' ).html( gM( 'mwe-loading_txt' ) );
 1613+ this.relatedTitleKeySearch();
 1614+ } else {
 1615+ this.onClipDoneDisp();
 1616+ }
 1617+ },
 1618+ onClipDoneDisp:function() {
 1619+ var _this = this;
 1620+ // add the liks_info_div black back
 1621+ $j( '#dc_' + this.id ).append( '<div id="liks_info_' + this.id + '" ' +
 1622+ 'style="width:' + parseInt( parseInt( this.width ) / 2 ) + 'px;' +
 1623+ 'height:' + parseInt( parseInt( this.height ) ) + 'px;' +
 1624+ 'position:absolute;top:10px;overflow:auto' +
 1625+ 'width: ' + parseInt( ( ( parseInt( this.width ) / 2 ) -15 ) ) + 'px;' +
 1626+ 'left:' + parseInt( ( ( parseInt( this.width ) / 2 ) + 15 ) ) + 'px;">' +
 1627+ '</div>'
 1628+ );
 1629+ // start animation (make thumb small in upper left add in div for "loading"
 1630+ $j( '#img_thumb_' + this.id ).animate( {
 1631+ width : parseInt( parseInt( _this.width ) / 2 ),
 1632+ height : parseInt( parseInt( _this.height ) / 2 ),
 1633+ top:20,
 1634+ left:10
 1635+ },
 1636+ 1000,
 1637+ function() {
 1638+ // animation done.. add "loading" to div if empty
 1639+ if ( $j( '#liks_info_' + _this.id ).html() == '' ) {
 1640+ $j( '#liks_info_' + _this.id ).html( gM( 'mwe-loading_txt' ) );
 1641+ }
 1642+ }
 1643+ )
 1644+ // now load roe if run the showNextPrevLinks
 1645+ if ( this.roe && this.media_element.addedROEData == false ) {
 1646+ do_request( this.roe, function( data )
 1647+ {
 1648+ _this.media_element.addROE( data );
 1649+ _this.getNextPrevLinks();
 1650+ } );
 1651+ } else {
 1652+ this.getNextPrevLinks();
 1653+ }
 1654+ },
 1655+ // @@todo we should merge getNextPrevLinks with textInterface .. there is repeated code between them.
 1656+ getNextPrevLinks:function() {
 1657+ js_log( 'f:getNextPrevLinks' );
 1658+ var anno_track_url = null;
 1659+ var _this = this;
 1660+ // check for annoative track
 1661+ $j.each( this.media_element.sources, function( inx, n ) {
 1662+ if ( n.mime_type == 'text/cmml' ) {
 1663+ if ( n.id == 'Anno_en' ) {
 1664+ anno_track_url = n.src;
 1665+ }
 1666+ }
 1667+ } );
 1668+
 1669+ if ( !anno_track_url ) {
 1670+ js_log( 'no annotative track url found' );
 1671+ // $j('#liks_info_'+this.id).html('no metadata found for related links');
 1672+ _this.doThumbnailHTML();
 1673+ return ;
 1674+ }
 1675+
 1676+ js_log( 'we have annotative track:' + anno_track_url );
 1677+ // Zero out seconds (should improve cache hit rate and generally expands metadata search)
 1678+ // @@todo this could be replaced with a regExp
 1679+ var annoURL = mw.parseUri( anno_track_url );
 1680+ var times = annoURL.queryKey['t'].split( '/' );
 1681+ var stime_parts = times[0].split( ':' );
 1682+ var etime_parts = times[1].split( ':' );
 1683+ // zero out the hour:
 1684+ var new_start = stime_parts[0] + ':' + '0:0';
 1685+ // zero out the end sec
 1686+ var new_end = ( etime_parts[0] == stime_parts[0] ) ? ( etime_parts[0] + 1 ) + ':0:0' :etime_parts[0] + ':0:0';
 1687+
 1688+ var etime_parts = times[1].split( ':' );
 1689+
 1690+ var new_anno_track_url = annoURL.protocol + '://' + annoURL.host + annoURL.path + '?';
 1691+ $j.each( annoURL.queryKey, function( i, val ) {
 1692+ new_anno_track_url += ( i == 't' ) ? 't=' + new_start + '/' + new_end + '&' :
 1693+ i + '=' + val + '&';
 1694+ } );
 1695+ var request_key = new_start + '/' + new_end;
 1696+ // check the anno_data cache:
 1697+ // @@todo search cache see if current is in range.
 1698+ if ( this.cmmlData ) {
 1699+ js_log( 'anno data found in cache: ' + request_key );
 1700+ this.showNextPrevLinks();
 1701+ } else {
 1702+ do_request( new_anno_track_url, function( cmml_data ) {
 1703+ js_log( 'raw response: ' + cmml_data );
 1704+ if ( typeof cmml_data == 'string' ) {
 1705+ var parser = new DOMParser();
 1706+ js_log( 'Parse CMML data:' + cmml_data );
 1707+ cmml_data = parser.parseFromString( cmml_data, "text/xml" );
 1708+ }
 1709+ // init cmmlData
 1710+ if ( !_this.cmmlData )
 1711+ _this.cmmlData = { };
 1712+ // grab all metadata and put it into the cmmlData:
 1713+ $j.each( cmml_data.getElementsByTagName( 'clip' ), function( inx, clip ) {
 1714+ _this.cmmlData[ $j( clip ).attr( "id" ) ] = {
 1715+ 'start_time_sec':npt2seconds( $j( clip ).attr( "start" ).replace( 'npt:', '' ) ),
 1716+ 'end_time_sec':npt2seconds( $j( clip ).attr( "end" ).replace( 'npt:', '' ) ),
 1717+ 'time_req':$j( clip ).attr( "start" ).replace( 'npt:', '' ) + '/' + $j( clip ).attr( "end" ).replace( 'npt:', '' )
 1718+ };
 1719+ // grab all its meta
 1720+ _this.cmmlData[ $j( clip ).attr( "id" ) ]['meta'] = { };
 1721+ $j.each( clip.getElementsByTagName( 'meta' ), function( imx, meta ) {
 1722+ // js_log('adding meta: '+ $j(meta).attr("name")+ ' = '+ $j(meta).attr("content"));
 1723+ _this.cmmlData[$j( clip ).attr( "id" )]['meta'][$j( meta ).attr( "name" )] = $j( meta ).attr( "content" );
 1724+ } );
 1725+ } );
 1726+ _this.showNextPrevLinks();
 1727+ } );
 1728+ }
 1729+ // query current request time +|- 60s to get prev next speech links.
 1730+ },
 1731+ showNextPrevLinks:function() {
 1732+ // js_log('f:showNextPrevLinks');
 1733+ // int requested links:
 1734+ var link = {
 1735+ 'prev':'',
 1736+ 'current':'',
 1737+ 'next':''
 1738+ }
 1739+ var curTime = this.getTimeRange().split( '/' );
 1740+ var s_sec = npt2seconds( curTime[0] );
 1741+ var e_sec = npt2seconds( curTime[1] );
 1742+ js_log( 'showNextPrevLinks: req time: ' + s_sec + ' to ' + e_sec );
 1743+ // now we have all the data in cmmlData
 1744+ var current_done = false;
 1745+ for ( var clip_id in this.cmmlData ) { // for in loop oky for object
 1746+ var clip = this.cmmlData[clip_id];
 1747+ // js_log('on clip:'+ clip_id);
 1748+ // set prev_link (if cur_link is still empty)
 1749+ if ( s_sec > clip.end_time_sec ) {
 1750+ link.prev = clip_id;
 1751+ js_log( 'showNextPrevLinks: ' + s_sec + ' < ' + clip.end_time_sec + ' set prev' );
 1752+ }
 1753+
 1754+ if ( e_sec == clip.end_time_sec && s_sec == clip.start_time_sec )
 1755+ current_done = true;
 1756+ // current clip is not done:
 1757+ if ( e_sec < clip.end_time_sec && link.current == '' && !current_done ) {
 1758+ link.current = clip_id;
 1759+ js_log( 'showNextPrevLinks: ' + e_sec + ' < ' + clip.end_time_sec + ' set current' );
 1760+ }
 1761+
 1762+ // set end clip (first clip where start time is > end_time of req
 1763+ if ( e_sec < clip.start_time_sec && link.next == '' ) {
 1764+ link.next = clip_id;
 1765+ js_log( 'showNextPrevLinks: ' + e_sec + ' < ' + clip.start_time_sec + ' && ' + link.next );
 1766+ }
 1767+ }
 1768+ var html = '';
 1769+ if ( link.prev == '' && link.current == '' && link.next == '' ) {
 1770+ html = '<p><a href="' + this.media_element.linkbackgetMsg + '">clip page</a>';
 1771+ } else {
 1772+ for ( var link_type in link ) {
 1773+ var link_id = link[link_type];
 1774+ if ( link_id != '' ) {
 1775+ var clip = this.cmmlData[link_id];
 1776+ var title_msg = '';
 1777+ for ( var j in clip['meta'] ) {
 1778+ title_msg += j.replace( /_/g, ' ' ) + ': ' + clip['meta'][j].replace( /_/g, ' ' ) + " <br>";
 1779+ }
 1780+ var time_req = clip.time_req;
 1781+ if ( link_type == 'current' ) // if current start from end of current clip play to end of current meta:
 1782+ time_req = curTime[1] + '/' + seconds2npt( clip.end_time_sec );
 1783+
 1784+ // do special linkbacks for metavid content:
 1785+ var regTimeCheck = new RegExp( /[0-9]+:[0-9]+:[0-9]+\/[0-9]+:[0-9]+:[0-9]+/ );
 1786+ html += '<p><a ';
 1787+ if ( regTimeCheck.test( this.media_element.linkback ) ) {
 1788+ html += ' href="' + this.media_element.linkback.replace( regTimeCheck, time_req ) + '" ';
 1789+ } else {
 1790+ html += ' href="#" onClick="$j(\'#' + this.id + '\').get(0).playByTimeReq(\'' +
 1791+ time_req + '\'); return false; "';
 1792+ }
 1793+ html += ' title="' + title_msg + '">' +
 1794+ gM( 'mwe-' + link_type + '_clip_msg' ) +
 1795+ '</a><br><span style="font-size:small">' + title_msg + '<span></p>';
 1796+ }
 1797+ }
 1798+ }
 1799+ // js_og("should set html:"+ html);
 1800+ $j( '#liks_info_' + this.id ).html( html );
 1801+ },
 1802+ playByTimeReq: function( time_req ) {
 1803+ js_log( 'f:playByTimeReq: ' + time_req );
 1804+ this.stop();
 1805+ this.updateVideoTimeReq( time_req );
 1806+ this.play();
 1807+ },
 1808+ doThumbnailHTML:function() {
 1809+ var _this = this;
 1810+ js_log( 'f:doThumbnailHTML' + this.thumbnail_disp );
 1811+ this.closeDisplayedHTML();
 1812+ $j( '#mv_embedded_player_' + this.id ).html( this.getThumbnailHTML() );
 1813+ this.paused = true;
 1814+ this.thumbnail_disp = true;
 1815+ // make sure the ctrlBuilder remain active:
 1816+ this.ctrlBuilder.addControlHooks();
 1817+ },
 1818+ refreshControlsHTML:function() {
 1819+ if ( $j( '#' + this.id + ' .control-bar' ).length == 0 ) {
 1820+ js_log( 'refreshControlsHTML::control-bar not present, no refresh' );
 1821+ return ;
 1822+ }
 1823+ // Do update controls:
 1824+ $j( '#' + this.id + ' .control-bar' ).html( this.getControlsHTML() );
 1825+ this.ctrlBuilder.addControlHooks();
 1826+
 1827+ },
 1828+ getControlsHTML:function() {
 1829+ return this.ctrlBuilder.getControls( this );
 1830+ },
 1831+ getHTML : function () {
 1832+ // set-up the local ctrlBuilder instance:
 1833+ this.ctrlBuilder = new ctrlBuilder( this );
 1834+
 1835+ var _this = this;
 1836+ var html_code = '';
 1837+ html_code = '<div id="videoPlayer_' + this.id + '" style="width:' + this.width + 'px;position:relative;"' +
 1838+ 'class="' + this.ctrlBuilder.parentClass + '">';
 1839+ html_code += '<div style="width:' + parseInt( this.width ) + 'px;height:' + parseInt( this.height ) + 'px;" id="mv_embedded_player_' + this.id + '">' +
 1840+ this.getThumbnailHTML() +
 1841+ '</div>';
 1842+
 1843+ // js_log("mvEmbed:controls "+ typeof this.controls);
 1844+ if ( this.controls ) {
 1845+ js_log( "f:getHTML:AddControls" );
 1846+ html_code += '<div class="ui-state-default ui-widget-header ui-helper-clearfix control-bar" >';
 1847+ html_code += this.getControlsHTML();
 1848+ html_code += '</div>';
 1849+ // block out some space by encapsulating the top level div
 1850+ $j( this ).wrap( '<div style="width:' + parseInt( this.width ) + 'px;height:'
 1851+ + ( parseInt( this.height ) + this.ctrlBuilder.height ) + 'px"></div>' );
 1852+ }
 1853+
 1854+ html_code += '</div>'; // videoPlayer div close
 1855+
 1856+ // js_log('should set: '+this.id);
 1857+ $j( this ).html( html_code );
 1858+
 1859+ // Add hooks once Controls are in DOM
 1860+ this.ctrlBuilder.addControlHooks();
 1861+
 1862+
 1863+ if ( this.autoplay ) {
 1864+ js_log( 'getHTML::activating autoplay' );
 1865+ this.play();
 1866+ }
 1867+ },
 1868+ /**
 1869+ * get missing plugin html (check for user included code)
 1870+ * @param {String} misssing_type missing type mime
 1871+ */
 1872+ getPluginMissingHTML : function( missing_type ) {
 1873+ // keep the box width hight:
 1874+ var out = '<div style="width:' + this.width + 'px;height:' + this.height + 'px">';
 1875+ if ( this.user_missing_plugin_html ) {
 1876+ out += this.user_missing_plugin_html;
 1877+ } else {
 1878+ if ( !missing_type )
 1879+ missing_type = '';
 1880+ out += gM( 'mwe-generic_missing_plugin', missing_type ) + '<br><a title="' + gM( 'mwe-download_clip' ) + '" href="' + this.src + '">' + gM( 'mwe-download_clip' ) + '</a>';
 1881+ }
 1882+ return out + '</div>';
 1883+ },
 1884+ updateVideoTimeReq:function( time_req ) {
 1885+ js_log( 'f:updateVideoTimeReq' );
 1886+ var time_parts = time_req.split( '/' );
 1887+ this.updateVideoTime( time_parts[0], time_parts[1] );
 1888+ },
 1889+ /**
 1890+ * Update Video time from provided start_npt and end_npt values
 1891+ *
 1892+ * @param {String} start_npt the new start time in npt format
 1893+ * @pamra {String} end_npt the new end time in npt format
 1894+ */
 1895+ updateVideoTime:function( start_npt, end_npt ) {
 1896+ // update media
 1897+ this.media_element.updateSourceTimes( start_npt, end_npt );
 1898+
 1899+ // update mv_time
 1900+ this.setStatus( start_npt + '/' + end_npt );
 1901+
 1902+ // reset slider
 1903+ this.setSliderValue( 0 );
 1904+
 1905+ // reset seek_offset:
 1906+ if ( this.media_element.selected_source.URLTimeEncoding )
 1907+ this.seek_time_sec = 0;
 1908+ else
 1909+ this.seek_time_sec = npt2seconds( start_npt );
 1910+ },
 1911+ // Should overwrite by embed library if we can render frames natively
 1912+ renderTimelineThumbnail:function( options ) {
 1913+ var my_thumb_src = this.media_element.getThumbnailURL();
 1914+ // check if our thumbnail has a time attribute:
 1915+ if ( my_thumb_src.indexOf( 't=' ) !== -1 ) {
 1916+ var time_ntp = seconds2npt ( options.time + parseInt( this.start_offset ) );
 1917+ my_thumb_src = getURLParamReplace( my_thumb_src, {
 1918+ 't' : time_ntp,
 1919+ 'size' : options.size
 1920+ });
 1921+ }
 1922+ var thumb_class = ( typeof options['thumb_class'] != 'undefined' ) ? options['thumb_class'] : '';
 1923+ return '<div class="ui-corner-all ' + thumb_class + '" src="' + my_thumb_src + '" ' +
 1924+ 'style="height:' + options.height + 'px;' +
 1925+ 'width:' + options.width + 'px" >' +
 1926+ '<img src="' + my_thumb_src + '" ' +
 1927+ 'style="height:' + options.height + 'px;' +
 1928+ 'width:' + options.width + 'px">' +
 1929+ '</div>';
 1930+ },
 1931+ updateThumbTimeNPT:function( time ) {
 1932+ this.updateThumbTime( npt2seconds( time ) - parseInt( this.start_offset ) );
 1933+ },
 1934+ updateThumbTime:function( float_sec ) {
 1935+ // js_log('updateThumbTime:'+float_sec);
 1936+ var _this = this;
 1937+ if ( typeof this.org_thum_src == 'undefined' ) {
 1938+ this.org_thum_src = this.media_element.getThumbnailURL();
 1939+ }
 1940+ if ( this.org_thum_src.indexOf( 't=' ) !== -1 ) {
 1941+ this.last_thumb_url = getURLParamReplace( this.org_thum_src,
 1942+ {
 1943+ 't' : seconds2npt( float_sec + parseInt( this.start_offset ) )
 1944+ }
 1945+ );
 1946+ if ( !this.thumbnail_updating ) {
 1947+ this.updateThumbnail( this.last_thumb_url , false );
 1948+ this.last_thumb_url = null;
 1949+ }
 1950+ }
 1951+ },
 1952+ updateThumbPerc:function( perc ) {
 1953+ return this.updateThumbTime( ( this.getDuration() * perc ) );
 1954+ },
 1955+ // Updates the thumbnail if the thumbnail is being displayed
 1956+ updateThumbnail : function( src, quick_switch ) {
 1957+ // make sure we don't go to the same url if we are not already updating:
 1958+ if ( !this.thumbnail_updating && $j( '#img_thumb_' + this.id ).attr( 'src' ) == src )
 1959+ return false;
 1960+ // if we are already updating don't issue a new update:
 1961+ if ( this.thumbnail_updating && $j( '#new_img_thumb_' + this.id ).attr( 'src' ) == src )
 1962+ return false;
 1963+
 1964+ js_log( 'update thumb: ' + src );
 1965+
 1966+ if ( quick_switch ) {
 1967+ $j( '#img_thumb_' + this.id ).attr( 'src', src );
 1968+ } else {
 1969+ var _this = this;
 1970+ // if still animating remove new_img_thumb_
 1971+ if ( this.thumbnail_updating == true )
 1972+ $j( '#new_img_thumb_' + this.id ).stop().remove();
 1973+
 1974+ if ( this.thumbnail_disp ) {
 1975+ js_log( 'set to thumb:' + src );
 1976+ this.thumbnail_updating = true;
 1977+ $j( '#dc_' + this.id ).append( '<img src="' + src + '" ' +
 1978+ 'style="display:none;position:absolute;zindex:2;top:0px;left:0px;" ' +
 1979+ 'width="' + this.width + '" height="' + this.height + '" ' +
 1980+ 'id = "new_img_thumb_' + this.id + '" />' );
 1981+ // js_log('appended: new_img_thumb_');
 1982+ $j( '#new_img_thumb_' + this.id ).fadeIn( "slow", function() {
 1983+ // once faded in remove org and rename new:
 1984+ $j( '#img_thumb_' + _this.id ).remove();
 1985+ $j( '#new_img_thumb_' + _this.id ).attr( 'id', 'img_thumb_' + _this.id );
 1986+ $j( '#img_thumb_' + _this.id ).css( 'zindex', '1' );
 1987+ _this.thumbnail_updating = false;
 1988+ // js_log("done fadding in "+ $j('#img_thumb_'+_this.id).attr("src"));
 1989+
 1990+ // if we have a thumb queued update to that
 1991+ if ( _this.last_thumb_url ) {
 1992+ var src_url = _this.last_thumb_url;
 1993+ _this.last_thumb_url = null;
 1994+ _this.updateThumbnail( src_url );
 1995+ }
 1996+ } );
 1997+ }
 1998+ }
 1999+ },
 2000+ /**
 2001+ * Returns the HTML code for the video when it is in thumbnail mode.
 2002+ * This includes the specified thumbnail as well as buttons for
 2003+ * playing, configuring the player, inline cmml display, HTML linkback,
 2004+ * download, and embed code.
 2005+ */
 2006+ getThumbnailHTML : function () {
 2007+ js_log( 'embedPlayer:getThumbnailHTML::' + this.id );
 2008+ var thumb_html = '';
 2009+ var class_atr = '';
 2010+ var style_atr = '';
 2011+ // if(this.class)class_atr = ' class="'+this.class+'"';
 2012+ // if(this.style)style_atr = ' style="'+this.style+'"';
 2013+ // else style_atr = 'overflow:hidden;height:'+this.height+'px;width:'+this.width+'px;';
 2014+ this.thumbnail = this.media_element.getThumbnailURL();
 2015+
 2016+ // put it all in the div container dc_id
 2017+ thumb_html += '<div id="dc_' + this.id + '" style="position:absolute;' +
 2018+ ' overflow:hidden; top:0px; left:0px; width:' + this.playerPixelWidth() + 'px; height:' + this.playerPixelHeight() + 'px; z-index:0;">' +
 2019+ '<img width="' + this.playerPixelWidth() + '" height="' + this.playerPixelHeight() + '" style="position:relative;width:' + this.playerPixelWidth() + ';height:' + this.playerPixelHeight() + '"' +
 2020+ ' id="img_thumb_' + this.id + '" src="' + this.thumbnail + '">';
 2021+
 2022+ if ( this.play_button == true && this.controls == true )
 2023+ thumb_html += this.ctrlBuilder.getComponent( 'play-btn-large' );
 2024+
 2025+ thumb_html += '</div>';
 2026+ return thumb_html;
 2027+ },
 2028+ getEmbeddingHTML:function() {
 2029+ var thumbnail = this.media_element.getThumbnailURL();
 2030+
 2031+ var embed_thumb_html;
 2032+ if ( thumbnail.substring( 0, 1 ) == '/' ) {
 2033+ eURL = mw.parseUri( mv_embed_path );
 2034+ embed_thumb_url = eURL.protocol + '://' + eURL.host + thumbnail;
 2035+ // js_log('set from mv_embed_path:'+embed_thumb_html);
 2036+ } else {
 2037+ embed_thumb_url = ( thumbnail.indexOf( 'http://' ) != -1 ) ? thumbnail:mv_embed_path + thumbnail;
 2038+ }
 2039+ var embed_code_html = '&lt;script type=&quot;text/javascript&quot; ' +
 2040+ 'src=&quot;' + mv_embed_path + 'mv_embed.js&quot;&gt;&lt;/script&gt' +
 2041+ '&lt;video ';
 2042+ if ( this.roe ) {
 2043+ embed_code_html += 'roe=&quot;' + escape( this.roe ) + '&quot; ';
 2044+ } else {
 2045+ embed_code_html += 'src=&quot;' + this.src + '&quot; ' +
 2046+ 'poster=&quot;' + escape( embed_thumb_url ) + '&quot; ';
 2047+ }
 2048+
 2049+ // Add in the wikiTitle key if provided
 2050+ // (in the future we should just include the titleKey on remote embeds
 2051+ // and query a roe like xml/json representaiton thing from mediawiki)
 2052+ if ( this.wikiTitleKey ) {
 2053+ embed_code_html += 'wikiTitleKey=&quot;' + escape( this.wikiTitleKey ) + '&quot;';
 2054+ }
 2055+
 2056+ // close the video tag
 2057+ embed_code_html += '&gt;&lt;/video&gt;';
 2058+
 2059+ return embed_code_html;
 2060+ },
 2061+ doOptionsHTML:function() {
 2062+ var sel_id = ( this.pc != null ) ? this.pc.pp.id:this.id;
 2063+ var pos = $j( '#' + sel_id + ' .options-btn' ).offset();
 2064+ pos['top'] = pos['top'] + 24;
 2065+ pos['left'] = pos['left'] -124;
 2066+ // js_log('pos of options button: t:'+pos['top']+' l:'+ pos['left']);
 2067+ $j( '#mv_vid_options_' + sel_id ).css( pos ).toggle();
 2068+ return;
 2069+ },
 2070+ doLinkBack:function() {
 2071+ if ( this.roe && this.media_element.addedROEData == false ) {
 2072+ var _this = this;
 2073+ this.displayHTML( gM( 'mwe-loading_txt' ) );
 2074+ do_request( this.roe, function( data ) {
 2075+ _this.media_element.addROE( data );
 2076+ _this.doLinkBack();
 2077+ } );
 2078+ } else {
 2079+ if ( this.linkback ) {
 2080+ window.location = this.linkback;
 2081+ } else if ( this.media_element.linkback ) {
 2082+ window.location = this.media_element.linkback;
 2083+ } else {
 2084+ this.displayHTML( gM( 'mwe-could_not_find_linkback' ) );
 2085+ }
 2086+ }
 2087+ },
 2088+ showShare:function( $target ) {
 2089+ var embed_code = this.getEmbeddingHTML();
 2090+ var o = '';
 2091+ var _this = this;
 2092+ // @todo: hook events to two a's for swapping in and out code for link vs. embed;
 2093+ // hook events for changing active class of li based on a.
 2094+ var o = '';
 2095+ o += '<h2>' + gM( 'mwe-share_this_video' ) + '</h2>' +
 2096+ '<ul>' +
 2097+ '<li><a href="#" class="active">' + gM( 'mwe-embed_site_or_blog' ) + '</a></li>';
 2098+ if ( this.linkback )
 2099+ o += '<li><a href="#" id="k-share-link">' + this.linkback + '</a></li>';
 2100+ o +='</ul>' +
 2101+ '<div class="source_wrap">'+
 2102+ '<textarea>' + embed_code + '</textarea>'+
 2103+ '</div>' +
 2104+ '<button class="ui-state-default ui-corner-all copycode">' + gM( 'mwe-copy-code' ) + '</button>' +
 2105+ '<div class="ui-state-highlight ui-corner-all">' +
 2106+ gM( 'mwe-read_before_embed' ) +
 2107+ '</div>';
 2108+ $target.html( o );
 2109+ $cpBtn = $j( '#' + this.id + ' .copycode' );
 2110+ $cpTxt = $j( '#' + this.id + ' .source_wrap textarea' );
 2111+
 2112+ $cpTxt.click( function() {
 2113+ $j( this ).get( 0 ).select();
 2114+ } );
 2115+
 2116+ // add copy binding:
 2117+ $cpBtn.click( function() {
 2118+ $cpTxt.focus().get( 0 ).select();
 2119+ if ( document.selection ) {
 2120+ CopiedTxt = document.selection.createRange();
 2121+ CopiedTxt.execCommand( "Copy" );
 2122+ }
 2123+ } );
 2124+ },
 2125+ showTextInterface:function() {
 2126+ var _this = this;
 2127+ if( $j( '#metaBox_' + this.id ).is( ':visible' ) ) {
 2128+ $j( '#metaBox_' + this.id ).fadeOut("fast");
 2129+ }else{
 2130+ $j( '#metaBox_' + this.id ).fadeIn( "fast" );
 2131+ }
 2132+ // display the text container with loading text:
 2133+ // @@todo support position config
 2134+ var loc = $j( this ).position();
 2135+ if ( $j( '#metaBox_' + this.id ).length == 0 ) {
 2136+ var theight = ( ( parseInt( this.height ) + this.ctrlBuilder.height ) < 200 ) ? 200 : ( parseInt( this.height ) + this.ctrlBuilder.height );
 2137+ $j( this ).after( '<div class="ui-widget ui-widget-content ui-corner-all" style="position:absolute;z-index:10;' +
 2138+ 'top:' + ( loc.top ) + 'px;' +
 2139+ 'left:' + ( parseInt( loc.left ) + parseInt( this.width ) + 10) + 'px;' +
 2140+ 'height:' + theight + 'px;width:400px;' +
 2141+ 'display:none;" ' +
 2142+ 'id="metaBox_' + this.id + '">' +
 2143+ mv_get_loading_img() +
 2144+ '</div>' );
 2145+ }
 2146+ // check if textObj present:
 2147+ if ( typeof this.textInterface == 'undefined' ) {
 2148+ // load the default text interface:
 2149+ mvJsLoader.doLoad( [
 2150+ 'mvTextInterface',
 2151+ '$j.fn.hoverIntent'
 2152+ ], function() {
 2153+ _this.textInterface = new mvTextInterface( _this );
 2154+ // show interface
 2155+ _this.textInterface.show();
 2156+ }
 2157+ );
 2158+ } else {
 2159+ // show interface
 2160+ this.textInterface.show();
 2161+ }
 2162+ },
 2163+ closeTextInterface:function() {
 2164+ js_log( 'closeTextInterface ' + typeof this.textInterface );
 2165+ if ( typeof this.textInterface !== 'undefined' ) {
 2166+ this.textInterface.close();
 2167+ }
 2168+ },
 2169+ /**
 2170+ * Generic function to display custom HTML inside the mv_embed element.
 2171+ * The code should call the closeDisplayedHTML function to close the
 2172+ * display of the custom HTML and restore the regular mv_embed display.
 2173+ * @param {String} html_code code for the selection list.
 2174+ */
 2175+ displayHTML:function( html_code )
 2176+ {
 2177+ var sel_id = ( this.pc != null ) ? this.pc.pp.id:this.id;
 2178+
 2179+ if ( !this.supports['overlays'] )
 2180+ this.stop();
 2181+
 2182+ // put select list on-top
 2183+ // make sure the parent is relatively positioned:
 2184+ $j( '#' + sel_id ).css( 'position', 'relative' );
 2185+ // set height width (check for playlist container)
 2186+ var width = ( this.pc ) ? this.pc.pp.width:this.playerPixelWidth();
 2187+ var height = ( this.pc ) ? this.pc.pp.height:this.playerPixelHeight();
 2188+
 2189+ if ( this.pc )
 2190+ height += ( this.pc.pp.pl_layout.title_bar_height + this.pc.pp.pl_layout.control_height );
 2191+
 2192+ var fade_in = true;
 2193+ if ( $j( '#blackbg_' + sel_id ).length != 0 )
 2194+ {
 2195+ fade_in = false;
 2196+ $j( '#blackbg_' + sel_id ).remove();
 2197+ }
 2198+ // fade in a black bg div ontop of everything
 2199+ var div_code = '<div id="blackbg_' + sel_id + '" class="videoComplete" ' +
 2200+ 'style="height:' + parseInt( height ) + 'px;width:' + parseInt( width ) + 'px;">' +
 2201+ '<span style="float:right;margin-right:10px">' +
 2202+ '<a href="#" style="color:white;" onClick="$j(\'#' + sel_id + '\').get(0).closeDisplayedHTML();return false;">close</a>' +
 2203+ '</span>' +
 2204+ '<div class="videoOptionsComplete">' +
 2205+ '</div>'+
 2206+ '</div>';
 2207+ $j( '#' + sel_id ).prepend( div_code );
 2208+ if ( fade_in )
 2209+ $j( '#blackbg_' + sel_id ).fadeIn( "slow" );
 2210+ else
 2211+ $j( '#blackbg_' + sel_id ).show();
 2212+ return false; // onclick action return false
 2213+ },
 2214+ /**
 2215+ * Close the custom HTML displayed using displayHTML and restores the
 2216+ * regular mv_embed display.
 2217+ */
 2218+ closeDisplayedHTML:function() {
 2219+ var sel_id = ( this.pc != null ) ? this.pc.pp.id:this.id;
 2220+ $j( '#blackbg_' + sel_id ).fadeOut( "slow", function() {
 2221+ $j( '#blackbg_' + sel_id ).remove();
 2222+ } );
 2223+ return false; // onclick action return false
 2224+ },
 2225+ showPlayerselect:function( $target ) {
 2226+ // Get id (in case where we have a parent container)
 2227+ var this_id = ( this.pc != null ) ? this.pc.pp.id:this.id;
 2228+ var _this = this;
 2229+ var o = '';
 2230+ o += '<h2>' + gM( 'mwe-chose_player' ) + '</h2>';
 2231+ var _this = this;
 2232+ $j.each( this.media_element.getPlayableSources(), function( source_id, source ) {
 2233+ var playable = embedTypes.players.defaultPlayer( source.getMIMEType() );
 2234+
 2235+ var is_selected = ( source == _this.media_element.selected_source );
 2236+ var image_src = mv_skin_img_path ;
 2237+
 2238+ o += '<h2>' + source.getTitle() + '</h2>';
 2239+
 2240+ if ( playable ) {
 2241+ o += '<ul>';
 2242+ // output the player select code:
 2243+ var supporting_players = embedTypes.players.getMIMETypePlayers( source.getMIMEType() );
 2244+
 2245+ for ( var i = 0; i < supporting_players.length ; i++ ) {
 2246+ if ( _this.selected_player.id == supporting_players[i].id && is_selected ) {
 2247+ o += '<li>' +
 2248+ '<a href="#" class="active" rel="sel_source" id="sc_' + source_id + '_' + supporting_players[i].id + '">' +
 2249+ supporting_players[i].getName() +
 2250+ '</li>';
 2251+ } else {
 2252+ o += '<li>' +
 2253+ '<a href="#" rel="sel_source" id="sc_' + source_id + '_' + supporting_players[i].id + '">' +
 2254+ supporting_players[i].getName() +
 2255+ '</a>' +
 2256+ '</li>';
 2257+ }
 2258+ }
 2259+ o += '</ul>';
 2260+ } else {
 2261+ o += source.getTitle() + ' - no player available';
 2262+ }
 2263+ } );
 2264+ $target.html( o );
 2265+
 2266+ // Set up the click bindings:
 2267+ $target.find( "[rel='sel_source']" ).each( function() {
 2268+ $j( this ).click( function() {
 2269+ var iparts = $j( this ).attr( 'id' ).replace(/sc_/ , '' ).split( '_' );
 2270+ var source_id = iparts[0];
 2271+ var default_player_id = iparts[1];
 2272+ js_log( 'source id: ' + source_id + ' player id: ' + default_player_id );
 2273+
 2274+ $j( '#' + this_id ).get( 0 ).closeDisplayedHTML();
 2275+ $j( '#' + _this.id ).get( 0 ).media_element.selectSource( source_id );
 2276+
 2277+ embedTypes.players.userSelectPlayer( default_player_id,
 2278+ _this.media_element.sources[ source_id ].getMIMEType() );
 2279+
 2280+ // Issue a stop
 2281+ $j( '#' + this_id ).get( 0 ).stop();
 2282+
 2283+ // Don't follow the empty # link:
 2284+ return false;
 2285+ } );
 2286+ } );
 2287+ },
 2288+ showDownload:function( $target ) {
 2289+ var _this = this;
 2290+ // Load the roe if available (to populate out download options:
 2291+ function getShowVideoDownload() {
 2292+ var out = '<div style="color:white">';
 2293+ var dl_list = '';
 2294+ var dl_txt_list = '';
 2295+ $j.each( _this.media_element.getSources(), function( index, source ) {
 2296+ var dl_line = '<li>' + '<a style="color:white" href="' + source.getURI() + '"> '
 2297+ + source.getTitle() + '</a> ' + '</li>' + "\n";
 2298+ if ( source.getURI().indexOf( '?t=' ) !== -1 ) {
 2299+ out += dl_line;
 2300+ } else if ( this.getMIMEType() == "text/cmml" || this.getMIMEType() == "text/x-srt" ) {
 2301+ dl_txt_list += dl_line;
 2302+ } else {
 2303+ dl_list += dl_line;
 2304+ }
 2305+ } );
 2306+
 2307+ if ( dl_list != '' )
 2308+ out += '<h2>' + gM( 'mwe-download_full' ) + '</h2><ul>' + dl_list + '</ul>';
 2309+ if ( dl_txt_list != '' )
 2310+ out += '<h2>' +gM( 'mwe-download_text' ) + '</h2><ul>' + dl_txt_list + '</ul>';
 2311+ out += '</div>';
 2312+ return out;
 2313+ }
 2314+ // js_log('f:showDownload '+ this.roe + ' ' + this.media_element.addedROEData);
 2315+ if ( this.roe && this.media_element.addedROEData == false ) {
 2316+ var _this = this;
 2317+ $target.html( gM( 'loading_txt' ) );
 2318+ do_request( this.roe, function( data ) {
 2319+ _this.media_element.addROE( data );
 2320+ $target.html( getShowVideoDownload() );
 2321+ } );
 2322+ } else {
 2323+ $target.html( getShowVideoDownload() );
 2324+ }
 2325+ },
 2326+ /*
 2327+ * Base embed controls
 2328+ * The Play Action:
 2329+ */
 2330+ play : function() {
 2331+ var eid = ( this.pc != null ) ? this.pc.pp.id:this.id;
 2332+
 2333+ // check if thumbnail is being displayed and embed html
 2334+ if ( this.thumbnail_disp ) {
 2335+ if ( !this.selected_player ) {
 2336+ js_log( 'no selected_player' );
 2337+ // this.innerHTML = this.getPluginMissingHTML();
 2338+ $j( '#' + this.id ).html( this.getPluginMissingHTML() );
 2339+ } else {
 2340+ this.doEmbedHTML();
 2341+ this.paused = false;
 2342+ this.thumbnail_disp = false;
 2343+ }
 2344+ } else {
 2345+ // the plugin is already being displayed
 2346+ this.paused = false; // make sure we are not "paused"
 2347+ this.seeking = false;
 2348+ }
 2349+
 2350+ $j( '#' + eid + ' .play-btn span' ).removeClass( 'ui-icon-play' ).addClass( 'ui-icon-pause' );
 2351+ $j( '#' + eid + ' .play-btn' ).unbind().btnBind().click( function() {
 2352+ $j( '#' + eid ).get( 0 ).pause();
 2353+ } ).attr( 'title', gM( 'mwe-pause_clip' ) );
 2354+
 2355+ },
 2356+ load:function() {
 2357+ // should be done by child (no base way to pre-buffer video)
 2358+ js_log( 'baseEmbed:load call' );
 2359+ },
 2360+ getSrc:function() {
 2361+ return this.media_element.selected_source.getURI( this.seek_time_sec );
 2362+ },
 2363+ /*
 2364+ * Base embed pause
 2365+ * there is no general way to pause the video
 2366+ * must be overwritten by embed object to support this functionality.
 2367+ */
 2368+ pause: function() {
 2369+ var _this = this;
 2370+ var eid = ( this.pc != null ) ? this.pc.pp.id:this.id;
 2371+ // js_log('mv_embed:do pause');
 2372+ // (playing) do pause
 2373+ this.paused = true;
 2374+ var $pt = $j( '#' + eid);
 2375+ // update the ctrl "paused state"
 2376+ $pt.find('.play-btn span' ).removeClass( 'ui-icon-pause' ).addClass( 'ui-icon-play' );
 2377+ $pt.find('.play-btn' ).unbind().btnBind().click( function() {
 2378+ _this.play();
 2379+ } ).attr( 'title', gM( 'mwe-play_clip' ) );
 2380+ },
 2381+ /**
 2382+ * Base embed stop (can be overwritten by the plugin)
 2383+ */
 2384+ stop: function() {
 2385+ var _this = this;
 2386+ js_log( 'mvEmbed:stop:' + this.id );
 2387+
 2388+ // no longer seeking:
 2389+ this.didSeekJump = false;
 2390+
 2391+ // first issue pause to update interface (only call the parent)
 2392+ if ( this['parent_pause'] ) {
 2393+ this.parent_pause();
 2394+ } else {
 2395+ this.pause();
 2396+ }
 2397+
 2398+ // reset the currentTime:
 2399+ this.currentTime = 0;
 2400+ // check if thumbnail is being displayed in which case do nothing
 2401+ if ( this.thumbnail_disp ) {
 2402+ // already in stooped state
 2403+ js_log( 'already in stopped state' );
 2404+ } else {
 2405+ // rewrite the html to thumbnail disp
 2406+ this.doThumbnailHTML();
 2407+ this.bufferedPercent = 0; // reset buffer state
 2408+ this.setSliderValue( 0 );
 2409+ this.setStatus( this.getTimeRange() );
 2410+ }
 2411+
 2412+ //Bind play-btn-large play
 2413+ $j( '#' + _this.id + ' .play-btn-large' ).unbind( 'click' ).click( function() {
 2414+ $j( '#' + _this.id ).get( 0 ).play();
 2415+ } );
 2416+
 2417+ if ( this.update_interval )
 2418+ {
 2419+ clearInterval( this.update_interval );
 2420+ this.update_interval = null;
 2421+ }
 2422+ },
 2423+ toggleMute:function() {
 2424+ var eid = ( this.pc != null ) ? this.pc.pp.id:this.id;
 2425+ if ( this.muted ) {
 2426+ this.muted = false;
 2427+ $j( '#' + eid + ' .volume-slider' ).slider( 'value', 100 );
 2428+ this.updateVolumen( 1 );
 2429+ } else {
 2430+ this.muted = true;
 2431+ $j( '#' + eid + ' .volume-slider' ).slider( 'value', 0 );
 2432+ this.updateVolumen( 0 );
 2433+ }
 2434+ js_log( 'f:toggleMute::' + this.muted );
 2435+ },
 2436+ updateVolumen:function( perc ) {
 2437+ js_log( 'update volume not supported with current playback type' );
 2438+ },
 2439+ fullscreen:function() {
 2440+ js_log( 'fullscreen not supported with current playback type' );
 2441+ },
 2442+ /**
 2443+ * returns bool true if playing or paused, false if stooped
 2444+ */
 2445+ isPlaying : function() {
 2446+ if ( this.thumbnail_disp ) {
 2447+ // in stoped state
 2448+ return false;
 2449+ } else if ( this.paused ) {
 2450+ // paused state
 2451+ return false;
 2452+ } else {
 2453+ return true;
 2454+ }
 2455+ },
 2456+ isPaused : function() {
 2457+ return this.isPlaying() && this.paused;
 2458+ },
 2459+ isStoped : function() {
 2460+ return this.thumbnail_disp;
 2461+ },
 2462+ playlistSupport:function() {
 2463+ // by default not supported (implemented in js)
 2464+ return false;
 2465+ },
 2466+ postEmbedJS:function() {
 2467+ return '';
 2468+ },
 2469+ /*
 2470+ * Monitor playback and update interface components.
 2471+ * underling plugin objects are responsible for updating currentTime
 2472+ */
 2473+ monitor:function() {
 2474+ var _this = this;
 2475+ //js_log(' ct: ' + this.currentTime + ' dur: ' + ( parseInt( this.duration ) + 1 ) + ' is seek: ' + this.seeking );
 2476+ if ( this.currentTime && this.currentTime > 0 && this.duration ) {
 2477+ if ( !this.userSlide && !this.seeking ) {
 2478+ if ( this.start_offset ) {
 2479+ // If start offset include that calculation
 2480+ this.setSliderValue( ( this.currentTime - this.start_offset ) / this.duration );
 2481+ var et = ( this.ctrlBuilder.long_time_disp ) ? '/' + seconds2npt( parseFloat( this.start_offset ) + parseFloat( this.duration ) ) : '';
 2482+ this.setStatus( seconds2npt( this.currentTime ) + et );
 2483+ } else {
 2484+ this.setSliderValue( this.currentTime / this.duration );
 2485+ var et = ( this.ctrlBuilder.long_time_disp ) ? '/' + seconds2npt( this.duration ):'';
 2486+ this.setStatus( seconds2npt( this.currentTime ) + et );
 2487+ }
 2488+ }
 2489+ // Check if we are "done"
 2490+ var end_presentation_time = parseFloat( this.startOffset) + parseFloat( this.duration ) ;
 2491+ if ( this.currentTime > end_presentation_time ) {
 2492+ js_log( "should run clip done ct:: " + this.currentTime + ' > ' + end_presentation_time );
 2493+ this.onClipDone();
 2494+ }
 2495+ } else {
 2496+ // Media lacks duration just show end time
 2497+ // js_log(' ct:' + this.currentTime + ' dur: ' + this.duration);
 2498+ if ( this.isStoped() ) {
 2499+ this.setStatus( this.getTimeRange() );
 2500+ } else if ( this.isPaused() ) {
 2501+ this.setStatus( gM( 'mwe-paused' ) );
 2502+ } else if ( this.isPlaying() ) {
 2503+ if ( this.currentTime && ! this.duration )
 2504+ this.setStatus( seconds2npt( this.currentTime ) + ' /' );
 2505+ else
 2506+ this.setStatus( " - - - " );
 2507+ } else {
 2508+ this.setStatus( this.getTimeRange() );
 2509+ }
 2510+ }
 2511+ // Update buffer information
 2512+ this.updateBufferStatus();
 2513+ // Update monitorTimerId to call child monitor
 2514+ if ( ! this.monitorTimerId ) {
 2515+ // Make sure an instance of this.id exists:
 2516+ if ( document.getElementById( this.id ) ) {
 2517+ this.monitorTimerId = setInterval( function() {
 2518+ if ( _this.id && $j( '#' + _this.id ).length != 0 ) {
 2519+ $j( '#' + _this.id ).get( 0 ).monitor();
 2520+ }
 2521+ }, 250 );
 2522+ }
 2523+ }
 2524+ },
 2525+ stopMonitor:function() {
 2526+ if ( this.monitorTimerId != 0 )
 2527+ {
 2528+ clearInterval( this.monitorTimerId );
 2529+ this.monitorTimerId = 0;
 2530+ }
 2531+ },
 2532+ updateBufferStatus: function() {
 2533+
 2534+ // Build the buffer target based for playlist vs clip
 2535+ var buffer_select = ( this.pc ) ?
 2536+ '#cl_status_' + this.id + ' .mv_buffer':
 2537+ '#' + this.id + ' .play_head .mv_buffer';
 2538+
 2539+ // Update the buffer progress bar (if available )
 2540+ if ( this.bufferedPercent != 0 ) {
 2541+ // js_log('bufferedPercent: ' + this.bufferedPercent);
 2542+ if ( this.bufferedPercent > 1 )
 2543+ this.bufferedPercent = 1;
 2544+
 2545+ $j( buffer_select ).css( "width", ( this.bufferedPercent * 100 ) + '%' );
 2546+ } else {
 2547+ $j( buffer_select ).css( "width", '0px' );
 2548+ }
 2549+ },
 2550+ relativeCurrentTime: function() {
 2551+ if ( !this.start_offset )
 2552+ this.start_offset = 0;
 2553+ var rt = this.currentTime - this.start_offset;
 2554+ if ( rt < 0 ) // should not happen but does.
 2555+ return 0;
 2556+ return rt;
 2557+ },
 2558+ getPluginEmbed : function() {
 2559+ if ( window.document[this.pid] ) {
 2560+ return window.document[this.pid];
 2561+ }
 2562+ if ( $j.browser.msie ) {
 2563+ return document.getElementById( this.pid );
 2564+ } else {
 2565+ if ( document.embeds && document.embeds[this.pid] )
 2566+ return document.embeds[this.pid];
 2567+ }
 2568+ return null;
 2569+ },
 2570+ setSliderValue: function( perc, hide_progress ) {
 2571+ var eid = ( this.pc ) ? this.pc.pp.id:this.id;
 2572+ if ( this.controls && $j( '#' + eid + ' .play_head' ).length != 0 ) {
 2573+ var val = parseInt( perc * 1000 );
 2574+ $j( '#' + eid + ' .play_head' ).slider( 'value', val );
 2575+ }
 2576+ // js_log('set#mv_seeker_slider_'+eid + ' perc in: ' + perc + ' * ' + $j('#mv_seeker_'+eid).width() + ' = set to: '+ val + ' - '+ Math.round(this.mv_seeker_width*perc) );
 2577+ // js_log('op:' + offset_perc + ' *('+perc+' * ' + $j('#slider_'+id).width() + ')');
 2578+ },
 2579+ highlightPlaySection:function( options ) {
 2580+ js_log( 'highlightPlaySection' );
 2581+ var eid = ( this.pc ) ? this.pc.pp.id:this.id;
 2582+ var dur = this.getDuration();
 2583+ var hide_progress = true;
 2584+ // set the left percet and update the slider:
 2585+ rel_start_sec = npt2seconds( options['start'] );
 2586+ // remove the start_offset if relevent:
 2587+ if ( this.start_offset )
 2588+ rel_start_sec = rel_start_sec - this.start_offset
 2589+
 2590+ var slider_perc = 0;
 2591+ if ( rel_start_sec <= 0 ) {
 2592+ left_perc = 0;
 2593+ options['start'] = seconds2npt( this.start_offset );
 2594+ rel_start_sec = 0;
 2595+ this.setSliderValue( 0 , hide_progress );
 2596+ } else {
 2597+ left_perc = parseInt( ( rel_start_sec / dur ) * 100 ) ;
 2598+ slider_perc = ( left_perc / 100 );
 2599+ }
 2600+
 2601+ js_log( "slider perc:" + slider_perc );
 2602+ if ( ! this.isPlaying() ) {
 2603+ this.setSliderValue( slider_perc , hide_progress );
 2604+ }
 2605+
 2606+ width_perc = parseInt( ( ( npt2seconds( options['end'] ) - npt2seconds( options['start'] ) ) / dur ) * 100 ) ;
 2607+ if ( ( width_perc + left_perc ) > 100 ) {
 2608+ width_perc = 100 - left_perc;
 2609+ }
 2610+ // js_log('should hl: '+rel_start_sec+ '/' + dur + ' re:' + rel_end_sec+' lp:' + left_perc + ' width: ' + width_perc);
 2611+ $j( '#mv_seeker_' + eid + ' .mv_highlight' ).css( {
 2612+ 'left' : left_perc + '%',
 2613+ 'width' : width_perc + '%'
 2614+ } ).show();
 2615+
 2616+ this.jump_time = options['start'];
 2617+ this.seek_time_sec = npt2seconds( options['start'] );
 2618+ // trim output to
 2619+ this.setStatus( gM( 'mwe-seek_to', seconds2npt( this.seek_time_sec ) ) );
 2620+ js_log( 'DO update: ' + this.jump_time );
 2621+ this.updateThumbTime( rel_start_sec );
 2622+ },
 2623+ hideHighlight:function() {
 2624+ var eid = ( this.pc ) ? this.pc.pp.id:this.id;
 2625+ $j( '#mv_seeker_' + eid + ' .mv_highlight' ).hide();
 2626+ this.setStatus( this.getTimeReq() );
 2627+ thigetTimeRangerValue( 0 );
 2628+ },
 2629+ setStatus:function( value ) {
 2630+ var eid = ( this.pc ) ? this.pc.pp.id:this.id;
 2631+ // update status:
 2632+ $j( '#' + eid + ' .time-disp' ).html( value );
 2633+ },
 2634+ /**
 2635+ * Helper Functions for selected source
 2636+ */
 2637+ /*
 2638+ * returns the selected source url for players to play
 2639+ */
 2640+ getURI : function( seek_time_sec ) {
 2641+ return this.media_element.selected_source.getURI( this.seek_time_sec );
 2642+ },
 2643+ supportsURLTimeEncoding: function() {
 2644+ // do head request if on the same domain
 2645+ return this.media_element.selected_source.URLTimeEncoding;
 2646+ }
 2647+}
 2648+
 2649+
 2650+
 2651+/**
 2652+ * mediaPlayer represents a media player plugin.
 2653+ * @param {String} id id used for the plugin.
 2654+ * @param {Array<String>} supported_types n array of supported MIME types.
 2655+ * @param {String} library external script containing the plugin interface code. (mv_<library>Embed.js)
 2656+ * @constructor
 2657+ */
 2658+function mediaPlayer( id, supported_types, library )
 2659+{
 2660+ this.id = id;
 2661+ this.supported_types = supported_types;
 2662+ this.library = library;
 2663+ this.loaded = false;
 2664+ this.loading_callbacks = new Array();
 2665+ return this;
 2666+}
 2667+mediaPlayer.prototype =
 2668+{
 2669+ id:null,
 2670+ supported_types:null,
 2671+ library:null,
 2672+ loaded:false,
 2673+ loading_callbacks:null,
 2674+ supportsMIMEType : function( type )
 2675+ {
 2676+ for ( var i = 0; i < this.supported_types.length; i++ )
 2677+ if ( this.supported_types[i] == type )
 2678+ return true;
 2679+ return false;
 2680+ },
 2681+ getName : function()
 2682+ {
 2683+ return gM( 'mwe-ogg-player-' + this.id );
 2684+ },
 2685+ load : function( callback ) {
 2686+ mvJsLoader.doLoad( [
 2687+ this.library + 'Embed'
 2688+ ], function() {
 2689+ callback();
 2690+ } );
 2691+ }
 2692+}
 2693+/* players and supported mime types
 2694+@@note ideally we query the plugin to get what mime types it supports in practice not always reliable/avaliable
 2695+*/
 2696+//var flowPlayer = new mediaPlayer( 'flowplayer', ['video/x-flv', 'video/h264'], 'flowplayer' );
 2697+var kplayer = new mediaPlayer('kplayer', ['video/x-flv', 'video/h264'], 'kplayer');
 2698+
 2699+var omtkPlayer = new mediaPlayer( 'omtkplayer', ['audio/ogg'], 'omtk' );
 2700+
 2701+var cortadoPlayer = new mediaPlayer( 'cortado', ['video/ogg', 'audio/ogg'], 'java' );
 2702+var videoElementPlayer = new mediaPlayer( 'videoElement', ['video/ogg', 'audio/ogg'], 'native' );
 2703+
 2704+var vlcMineList = ['video/ogg', 'audio/ogg', 'video/x-flv', 'video/mp4', 'video/h264'];
 2705+var vlcPlayer = new mediaPlayer( 'vlc-player', vlcMineList, 'vlc' );
 2706+
 2707+// add generic
 2708+var oggPluginPlayer = new mediaPlayer( 'oggPlugin', ['video/ogg'], 'generic' );
 2709+
 2710+// depricate quicktime in favor of safari native
 2711+// var quicktimeMozillaPlayer = new mediaPlayer('quicktime-mozilla',['video/ogg'],'quicktime');
 2712+// var quicktimeActiveXPlayer = new mediaPlayer('quicktime-activex',['video/ogg'],'quicktime');
 2713+
 2714+var htmlPlayer = new mediaPlayer( 'html', ['text/html', 'image/jpeg', 'image/png', 'image/svg'], 'html' );
 2715+
 2716+/**
 2717+ * mediaPlayers is a collection of mediaPlayer objects supported by the client.
 2718+ * It could be merged with embedTypes, since there is one embedTypes per script
 2719+ * and one mediaPlayers per embedTypes.
 2720+ */
 2721+function mediaPlayers()
 2722+{
 2723+ this.init();
 2724+}
 2725+
 2726+mediaPlayers.prototype =
 2727+{
 2728+ players : null,
 2729+ preference : null,
 2730+ default_players : { },
 2731+ init : function() {
 2732+ this.players = new Array();
 2733+ this.loadPreferences();
 2734+
 2735+ // set up default players order for each library type
 2736+ this.default_players['video/x-flv'] = ['kplayer', 'vlc'];
 2737+ this.default_players['video/h264'] = ['kplayer', 'vlc'];
 2738+
 2739+ this.default_players['video/ogg'] = ['native', 'vlc', 'java', 'generic'];
 2740+ this.default_players['application/ogg'] = ['native', 'vlc', 'java', 'generic'];
 2741+ this.default_players['audio/ogg'] = ['native', 'vlc', 'java', 'omtk' ];
 2742+ this.default_players['video/mp4'] = ['vlc'];
 2743+
 2744+ this.default_players['text/html'] = ['html'];
 2745+ this.default_players['image/jpeg'] = ['html'];
 2746+ this.default_players['image/png'] = ['html'];
 2747+ this.default_players['image/svg'] = ['html'];
 2748+
 2749+ },
 2750+ addPlayer : function( player, mime_type ) {
 2751+ for ( var i = 0; i < this.players.length; i++ ) {
 2752+ if ( this.players[i].id == player.id ) {
 2753+ if ( mime_type != null ) {
 2754+ // make sure the mime_type is not already there:
 2755+ var add_mime = true;
 2756+ for ( var j = 0; j < this.players[i].supported_types.length; j++ ) {
 2757+ if ( this.players[i].supported_types[j] == mime_type )
 2758+ add_mime = false;
 2759+ }
 2760+ if ( add_mime )
 2761+ this.players[i].supported_types.push( mime_type );
 2762+ }
 2763+ return ;
 2764+ }
 2765+ }
 2766+ // Player not found:
 2767+ if ( mime_type != null )
 2768+ player.supported_types.push( mime_type );
 2769+
 2770+ js_log( 'Adding ' + player.id + ' with mime_type ' + mime_type );
 2771+ this.players.push( player );
 2772+ },
 2773+ getMIMETypePlayers : function( mime_type ) {
 2774+ var mime_players = new Array();
 2775+ var _this = this;
 2776+ var inx = 0;
 2777+ if ( this.default_players[mime_type] ) {
 2778+ $j.each( this.default_players[mime_type], function( d, lib ) {
 2779+ var library = _this.default_players[mime_type][d];
 2780+ for ( var i = 0; i < _this.players.length; i++ ) {
 2781+ if ( _this.players[i].library == library && _this.players[i].supportsMIMEType( mime_type ) ) {
 2782+ mime_players[ inx ] = _this.players[i];
 2783+ inx++;
 2784+ }
 2785+ }
 2786+ } );
 2787+ }
 2788+ return mime_players;
 2789+ },
 2790+ defaultPlayer : function( mime_type ) {
 2791+ js_log( "get defaultPlayer for " + mime_type );
 2792+ var mime_players = this.getMIMETypePlayers( mime_type );
 2793+ if ( mime_players.length > 0 )
 2794+ {
 2795+ // Check for prior preference for this mime type
 2796+ for ( var i = 0; i < mime_players.length; i++ ) {
 2797+ if ( mime_players[i].id == this.preference[mime_type] )
 2798+ return mime_players[i];
 2799+ }
 2800+ // Otherwise just return the first compatible player
 2801+ // (it will be chosen according to the default_players list
 2802+ return mime_players[0];
 2803+ }
 2804+ js_log( 'No default player found for ' + mime_type );
 2805+ return null;
 2806+ },
 2807+ userSelectFormat : function ( mime_format ) {
 2808+ this.preference['format_prefrence'] = mime_format;
 2809+ this.savePreferences();
 2810+ },
 2811+ userSelectPlayer : function( player_id, mime_type ) {
 2812+ var selected_player = null;
 2813+ for ( var i = 0; i < this.players.length; i++ ) {
 2814+ if ( this.players[i].id == player_id ) {
 2815+ selected_player = this.players[i];
 2816+ js_log( 'choosing ' + player_id + ' for ' + mime_type );
 2817+ this.preference[mime_type] = player_id;
 2818+ this.savePreferences();
 2819+ break;
 2820+ }
 2821+ }
 2822+ if ( selected_player ) {
 2823+ for ( var i = 0; i < mw.player_list.length; i++ ) {
 2824+ var embed = $j( '#' + mw.player_list[i] ).get( 0 );
 2825+ if ( embed.media_element.selected_source && ( embed.media_element.selected_source.mime_type == mime_type ) )
 2826+ {
 2827+ embed.selectPlayer( selected_player );
 2828+ js_log( 'using ' + embed.selected_player.getName() + ' for ' + embed.media_element.selected_source.getTitle() );
 2829+ }
 2830+ }
 2831+ }
 2832+ },
 2833+ loadPreferences : function()
 2834+ {
 2835+ this.preference = new Object();
 2836+ // see if we have a cookie set to a clientSupported type:
 2837+ var cookieVal = $j.cookie( 'ogg_player_exp' );
 2838+ if ( cookieVal ) {
 2839+ var pairs = cookieVal.split( '&' );
 2840+ for ( var i = 0; i < pairs.length; i++ )
 2841+ {
 2842+ var name_value = pairs[i].split( '=' );
 2843+ this.preference[name_value[0]] = name_value[1];
 2844+ // js_log('load preference for ' + name_value[0] + ' is ' + name_value[1]);
 2845+ }
 2846+ }
 2847+ },
 2848+ savePreferences : function() {
 2849+ var cookieVal = '';
 2850+ for ( var i in this.preference )
 2851+ cookieVal += i + '=' + this.preference[i] + '&';
 2852+
 2853+ cookieVal = cookieVal.substr( 0, cookieVal.length -1 );
 2854+ var week = 7 * 86400 * 1000;
 2855+ $j.cookie( 'ogg_player_exp', cookieVal, { 'expires':week } );
 2856+ }
 2857+};
 2858+
 2859+/*
 2860+ * embedTypes object handles setting and getting of supported embed types:
 2861+ * closely mirrors OggHandler so that its easier to share efforts in this area:
 2862+ * http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/OggHandler/OggPlayer.js
 2863+ */
 2864+var embedTypes = {
 2865+ // List of players
 2866+ players: null,
 2867+ detect_done:false,
 2868+ init: function() {
 2869+ // detect supported types
 2870+ this.detect();
 2871+ this.detect_done = true;
 2872+ },
 2873+ clientSupports: { 'thumbnail' : true },
 2874+ supportedMimeType: function( mimetype ) {
 2875+ for ( var i = navigator.plugins.length; i-- > 0; ) {
 2876+ var plugin = navigator.plugins[i];
 2877+ if ( typeof plugin[mimetype] != "undefined" )
 2878+ return true;
 2879+ }
 2880+ return false;
 2881+ },
 2882+
 2883+ detect: function() {
 2884+ js_log( "running detect" );
 2885+ this.players = new mediaPlayers();
 2886+ // every browser supports html rendering:
 2887+ this.players.addPlayer( htmlPlayer );
 2888+ // In Mozilla, navigator.javaEnabled() only tells us about preferences, we need to
 2889+ // search navigator.mimeTypes to see if it's installed
 2890+ var javaEnabled = navigator.javaEnabled();
 2891+ // Some browsers filter out duplicate mime types, hiding some plugins
 2892+ var uniqueMimesOnly = $j.browser.opera || $j.browser.safari;
 2893+ // Opera will switch off javaEnabled in preferences if java can't be found.
 2894+ // And it doesn't register an application/x-java-applet mime type like Mozilla does.
 2895+ if ( javaEnabled )
 2896+ this.players.addPlayer( cortadoPlayer );
 2897+
 2898+ // ActiveX plugins
 2899+ if ( $j.browser.msie ) {
 2900+ // check for flash
 2901+ if ( this.testActiveX( 'ShockwaveFlash.ShockwaveFlash' ) ) {
 2902+ // try to get the flash version for omtk include:
 2903+ try {
 2904+ a = new ActiveXObject( SHOCKWAVE_FLASH_AX + ".7" );
 2905+ d = a.GetVariable( "$version" ); // Will crash fp6.0.21/23/29
 2906+ if ( d ) {
 2907+ d = d.split( " " )[1].split( "," );
 2908+ // we need flash version 10 or greater:
 2909+ if ( parseInt( d[0] ) >= 10 ) {
 2910+ this.players.addPlayer( omtkPlayer );
 2911+ }
 2912+ }
 2913+ } catch ( e ) {
 2914+ // failed to check for flash
 2915+ }
 2916+ // flowplayer has pretty good compatiablity
 2917+ // (but if we wanted to be fancy we would check for version of flash and update the mp4/h.264 support
 2918+
 2919+ this.players.addPlayer( kplayer );
 2920+ //this.players.addPlayer( flowPlayer );
 2921+ }
 2922+ // VLC
 2923+ if ( this.testActiveX( 'VideoLAN.VLCPlugin.2' ) )
 2924+ this.players.addPlayer( vlcPlayer );
 2925+
 2926+ // Java ActiveX
 2927+ if ( this.testActiveX( 'JavaWebStart.isInstalled' ) )
 2928+ this.players.addPlayer( cortadoPlayer );
 2929+ // quicktime (currently off)
 2930+ // if ( this.testActiveX( 'QuickTimeCheckObject.QuickTimeCheck.1' ) )
 2931+ // this.players.addPlayer(quicktimeActiveXPlayer);
 2932+ }
 2933+ // <video> element
 2934+ if ( typeof HTMLVideoElement == 'object' // Firefox, Safari
 2935+ || typeof HTMLVideoElement == 'function' ) // Opera
 2936+ {
 2937+ // do another test for safari:
 2938+ if ( $j.browser.safari ) {
 2939+ try {
 2940+ var dummyvid = document.createElement( "video" );
 2941+ if ( dummyvid.canPlayType && dummyvid.canPlayType( "video/ogg;codecs=\"theora,vorbis\"" ) == "probably" )
 2942+ {
 2943+ this.players.addPlayer( videoElementPlayer );
 2944+ } else if ( this.supportedMimeType( 'video/ogg' ) ) {
 2945+ /* older versions of safari do not support canPlayType,
 2946+ but xiph qt registers mimetype via quicktime plugin */
 2947+ this.players.addPlayer( videoElementPlayer );
 2948+ } else {
 2949+ // @@todo add some user nagging to install the xiph qt
 2950+ }
 2951+ } catch ( e ) {
 2952+ js_log( 'could not run canPlayType in safari' );
 2953+ }
 2954+ } else {
 2955+ this.players.addPlayer( videoElementPlayer );
 2956+ }
 2957+ }
 2958+
 2959+ // "navigator" plugins
 2960+ if ( navigator.mimeTypes && navigator.mimeTypes.length > 0 ) {
 2961+ for ( var i = 0; i < navigator.mimeTypes.length; i++ ) {
 2962+ var type = navigator.mimeTypes[i].type;
 2963+ var semicolonPos = type.indexOf( ';' );
 2964+ if ( semicolonPos > -1 ) {
 2965+ type = type.substr( 0, semicolonPos );
 2966+ }
 2967+ // js_log('on type: '+type);
 2968+ var pluginName = navigator.mimeTypes[i].enabledPlugin ? navigator.mimeTypes[i].enabledPlugin.name : '';
 2969+ if ( !pluginName ) {
 2970+ // In case it is null or undefined
 2971+ pluginName = '';
 2972+ }
 2973+ if ( pluginName.toLowerCase() == 'vlc multimedia plugin' || pluginName.toLowerCase() == 'vlc multimedia plug-in' ) {
 2974+ this.players.addPlayer( vlcPlayer, type );
 2975+ continue;
 2976+ }
 2977+
 2978+ if ( type == 'application/x-java-applet' ) {
 2979+ this.players.addPlayer( cortadoPlayer );
 2980+ continue;
 2981+ }
 2982+
 2983+ if ( type == 'application/ogg' ) {
 2984+ if ( pluginName.toLowerCase() == 'vlc multimedia plugin' ) {
 2985+ this.players.addPlayer( vlcMozillaPlayer, type );
 2986+ // else if ( pluginName.indexOf( 'QuickTime' ) > -1 )
 2987+ // this.players.addPlayer(quicktimeMozillaPlayer);
 2988+ } else {
 2989+ this.players.addPlayer( oggPluginPlayer );
 2990+ }
 2991+ continue;
 2992+ } else if ( uniqueMimesOnly ) {
 2993+ if ( type == 'application/x-vlc-player' ) {
 2994+ this.players.addPlayer( vlcMozillaPlayer, type );
 2995+ continue;
 2996+ } else if ( type == 'video/quicktime' ) {
 2997+ // this.players.addPlayer(quicktimeMozillaPlayer);
 2998+ continue;
 2999+ }
 3000+ }
 3001+
 3002+ /*if ( type == 'video/quicktime' ) {
 3003+ this.players.addPlayer(vlcMozillaPlayer, type);
 3004+ continue;
 3005+ }*/
 3006+ if ( type == 'application/x-shockwave-flash' ) {
 3007+
 3008+ this.players.addPlayer( kplayer );
 3009+ //this.players.addPlayer( flowPlayer );
 3010+
 3011+ // check version to add omtk:
 3012+ var flashDescription = navigator.plugins["Shockwave Flash"].description;
 3013+ var descArray = flashDescription.split( " " );
 3014+ var tempArrayMajor = descArray[2].split( "." );
 3015+ var versionMajor = tempArrayMajor[0];
 3016+ // js_log("version of flash: " + versionMajor);
 3017+ if ( versionMajor >= 10 ) {
 3018+ this.players.addPlayer( omtkPlayer );
 3019+ }
 3020+ continue;
 3021+ }
 3022+ }
 3023+ }
 3024+ // @@The xiph quicktime component does not work well with annodex streams (temporarly disable)
 3025+ // this.clientSupports['quicktime-mozilla'] = false;
 3026+ // this.clientSupports['quicktime-activex'] = false;
 3027+ // js_log(this.clientSupports);
 3028+ },
 3029+ testActiveX : function ( name ) {
 3030+ var hasObj = true;
 3031+ try {
 3032+ // No IE, not a class called "name", it's a variable
 3033+ var obj = new ActiveXObject( '' + name );
 3034+ } catch ( e ) {
 3035+ hasObj = false;
 3036+ }
 3037+ return hasObj;
 3038+ }
 3039+};
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/embedPlayer.js
___________________________________________________________________
Added: svn:mergeinfo
13040 Merged /branches/REL1_15/phase3/js2/mwEmbed/libEmbedVideo/embedVideo.js:r51646
23041 Merged /branches/sqlite/js2/mwEmbed/libEmbedVideo/embedVideo.js:r58211-58321
Added: svn:eol-style
33042 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/genericEmbed.js
@@ -0,0 +1,17 @@
 2+/* the most simple implementation used for unknown application/ogg plugin */
 3+var genericEmbed = {
 4+ supports: {
 5+ 'play_head':false,
 6+ 'pause':false,
 7+ 'stop':true,
 8+ 'fullscreen':false,
 9+ 'time_display':false,
 10+ 'volume_control':false
 11+ },
 12+ instanceOf:'genericEmbed',
 13+ getEmbedHTML:function() {
 14+ return '<object type="application/ogg" ' +
 15+ 'width="' + this.width + '" height="' + this.height + '" ' +
 16+ 'data="' + this.getURI( this.seek_time_sec ) + '"></object>';
 17+ }
 18+};
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/genericEmbed.js
___________________________________________________________________
Added: svn:eol-style
119 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/LICENSE.txt
@@ -0,0 +1,674 @@
 2+ GNU GENERAL PUBLIC LICENSE
 3+ Version 3, 29 June 2007
 4+
 5+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 6+ Everyone is permitted to copy and distribute verbatim copies
 7+ of this license document, but changing it is not allowed.
 8+
 9+ Preamble
 10+
 11+ The GNU General Public License is a free, copyleft license for
 12+software and other kinds of works.
 13+
 14+ The licenses for most software and other practical works are designed
 15+to take away your freedom to share and change the works. By contrast,
 16+the GNU General Public License is intended to guarantee your freedom to
 17+share and change all versions of a program--to make sure it remains free
 18+software for all its users. We, the Free Software Foundation, use the
 19+GNU General Public License for most of our software; it applies also to
 20+any other work released this way by its authors. You can apply it to
 21+your programs, too.
 22+
 23+ When we speak of free software, we are referring to freedom, not
 24+price. Our General Public Licenses are designed to make sure that you
 25+have the freedom to distribute copies of free software (and charge for
 26+them if you wish), that you receive source code or can get it if you
 27+want it, that you can change the software or use pieces of it in new
 28+free programs, and that you know you can do these things.
 29+
 30+ To protect your rights, we need to prevent others from denying you
 31+these rights or asking you to surrender the rights. Therefore, you have
 32+certain responsibilities if you distribute copies of the software, or if
 33+you modify it: responsibilities to respect the freedom of others.
 34+
 35+ For example, if you distribute copies of such a program, whether
 36+gratis or for a fee, you must pass on to the recipients the same
 37+freedoms that you received. You must make sure that they, too, receive
 38+or can get the source code. And you must show them these terms so they
 39+know their rights.
 40+
 41+ Developers that use the GNU GPL protect your rights with two steps:
 42+(1) assert copyright on the software, and (2) offer you this License
 43+giving you legal permission to copy, distribute and/or modify it.
 44+
 45+ For the developers' and authors' protection, the GPL clearly explains
 46+that there is no warranty for this free software. For both users' and
 47+authors' sake, the GPL requires that modified versions be marked as
 48+changed, so that their problems will not be attributed erroneously to
 49+authors of previous versions.
 50+
 51+ Some devices are designed to deny users access to install or run
 52+modified versions of the software inside them, although the manufacturer
 53+can do so. This is fundamentally incompatible with the aim of
 54+protecting users' freedom to change the software. The systematic
 55+pattern of such abuse occurs in the area of products for individuals to
 56+use, which is precisely where it is most unacceptable. Therefore, we
 57+have designed this version of the GPL to prohibit the practice for those
 58+products. If such problems arise substantially in other domains, we
 59+stand ready to extend this provision to those domains in future versions
 60+of the GPL, as needed to protect the freedom of users.
 61+
 62+ Finally, every program is threatened constantly by software patents.
 63+States should not allow patents to restrict development and use of
 64+software on general-purpose computers, but in those that do, we wish to
 65+avoid the special danger that patents applied to a free program could
 66+make it effectively proprietary. To prevent this, the GPL assures that
 67+patents cannot be used to render the program non-free.
 68+
 69+ The precise terms and conditions for copying, distribution and
 70+modification follow.
 71+
 72+ TERMS AND CONDITIONS
 73+
 74+ 0. Definitions.
 75+
 76+ "This License" refers to version 3 of the GNU General Public License.
 77+
 78+ "Copyright" also means copyright-like laws that apply to other kinds of
 79+works, such as semiconductor masks.
 80+
 81+ "The Program" refers to any copyrightable work licensed under this
 82+License. Each licensee is addressed as "you". "Licensees" and
 83+"recipients" may be individuals or organizations.
 84+
 85+ To "modify" a work means to copy from or adapt all or part of the work
 86+in a fashion requiring copyright permission, other than the making of an
 87+exact copy. The resulting work is called a "modified version" of the
 88+earlier work or a work "based on" the earlier work.
 89+
 90+ A "covered work" means either the unmodified Program or a work based
 91+on the Program.
 92+
 93+ To "propagate" a work means to do anything with it that, without
 94+permission, would make you directly or secondarily liable for
 95+infringement under applicable copyright law, except executing it on a
 96+computer or modifying a private copy. Propagation includes copying,
 97+distribution (with or without modification), making available to the
 98+public, and in some countries other activities as well.
 99+
 100+ To "convey" a work means any kind of propagation that enables other
 101+parties to make or receive copies. Mere interaction with a user through
 102+a computer network, with no transfer of a copy, is not conveying.
 103+
 104+ An interactive user interface displays "Appropriate Legal Notices"
 105+to the extent that it includes a convenient and prominently visible
 106+feature that (1) displays an appropriate copyright notice, and (2)
 107+tells the user that there is no warranty for the work (except to the
 108+extent that warranties are provided), that licensees may convey the
 109+work under this License, and how to view a copy of this License. If
 110+the interface presents a list of user commands or options, such as a
 111+menu, a prominent item in the list meets this criterion.
 112+
 113+ 1. Source Code.
 114+
 115+ The "source code" for a work means the preferred form of the work
 116+for making modifications to it. "Object code" means any non-source
 117+form of a work.
 118+
 119+ A "Standard Interface" means an interface that either is an official
 120+standard defined by a recognized standards body, or, in the case of
 121+interfaces specified for a particular programming language, one that
 122+is widely used among developers working in that language.
 123+
 124+ The "System Libraries" of an executable work include anything, other
 125+than the work as a whole, that (a) is included in the normal form of
 126+packaging a Major Component, but which is not part of that Major
 127+Component, and (b) serves only to enable use of the work with that
 128+Major Component, or to implement a Standard Interface for which an
 129+implementation is available to the public in source code form. A
 130+"Major Component", in this context, means a major essential component
 131+(kernel, window system, and so on) of the specific operating system
 132+(if any) on which the executable work runs, or a compiler used to
 133+produce the work, or an object code interpreter used to run it.
 134+
 135+ The "Corresponding Source" for a work in object code form means all
 136+the source code needed to generate, install, and (for an executable
 137+work) run the object code and to modify the work, including scripts to
 138+control those activities. However, it does not include the work's
 139+System Libraries, or general-purpose tools or generally available free
 140+programs which are used unmodified in performing those activities but
 141+which are not part of the work. For example, Corresponding Source
 142+includes interface definition files associated with source files for
 143+the work, and the source code for shared libraries and dynamically
 144+linked subprograms that the work is specifically designed to require,
 145+such as by intimate data communication or control flow between those
 146+subprograms and other parts of the work.
 147+
 148+ The Corresponding Source need not include anything that users
 149+can regenerate automatically from other parts of the Corresponding
 150+Source.
 151+
 152+ The Corresponding Source for a work in source code form is that
 153+same work.
 154+
 155+ 2. Basic Permissions.
 156+
 157+ All rights granted under this License are granted for the term of
 158+copyright on the Program, and are irrevocable provided the stated
 159+conditions are met. This License explicitly affirms your unlimited
 160+permission to run the unmodified Program. The output from running a
 161+covered work is covered by this License only if the output, given its
 162+content, constitutes a covered work. This License acknowledges your
 163+rights of fair use or other equivalent, as provided by copyright law.
 164+
 165+ You may make, run and propagate covered works that you do not
 166+convey, without conditions so long as your license otherwise remains
 167+in force. You may convey covered works to others for the sole purpose
 168+of having them make modifications exclusively for you, or provide you
 169+with facilities for running those works, provided that you comply with
 170+the terms of this License in conveying all material for which you do
 171+not control copyright. Those thus making or running the covered works
 172+for you must do so exclusively on your behalf, under your direction
 173+and control, on terms that prohibit them from making any copies of
 174+your copyrighted material outside their relationship with you.
 175+
 176+ Conveying under any other circumstances is permitted solely under
 177+the conditions stated below. Sublicensing is not allowed; section 10
 178+makes it unnecessary.
 179+
 180+ 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
 181+
 182+ No covered work shall be deemed part of an effective technological
 183+measure under any applicable law fulfilling obligations under article
 184+11 of the WIPO copyright treaty adopted on 20 December 1996, or
 185+similar laws prohibiting or restricting circumvention of such
 186+measures.
 187+
 188+ When you convey a covered work, you waive any legal power to forbid
 189+circumvention of technological measures to the extent such circumvention
 190+is effected by exercising rights under this License with respect to
 191+the covered work, and you disclaim any intention to limit operation or
 192+modification of the work as a means of enforcing, against the work's
 193+users, your or third parties' legal rights to forbid circumvention of
 194+technological measures.
 195+
 196+ 4. Conveying Verbatim Copies.
 197+
 198+ You may convey verbatim copies of the Program's source code as you
 199+receive it, in any medium, provided that you conspicuously and
 200+appropriately publish on each copy an appropriate copyright notice;
 201+keep intact all notices stating that this License and any
 202+non-permissive terms added in accord with section 7 apply to the code;
 203+keep intact all notices of the absence of any warranty; and give all
 204+recipients a copy of this License along with the Program.
 205+
 206+ You may charge any price or no price for each copy that you convey,
 207+and you may offer support or warranty protection for a fee.
 208+
 209+ 5. Conveying Modified Source Versions.
 210+
 211+ You may convey a work based on the Program, or the modifications to
 212+produce it from the Program, in the form of source code under the
 213+terms of section 4, provided that you also meet all of these conditions:
 214+
 215+ a) The work must carry prominent notices stating that you modified
 216+ it, and giving a relevant date.
 217+
 218+ b) The work must carry prominent notices stating that it is
 219+ released under this License and any conditions added under section
 220+ 7. This requirement modifies the requirement in section 4 to
 221+ "keep intact all notices".
 222+
 223+ c) You must license the entire work, as a whole, under this
 224+ License to anyone who comes into possession of a copy. This
 225+ License will therefore apply, along with any applicable section 7
 226+ additional terms, to the whole of the work, and all its parts,
 227+ regardless of how they are packaged. This License gives no
 228+ permission to license the work in any other way, but it does not
 229+ invalidate such permission if you have separately received it.
 230+
 231+ d) If the work has interactive user interfaces, each must display
 232+ Appropriate Legal Notices; however, if the Program has interactive
 233+ interfaces that do not display Appropriate Legal Notices, your
 234+ work need not make them do so.
 235+
 236+ A compilation of a covered work with other separate and independent
 237+works, which are not by their nature extensions of the covered work,
 238+and which are not combined with it such as to form a larger program,
 239+in or on a volume of a storage or distribution medium, is called an
 240+"aggregate" if the compilation and its resulting copyright are not
 241+used to limit the access or legal rights of the compilation's users
 242+beyond what the individual works permit. Inclusion of a covered work
 243+in an aggregate does not cause this License to apply to the other
 244+parts of the aggregate.
 245+
 246+ 6. Conveying Non-Source Forms.
 247+
 248+ You may convey a covered work in object code form under the terms
 249+of sections 4 and 5, provided that you also convey the
 250+machine-readable Corresponding Source under the terms of this License,
 251+in one of these ways:
 252+
 253+ a) Convey the object code in, or embodied in, a physical product
 254+ (including a physical distribution medium), accompanied by the
 255+ Corresponding Source fixed on a durable physical medium
 256+ customarily used for software interchange.
 257+
 258+ b) Convey the object code in, or embodied in, a physical product
 259+ (including a physical distribution medium), accompanied by a
 260+ written offer, valid for at least three years and valid for as
 261+ long as you offer spare parts or customer support for that product
 262+ model, to give anyone who possesses the object code either (1) a
 263+ copy of the Corresponding Source for all the software in the
 264+ product that is covered by this License, on a durable physical
 265+ medium customarily used for software interchange, for a price no
 266+ more than your reasonable cost of physically performing this
 267+ conveying of source, or (2) access to copy the
 268+ Corresponding Source from a network server at no charge.
 269+
 270+ c) Convey individual copies of the object code with a copy of the
 271+ written offer to provide the Corresponding Source. This
 272+ alternative is allowed only occasionally and noncommercially, and
 273+ only if you received the object code with such an offer, in accord
 274+ with subsection 6b.
 275+
 276+ d) Convey the object code by offering access from a designated
 277+ place (gratis or for a charge), and offer equivalent access to the
 278+ Corresponding Source in the same way through the same place at no
 279+ further charge. You need not require recipients to copy the
 280+ Corresponding Source along with the object code. If the place to
 281+ copy the object code is a network server, the Corresponding Source
 282+ may be on a different server (operated by you or a third party)
 283+ that supports equivalent copying facilities, provided you maintain
 284+ clear directions next to the object code saying where to find the
 285+ Corresponding Source. Regardless of what server hosts the
 286+ Corresponding Source, you remain obligated to ensure that it is
 287+ available for as long as needed to satisfy these requirements.
 288+
 289+ e) Convey the object code using peer-to-peer transmission, provided
 290+ you inform other peers where the object code and Corresponding
 291+ Source of the work are being offered to the general public at no
 292+ charge under subsection 6d.
 293+
 294+ A separable portion of the object code, whose source code is excluded
 295+from the Corresponding Source as a System Library, need not be
 296+included in conveying the object code work.
 297+
 298+ A "User Product" is either (1) a "consumer product", which means any
 299+tangible personal property which is normally used for personal, family,
 300+or household purposes, or (2) anything designed or sold for incorporation
 301+into a dwelling. In determining whether a product is a consumer product,
 302+doubtful cases shall be resolved in favor of coverage. For a particular
 303+product received by a particular user, "normally used" refers to a
 304+typical or common use of that class of product, regardless of the status
 305+of the particular user or of the way in which the particular user
 306+actually uses, or expects or is expected to use, the product. A product
 307+is a consumer product regardless of whether the product has substantial
 308+commercial, industrial or non-consumer uses, unless such uses represent
 309+the only significant mode of use of the product.
 310+
 311+ "Installation Information" for a User Product means any methods,
 312+procedures, authorization keys, or other information required to install
 313+and execute modified versions of a covered work in that User Product from
 314+a modified version of its Corresponding Source. The information must
 315+suffice to ensure that the continued functioning of the modified object
 316+code is in no case prevented or interfered with solely because
 317+modification has been made.
 318+
 319+ If you convey an object code work under this section in, or with, or
 320+specifically for use in, a User Product, and the conveying occurs as
 321+part of a transaction in which the right of possession and use of the
 322+User Product is transferred to the recipient in perpetuity or for a
 323+fixed term (regardless of how the transaction is characterized), the
 324+Corresponding Source conveyed under this section must be accompanied
 325+by the Installation Information. But this requirement does not apply
 326+if neither you nor any third party retains the ability to install
 327+modified object code on the User Product (for example, the work has
 328+been installed in ROM).
 329+
 330+ The requirement to provide Installation Information does not include a
 331+requirement to continue to provide support service, warranty, or updates
 332+for a work that has been modified or installed by the recipient, or for
 333+the User Product in which it has been modified or installed. Access to a
 334+network may be denied when the modification itself materially and
 335+adversely affects the operation of the network or violates the rules and
 336+protocols for communication across the network.
 337+
 338+ Corresponding Source conveyed, and Installation Information provided,
 339+in accord with this section must be in a format that is publicly
 340+documented (and with an implementation available to the public in
 341+source code form), and must require no special password or key for
 342+unpacking, reading or copying.
 343+
 344+ 7. Additional Terms.
 345+
 346+ "Additional permissions" are terms that supplement the terms of this
 347+License by making exceptions from one or more of its conditions.
 348+Additional permissions that are applicable to the entire Program shall
 349+be treated as though they were included in this License, to the extent
 350+that they are valid under applicable law. If additional permissions
 351+apply only to part of the Program, that part may be used separately
 352+under those permissions, but the entire Program remains governed by
 353+this License without regard to the additional permissions.
 354+
 355+ When you convey a copy of a covered work, you may at your option
 356+remove any additional permissions from that copy, or from any part of
 357+it. (Additional permissions may be written to require their own
 358+removal in certain cases when you modify the work.) You may place
 359+additional permissions on material, added by you to a covered work,
 360+for which you have or can give appropriate copyright permission.
 361+
 362+ Notwithstanding any other provision of this License, for material you
 363+add to a covered work, you may (if authorized by the copyright holders of
 364+that material) supplement the terms of this License with terms:
 365+
 366+ a) Disclaiming warranty or limiting liability differently from the
 367+ terms of sections 15 and 16 of this License; or
 368+
 369+ b) Requiring preservation of specified reasonable legal notices or
 370+ author attributions in that material or in the Appropriate Legal
 371+ Notices displayed by works containing it; or
 372+
 373+ c) Prohibiting misrepresentation of the origin of that material, or
 374+ requiring that modified versions of such material be marked in
 375+ reasonable ways as different from the original version; or
 376+
 377+ d) Limiting the use for publicity purposes of names of licensors or
 378+ authors of the material; or
 379+
 380+ e) Declining to grant rights under trademark law for use of some
 381+ trade names, trademarks, or service marks; or
 382+
 383+ f) Requiring indemnification of licensors and authors of that
 384+ material by anyone who conveys the material (or modified versions of
 385+ it) with contractual assumptions of liability to the recipient, for
 386+ any liability that these contractual assumptions directly impose on
 387+ those licensors and authors.
 388+
 389+ All other non-permissive additional terms are considered "further
 390+restrictions" within the meaning of section 10. If the Program as you
 391+received it, or any part of it, contains a notice stating that it is
 392+governed by this License along with a term that is a further
 393+restriction, you may remove that term. If a license document contains
 394+a further restriction but permits relicensing or conveying under this
 395+License, you may add to a covered work material governed by the terms
 396+of that license document, provided that the further restriction does
 397+not survive such relicensing or conveying.
 398+
 399+ If you add terms to a covered work in accord with this section, you
 400+must place, in the relevant source files, a statement of the
 401+additional terms that apply to those files, or a notice indicating
 402+where to find the applicable terms.
 403+
 404+ Additional terms, permissive or non-permissive, may be stated in the
 405+form of a separately written license, or stated as exceptions;
 406+the above requirements apply either way.
 407+
 408+ 8. Termination.
 409+
 410+ You may not propagate or modify a covered work except as expressly
 411+provided under this License. Any attempt otherwise to propagate or
 412+modify it is void, and will automatically terminate your rights under
 413+this License (including any patent licenses granted under the third
 414+paragraph of section 11).
 415+
 416+ However, if you cease all violation of this License, then your
 417+license from a particular copyright holder is reinstated (a)
 418+provisionally, unless and until the copyright holder explicitly and
 419+finally terminates your license, and (b) permanently, if the copyright
 420+holder fails to notify you of the violation by some reasonable means
 421+prior to 60 days after the cessation.
 422+
 423+ Moreover, your license from a particular copyright holder is
 424+reinstated permanently if the copyright holder notifies you of the
 425+violation by some reasonable means, this is the first time you have
 426+received notice of violation of this License (for any work) from that
 427+copyright holder, and you cure the violation prior to 30 days after
 428+your receipt of the notice.
 429+
 430+ Termination of your rights under this section does not terminate the
 431+licenses of parties who have received copies or rights from you under
 432+this License. If your rights have been terminated and not permanently
 433+reinstated, you do not qualify to receive new licenses for the same
 434+material under section 10.
 435+
 436+ 9. Acceptance Not Required for Having Copies.
 437+
 438+ You are not required to accept this License in order to receive or
 439+run a copy of the Program. Ancillary propagation of a covered work
 440+occurring solely as a consequence of using peer-to-peer transmission
 441+to receive a copy likewise does not require acceptance. However,
 442+nothing other than this License grants you permission to propagate or
 443+modify any covered work. These actions infringe copyright if you do
 444+not accept this License. Therefore, by modifying or propagating a
 445+covered work, you indicate your acceptance of this License to do so.
 446+
 447+ 10. Automatic Licensing of Downstream Recipients.
 448+
 449+ Each time you convey a covered work, the recipient automatically
 450+receives a license from the original licensors, to run, modify and
 451+propagate that work, subject to this License. You are not responsible
 452+for enforcing compliance by third parties with this License.
 453+
 454+ An "entity transaction" is a transaction transferring control of an
 455+organization, or substantially all assets of one, or subdividing an
 456+organization, or merging organizations. If propagation of a covered
 457+work results from an entity transaction, each party to that
 458+transaction who receives a copy of the work also receives whatever
 459+licenses to the work the party's predecessor in interest had or could
 460+give under the previous paragraph, plus a right to possession of the
 461+Corresponding Source of the work from the predecessor in interest, if
 462+the predecessor has it or can get it with reasonable efforts.
 463+
 464+ You may not impose any further restrictions on the exercise of the
 465+rights granted or affirmed under this License. For example, you may
 466+not impose a license fee, royalty, or other charge for exercise of
 467+rights granted under this License, and you may not initiate litigation
 468+(including a cross-claim or counterclaim in a lawsuit) alleging that
 469+any patent claim is infringed by making, using, selling, offering for
 470+sale, or importing the Program or any portion of it.
 471+
 472+ 11. Patents.
 473+
 474+ A "contributor" is a copyright holder who authorizes use under this
 475+License of the Program or a work on which the Program is based. The
 476+work thus licensed is called the contributor's "contributor version".
 477+
 478+ A contributor's "essential patent claims" are all patent claims
 479+owned or controlled by the contributor, whether already acquired or
 480+hereafter acquired, that would be infringed by some manner, permitted
 481+by this License, of making, using, or selling its contributor version,
 482+but do not include claims that would be infringed only as a
 483+consequence of further modification of the contributor version. For
 484+purposes of this definition, "control" includes the right to grant
 485+patent sublicenses in a manner consistent with the requirements of
 486+this License.
 487+
 488+ Each contributor grants you a non-exclusive, worldwide, royalty-free
 489+patent license under the contributor's essential patent claims, to
 490+make, use, sell, offer for sale, import and otherwise run, modify and
 491+propagate the contents of its contributor version.
 492+
 493+ In the following three paragraphs, a "patent license" is any express
 494+agreement or commitment, however denominated, not to enforce a patent
 495+(such as an express permission to practice a patent or covenant not to
 496+sue for patent infringement). To "grant" such a patent license to a
 497+party means to make such an agreement or commitment not to enforce a
 498+patent against the party.
 499+
 500+ If you convey a covered work, knowingly relying on a patent license,
 501+and the Corresponding Source of the work is not available for anyone
 502+to copy, free of charge and under the terms of this License, through a
 503+publicly available network server or other readily accessible means,
 504+then you must either (1) cause the Corresponding Source to be so
 505+available, or (2) arrange to deprive yourself of the benefit of the
 506+patent license for this particular work, or (3) arrange, in a manner
 507+consistent with the requirements of this License, to extend the patent
 508+license to downstream recipients. "Knowingly relying" means you have
 509+actual knowledge that, but for the patent license, your conveying the
 510+covered work in a country, or your recipient's use of the covered work
 511+in a country, would infringe one or more identifiable patents in that
 512+country that you have reason to believe are valid.
 513+
 514+ If, pursuant to or in connection with a single transaction or
 515+arrangement, you convey, or propagate by procuring conveyance of, a
 516+covered work, and grant a patent license to some of the parties
 517+receiving the covered work authorizing them to use, propagate, modify
 518+or convey a specific copy of the covered work, then the patent license
 519+you grant is automatically extended to all recipients of the covered
 520+work and works based on it.
 521+
 522+ A patent license is "discriminatory" if it does not include within
 523+the scope of its coverage, prohibits the exercise of, or is
 524+conditioned on the non-exercise of one or more of the rights that are
 525+specifically granted under this License. You may not convey a covered
 526+work if you are a party to an arrangement with a third party that is
 527+in the business of distributing software, under which you make payment
 528+to the third party based on the extent of your activity of conveying
 529+the work, and under which the third party grants, to any of the
 530+parties who would receive the covered work from you, a discriminatory
 531+patent license (a) in connection with copies of the covered work
 532+conveyed by you (or copies made from those copies), or (b) primarily
 533+for and in connection with specific products or compilations that
 534+contain the covered work, unless you entered into that arrangement,
 535+or that patent license was granted, prior to 28 March 2007.
 536+
 537+ Nothing in this License shall be construed as excluding or limiting
 538+any implied license or other defenses to infringement that may
 539+otherwise be available to you under applicable patent law.
 540+
 541+ 12. No Surrender of Others' Freedom.
 542+
 543+ If conditions are imposed on you (whether by court order, agreement or
 544+otherwise) that contradict the conditions of this License, they do not
 545+excuse you from the conditions of this License. If you cannot convey a
 546+covered work so as to satisfy simultaneously your obligations under this
 547+License and any other pertinent obligations, then as a consequence you may
 548+not convey it at all. For example, if you agree to terms that obligate you
 549+to collect a royalty for further conveying from those to whom you convey
 550+the Program, the only way you could satisfy both those terms and this
 551+License would be to refrain entirely from conveying the Program.
 552+
 553+ 13. Use with the GNU Affero General Public License.
 554+
 555+ Notwithstanding any other provision of this License, you have
 556+permission to link or combine any covered work with a work licensed
 557+under version 3 of the GNU Affero General Public License into a single
 558+combined work, and to convey the resulting work. The terms of this
 559+License will continue to apply to the part which is the covered work,
 560+but the special requirements of the GNU Affero General Public License,
 561+section 13, concerning interaction through a network will apply to the
 562+combination as such.
 563+
 564+ 14. Revised Versions of this License.
 565+
 566+ The Free Software Foundation may publish revised and/or new versions of
 567+the GNU General Public License from time to time. Such new versions will
 568+be similar in spirit to the present version, but may differ in detail to
 569+address new problems or concerns.
 570+
 571+ Each version is given a distinguishing version number. If the
 572+Program specifies that a certain numbered version of the GNU General
 573+Public License "or any later version" applies to it, you have the
 574+option of following the terms and conditions either of that numbered
 575+version or of any later version published by the Free Software
 576+Foundation. If the Program does not specify a version number of the
 577+GNU General Public License, you may choose any version ever published
 578+by the Free Software Foundation.
 579+
 580+ If the Program specifies that a proxy can decide which future
 581+versions of the GNU General Public License can be used, that proxy's
 582+public statement of acceptance of a version permanently authorizes you
 583+to choose that version for the Program.
 584+
 585+ Later license versions may give you additional or different
 586+permissions. However, no additional obligations are imposed on any
 587+author or copyright holder as a result of your choosing to follow a
 588+later version.
 589+
 590+ 15. Disclaimer of Warranty.
 591+
 592+ THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
 593+APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
 594+HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
 595+OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
 596+THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 597+PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
 598+IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
 599+ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
 600+
 601+ 16. Limitation of Liability.
 602+
 603+ IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
 604+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
 605+THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
 606+GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
 607+USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
 608+DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
 609+PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
 610+EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
 611+SUCH DAMAGES.
 612+
 613+ 17. Interpretation of Sections 15 and 16.
 614+
 615+ If the disclaimer of warranty and limitation of liability provided
 616+above cannot be given local legal effect according to their terms,
 617+reviewing courts shall apply local law that most closely approximates
 618+an absolute waiver of all civil liability in connection with the
 619+Program, unless a warranty or assumption of liability accompanies a
 620+copy of the Program in return for a fee.
 621+
 622+ END OF TERMS AND CONDITIONS
 623+
 624+ How to Apply These Terms to Your New Programs
 625+
 626+ If you develop a new program, and you want it to be of the greatest
 627+possible use to the public, the best way to achieve this is to make it
 628+free software which everyone can redistribute and change under these terms.
 629+
 630+ To do so, attach the following notices to the program. It is safest
 631+to attach them to the start of each source file to most effectively
 632+state the exclusion of warranty; and each file should have at least
 633+the "copyright" line and a pointer to where the full notice is found.
 634+
 635+ <one line to give the program's name and a brief idea of what it does.>
 636+ Copyright (C) <year> <name of author>
 637+
 638+ This program is free software: you can redistribute it and/or modify
 639+ it under the terms of the GNU General Public License as published by
 640+ the Free Software Foundation, either version 3 of the License, or
 641+ (at your option) any later version.
 642+
 643+ This program is distributed in the hope that it will be useful,
 644+ but WITHOUT ANY WARRANTY; without even the implied warranty of
 645+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 646+ GNU General Public License for more details.
 647+
 648+ You should have received a copy of the GNU General Public License
 649+ along with this program. If not, see <http://www.gnu.org/licenses/>.
 650+
 651+Also add information on how to contact you by electronic and paper mail.
 652+
 653+ If the program does terminal interaction, make it output a short
 654+notice like this when it starts in an interactive mode:
 655+
 656+ <program> Copyright (C) <year> <name of author>
 657+ This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
 658+ This is free software, and you are welcome to redistribute it
 659+ under certain conditions; type `show c' for details.
 660+
 661+The hypothetical commands `show w' and `show c' should show the appropriate
 662+parts of the General Public License. Of course, your program's commands
 663+might be different; for a GUI interface, you would use an "about box".
 664+
 665+ You should also get your employer (if you work as a programmer) or school,
 666+if any, to sign a "copyright disclaimer" for the program, if necessary.
 667+For more information on this, and how to apply and follow the GNU GPL, see
 668+<http://www.gnu.org/licenses/>.
 669+
 670+ The GNU General Public License does not permit incorporating your program
 671+into proprietary programs. If your program is a subroutine library, you
 672+may consider it more useful to permit linking proprietary applications with
 673+the library. If this is what you want to do, use the GNU Lesser General
 674+Public License instead of this License. But first, please read
 675+<http://www.gnu.org/philosophy/why-not-lgpl.html>.
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/LICENSE.txt
___________________________________________________________________
Added: svn:eol-style
1676 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer.controls-3.0.0-beta7.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer.controls-3.0.0-beta7.swf
___________________________________________________________________
Added: svn:mime-type
2677 + application/octet-stream
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer-3.0.0-rc2.min.js
@@ -0,0 +1,15 @@
 2+/**
 3+ * flowplayer.js 3.0.0-rc2. The Flowplayer API.
 4+ *
 5+ * This file is part of Flowplayer, http://flowplayer.org
 6+ *
 7+ * Author: Tero Piirainen, <support@flowplayer.org>
 8+ * Copyright (c) 2008 Flowplayer Ltd
 9+ *
 10+ * Released under the MIT License:
 11+ * http://www.opensource.org/licenses/mit-license.php
 12+ *
 13+ * Version: 3.0.0-rc2 - Fri Nov 07 2008 16:50:52 GMT-0000 (GMT+00:00)
 14+ */
 15+(function(){function log(args){if(typeof opera=='object'){opera.postError("$f.fireEvent: "+args.join(" | "));}else if(typeof console=='object'){console.log("$f.fireEvent",[].slice.call(args));}}function clone(obj){if(!obj||typeof obj!='object'){return obj;}var temp=new obj.constructor();for(var key in obj){if(obj.hasOwnProperty(key)){temp[key]=clone(obj[key]);}}return temp;}function each(obj,fn){if(!obj){return;}var name,i=0,length=obj.length;if(length===undefined){for(name in obj){if(fn.call(obj[name],name,obj[name])===false){break;}}}else{for(var value=obj[0];i<length&&fn.call(value,i,value)!==false;value=obj[++i]){}}return obj;}function el(id){return document.getElementById(id);}function extend(to,from,skipFuncs){if(to&&from){each(from,function(name,value){if(!skipFuncs||typeof value!='function'){to[name]=value;}});}}function select(query){var index=query.indexOf(".");if(index!=-1){var tag=query.substring(0,index)||"*";var klass=query.substring(index+1,query.length);var els=[];each(document.getElementsByTagName(tag),function(){if(this.className&&this.className.indexOf(klass)!=-1){els.push(this);}});return els;}}function stopEvent(e){e=e||window.event;if(e.preventDefault){e.stopPropagation();e.preventDefault();}else{e.returnValue=false;e.cancelBubble=true;}return false;}function bind(to,evt,fn){to[evt]=to[evt]||[];to[evt].push(fn);}function makeId(){return"_"+(""+Math.random()).substring(2,10);}var Clip=function(json,index,player){var self=this;var cuepoints={};var listeners={};this.index=index;if(typeof json=='string'){json={url:json};}extend(this,json,true);each(("Start*,MetaData,Pause*,Resume*,Seek*,Stop*,Finish,LastSecond,Update,BufferFull,BufferEmpty").split(","),function(){var evt="on"+this;if(evt.indexOf("*")!=-1){evt=evt.substring(0,evt.length-1);var before="onBefore"+evt.substring(2);self[before]=function(fn){bind(listeners,before,fn);return self;};}self[evt]=function(fn){bind(listeners,evt,fn);return self;};if(index==-1){if(self[before]){player[before]=self[before];}if(self[evt]){player[evt]=self[evt];}}});extend(this,{onCuepoint:function(points,fn){if(arguments.length==1){cuepoints.embedded=[null,points];return self;}if(typeof points=='number'){points=[points];}var fnId=makeId();cuepoints[fnId]=[points,fn];if(player.isLoaded()){player._api().fp_addCuepoints(points,index,fnId);}return self;},update:function(json){extend(self,json);if(player.isLoaded()){player._api().fp_updateClip(json,index);}var conf=player._config();var clip=(index==-1)?conf.clip:conf.playlist[index];extend(clip,json,true);},_fireEvent:function(evt,arg1,arg2,target){if(evt=='onLoad'){each(cuepoints,function(key,val){player._api().fp_addCuepoints(val[0],index,key);});return false;}if(index!=-1){target=self;}if(evt=='onCuepoint'){var fn=cuepoints[arg1];if(fn){return fn[1].call(player,target,arg2);}}if(evt=='onMetaData'||evt=='onUpdate'){extend(target,arg1);if(!target.duration){target.duration=arg1.metaData.duration;}else{target.fullDuration=arg1.metaData.duration;}}var ret=true;each(listeners[evt],function(){ret=this.call(player,target,arg1);});return ret;}});if(json.onCuepoint){self.onCuepoint.apply(self,json.onCuepoint);delete json.onCuepoint;}each(json,function(key,val){if(typeof val=='function'){bind(listeners,key,val);delete json[key];}});if(index==-1){player.onCuepoint=this.onCuepoint;}};var Plugin=function(name,json,player,fn){var listeners={};var self=this;var hasMethods=false;if(fn){extend(listeners,fn);}each(json,function(key,val){if(typeof val=='function'){listeners[key]=val;delete json[key];}});extend(this,{animate:function(props,speed,fn){if(!props){return self;}if(typeof speed=='function'){fn=speed;speed=500;}if(typeof props=='string'){var key=props;props={};props[key]=speed;speed=500;}if(fn){var fnId=makeId();listeners[fnId]=fn;}if(speed===undefined){speed=500;}json=player._api().fp_animate(name,props,speed,fnId);return self;},css:function(props,val){if(val!==undefined){var css={};css[props]=val;props=css;}json=player._api().fp_css(name,props);extend(self,json);return self;},show:function(){this.display='block';player._api().fp_showPlugin(name);return self;},hide:function(){this.display='none';player._api().fp_hidePlugin(name);return self;},toggle:function(){this.display=player._api().fp_togglePlugin(name);return self;},fadeTo:function(o,speed,fn){if(typeof speed=='function'){fn=speed;speed=500;}if(fn){var fnId=makeId();listeners[fnId]=fn;}this.display=player._api().fp_fadeTo(name,o,speed,fnId);this.opacity=o;return self;},fadeIn:function(speed,fn){return self.fadeTo(1,speed,fn);},fadeOut:function(speed,fn){return self.fadeTo(0,speed,fn);},getName:function(){return name;},_fireEvent:function(evt,arg){if(evt=='onUpdate'){var json=arg||player._api().fp_getPlugin(name);if(!json){return;}extend(self,json);delete self.methods;if(!hasMethods){each(json.methods,function(){var method=""+this;self[method]=function(){var a=[].slice.call(arguments);var ret=player._api().fp_invoke(name,method,a);return ret=='undefined'?self:ret;};});hasMethods=true;}}var fn=listeners[evt];if(fn){fn.call(self,arg);if(evt.substring(0,1)=="_"){delete listeners[evt];}}}});};function Player(wrapper,params,conf){var
 16+self=this,api=null,html,commonClip,playlist=[],plugins={},listeners={},playerId,apiId,activeIndex,swfHeight;extend(self,{id:function(){return playerId;},isLoaded:function(){return(api!==null);},getParent:function(){return wrapper;},hide:function(){if(api){api.style.height="0px";}return self;},show:function(){if(api){api.style.height=swfHeight+"px";}return self;},isHidden:function(){return api&&parseInt(api.style.height,10)===0;},load:function(fn){if(!api&&self._fireEvent("onBeforeLoad")!==false){each(players,function(){this.unload();});html=wrapper.innerHTML;flashembed(wrapper,params,{config:conf});if(fn){fn.cached=true;bind(listeners,"onLoad",fn);}}return self;},unload:function(){if(api&&html.replace(/\s/g,'')!==''&&!api.fp_isFullscreen()&&self._fireEvent("onBeforeUnload")!==false){api.fp_close();wrapper.innerHTML=html;self._fireEvent("onUnload");api=null;}return self;},getClip:function(index){if(index===undefined){index=activeIndex;}return playlist[index];},getCommonClip:function(){return commonClip;},getPlaylist:function(){return playlist;},getPlugin:function(name){var plugin=plugins[name];if(!plugin&&self.isLoaded()){var json=self._api().fp_getPlugin(name);if(json){plugin=new Plugin(name,json,self);plugins[name]=plugin;}}return plugin;},getScreen:function(){return self.getPlugin("screen");},getControls:function(){return self.getPlugin("controls");},getConfig:function(){return clone(conf);},getFlashParams:function(){return params;},loadPlugin:function(name,url,props,fn){if(typeof props=='function'){fn=props;props={};}var fnId=fn?makeId():"_";self._api().fp_loadPlugin(name,url,props,fnId);var arg={};arg[fnId]=fn;var p=new Plugin(name,null,self,arg);plugins[name]=p;return p;},getState:function(){return api?api.fp_getState():-1;},play:function(clip){function play(){if(clip!==undefined){self._api().fp_play(clip);}else{self._api().fp_play();}}if(api){play();}else{self.load(function(){play();});}return self;},getVersion:function(){var js="flowplayer.js 3.0.0-rc2";if(api){var ver=api.fp_getVersion();ver.push(js);return ver;}return js;},_api:function(){if(!api){throw"Flowplayer "+self.id()+" not loaded. Try moving your call to player's onLoad event";}return api;},_config:function(){return conf;}});each(("Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,Fullscreen*,FullscreenExit,Error").split(","),function(){var name="on"+this;if(name.indexOf("*")!=-1){name=name.substring(0,name.length-1);var name2="onBefore"+name.substring(2);self[name2]=function(fn){bind(listeners,name2,fn);return self;};}self[name]=function(fn){bind(listeners,name,fn);return self;};});each(("pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,reset").split(","),function(){var name=this;self[name]=function(arg){if(!api){return self;}var ret=(arg===undefined)?api["fp_"+name]():api["fp_"+name](arg);return ret=='undefined'?self:ret;};});self._fireEvent=function(evt,arg0,arg1,arg2){if(conf.debug){log(arguments);}if(evt=='onLoad'&&!api){api=api||el(apiId);swfHeight=api.clientHeight;each(playlist,function(){this._fireEvent("onLoad");});each(plugins,function(name,p){p._fireEvent("onUpdate");});commonClip._fireEvent("onLoad");}if(evt=='onContextMenu'){each(conf.contextMenu[arg0],function(key,fn){fn.call(self);});return;}if(evt=='onPluginEvent'){var name=arg0.name||arg0;var p=plugins[name];if(p){if(arg0.name){p._fireEvent("onUpdate",arg0);}p._fireEvent(arg1);}return;}if(evt=='onPlaylistReplace'){playlist=[];var index=0;each(arg0,function(){playlist.push(new Clip(this,index++));});}var ret=true;if(arg0===0||(arg0&&arg0>=0)){activeIndex=arg0;var clip=playlist[arg0];if(!clip||clip._fireEvent(evt,arg1,arg2)!==false){ret=commonClip._fireEvent(evt,arg1,arg2,clip);}}var i=0;each(listeners[evt],function(){ret=this.call(self,arg0);if(this.cached){listeners[evt].splice(i,1);}if(ret===false){return false;}i++;});return ret;};function init(){if($f(wrapper)){return null;}players.push(self);if(typeof params=='string'){params={src:params};}playerId=wrapper.id||"fp"+makeId();apiId=params.id||playerId+"_api";params.id=apiId;conf.playerId=playerId;if(typeof conf=='string'){conf={clip:{url:conf}};}conf.clip=conf.clip||{};commonClip=new Clip(conf.clip,-1,self);if(wrapper.getAttribute("href")){conf.playlist=[{url:wrapper.getAttribute("href",2)}];}conf.playlist=conf.playlist||[conf.clip];var index=0;each(conf.playlist,function(){var clip=this;if(typeof clip=='object'&&clip.length){clip=""+clip;}if(!clip.url&&typeof clip=='string'){clip={url:clip};}extend(clip,conf.clip,true);conf.playlist[index]=clip;clip=new Clip(clip,index,self);playlist.push(clip);index++;});each(conf,function(key,val){if(typeof val=='function'){bind(listeners,key,val);delete conf[key];}});each(conf.plugins,function(name,val){if(val){plugins[name]=new Plugin(name,val,self);}});if(!conf.plugins||conf.plugins.controls===undefined){plugins.controls=new Plugin("controls",null,self);}params.bgcolor=params.bgcolor||"#000000";params.version=params.version||[9,0];params.expressInstall='http://www.flowplayer.org/swf/expressinstall.swf';function doClick(e){if(self._fireEvent("onBeforeClick")!==false){self.load();}return stopEvent(e);}html=wrapper.innerHTML;if(html.replace(/\s/g,'')!==''){if(wrapper.addEventListener){wrapper.addEventListener("click",doClick,false);}else if(wrapper.attachEvent){wrapper.attachEvent("onclick",doClick);}}else{if(wrapper.addEventListener){wrapper.addEventListener("click",stopEvent,false);}self.load();}}if(typeof wrapper=='string'){flashembed.domReady(function(){var node=el(wrapper);if(!node){throw"Flowplayer cannot access element: "+wrapper;}else{wrapper=node;init();}});}else{init();}}var players=[];function Iterator(arr){this.length=arr.length;this.each=function(fn){each(arr,fn);};this.size=function(){return arr.length;};}window.flowplayer=window.$f=function(){var instance=null;var arg=arguments[0];if(!arguments.length){each(players,function(){if(this.isLoaded()){instance=this;return false;}});return instance||players[0];}if(arguments.length==1){if(typeof arg=='number'){return players[arg];}else{if(arg=='*'){return new Iterator(players);}each(players,function(){if(this.id()==arg.id||this.id()==arg||this.getParent()==arg){instance=this;return false;}});return instance;}}if(arguments.length>1){var swf=arguments[1];var conf=(arguments.length==3)?arguments[2]:{};if(typeof arg=='string'){if(arg.indexOf(".")!=-1){var instances=[];each(select(arg),function(){instances.push(new Player(this,clone(swf),clone(conf)));});return new Iterator(instances);}else{var node=el(arg);return new Player(node!==null?node:arg,swf,conf);}}else if(arg){return new Player(arg,swf,conf);}}return null;};extend(window.$f,{fireEvent:function(id,evt,a0,a1,a2){var p=$f(id);return p?p._fireEvent(evt,a0,a1,a2):null;},addPlugin:function(name,fn){Player.prototype[name]=fn;return $f;},each:each,extend:extend});if(typeof jQuery=='function'){jQuery.prototype.flowplayer=function(params,conf){if(!arguments.length||typeof arguments[0]=='number'){var arr=[];this.each(function(){var p=$f(this);if(p){arr.push(p);}});return arguments.length?arr[arguments[0]]:new Iterator(arr);}return this.each(function(){$f(this,clone(params),conf?clone(conf):{});});};}})();(function(){var jQ=typeof jQuery=='function';function isDomReady(){if(domReady.done){return false;}var d=document;if(d&&d.getElementsByTagName&&d.getElementById&&d.body){clearInterval(domReady.timer);domReady.timer=null;for(var i=0;i<domReady.ready.length;i++){domReady.ready[i].call();}domReady.ready=null;domReady.done=true;}}var domReady=jQ?jQuery:function(f){if(domReady.done){return f();}if(domReady.timer){domReady.ready.push(f);}else{domReady.ready=[f];domReady.timer=setInterval(isDomReady,13);}};function extend(to,from){if(from){for(key in from){if(from.hasOwnProperty(key)){to[key]=from[key];}}}}function concatVars(vars){var out="";for(var key in vars){if(vars[key]){out+=[key]+'='+toString(vars[key])+'&';}}return out.substring(0,out.length-1);}function toString(obj){switch(typeOf(obj)){case'string':obj=obj.replace(new RegExp('(["\\\\])','g'),'\\$1');obj=obj.replace(/^\s?(\d+)%/,"$1pct");return'"'+obj+'"';case'array':return'['+map(obj,function(el){return toString(el);}).join(',')+']';case'function':return'"function()"';case'object':var str=[];for(var prop in obj){if(obj.hasOwnProperty(prop)){str.push('"'+prop+'":'+toString(obj[prop]));}}return'{'+str.join(',')+'}';}return String(obj).replace(/\s/g," ").replace(/\'/g,"\"");}function typeOf(obj){if(obj===null||obj===undefined){return false;}var type=typeof obj;return(type=='object'&&obj.push)?'array':type;}if(window.attachEvent){window.attachEvent("onbeforeunload",function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};});}function map(arr,func){var newArr=[];for(var i in arr){if(arr.hasOwnProperty(i)){newArr[i]=func(arr[i]);}}return newArr;}window.flashembed=function(root,userParams,flashvars){function getHTML(){var html="";if(typeof flashvars=='function'){flashvars=flashvars();}params.src+=((params.src.indexOf("?")!=-1?"&":"?")+Math.random());if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){html='<embed type="application/x-shockwave-flash" ';if(params.id){extend(params,{name:params.id});}for(var key in params){if(params[key]!==null){html+=[key]+'="'+params[key]+'"\n\t';}}if(flashvars){html+='flashvars=\''+concatVars(flashvars)+'\'';}html+='/>';}else{html='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';html+='width="'+params.width+'" height="'+params.height+'"';if(!params.id&&document.all){params.id="_"+(""+Math.random()).substring(5);}if(params.id){html+=' id="'+params.id+'"';}html+='>';html+='\n\t<param name="movie" value="'+params.src+'" />';params.id=params.src=params.width=params.height=null;for(var k in params){if(params[k]!==null){html+='\n\t<param name="'+k+'" value="'+params[k]+'" />';}}if(flashvars){html+='\n\t<param name="flashvars" value=\''+concatVars(flashvars)+'\' />';}html+="</object>";if(debug){alert(html);}}return html;}var params={src:'#',width:'100%',height:'100%',version:null,onFail:null,expressInstall:null,debug:false,allowfullscreen:true,allowscriptaccess:'always',quality:'high',type:'application/x-shockwave-flash',pluginspage:'http://www.adobe.com/go/getflashplayer'};if(typeof userParams=='string'){userParams={src:userParams};}extend(params,userParams);var version=flashembed.getVersion();var required=params.version;var express=params.expressInstall;var debug=params.debug;if(typeof root=='string'){var el=document.getElementById(root);if(el){root=el;}else{domReady(function(){flashembed(root,userParams,flashvars);});return;}}if(!root){return;}if(!required||flashembed.isSupported(required)){params.onFail=params.version=params.expressInstall=params.debug=null;root.innerHTML=getHTML();return root.firstChild;}else if(params.onFail){var ret=params.onFail.call(params,flashembed.getVersion(),flashvars);if(ret===true){root.innerHTML=ret;}}else if(required&&express&&flashembed.isSupported([6,65])){extend(params,{src:express});flashvars={MMredirectURL:location.href,MMplayerType:'PlugIn',MMdoctitle:document.title};root.innerHTML=getHTML();}else{if(root.innerHTML.replace(/\s/g,'')!==''){}else{root.innerHTML="<h2>Flash version "+required+" or greater is required</h2>"+"<h3>"+(version[0]>0?"Your version is "+version:"You have no flash plugin installed")+"</h3>"+"<p>Download latest version from <a href='"+params.pluginspage+"'>here</a></p>";}}return root;};extend(window.flashembed,{getVersion:function(){var version=[0,0];if(navigator.plugins&&typeof navigator.plugins["Shockwave Flash"]=="object"){var _d=navigator.plugins["Shockwave Flash"].description;if(typeof _d!="undefined"){_d=_d.replace(/^.*\s+(\S+\s+\S+$)/,"$1");var _m=parseInt(_d.replace(/^(.*)\..*$/,"$1"),10);var _r=/r/.test(_d)?parseInt(_d.replace(/^.*r(.*)$/,"$1"),10):0;version=[_m,_r];}}else if(window.ActiveXObject){try{var _a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{_a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");version=[6,0];_a.AllowScriptAccess="always";}catch(ee){if(version[0]==6){return;}}try{_a=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(eee){}}if(typeof _a=="object"){_d=_a.GetVariable("$version");if(typeof _d!="undefined"){_d=_d.replace(/^\S+\s+(.*)$/,"$1").split(",");version=[parseInt(_d[0],10),parseInt(_d[2],10)];}}}return version;},isSupported:function(version){var now=flashembed.getVersion();var ret=(now[0]>version[0])||(now[0]==version[0]&&now[1]>=version[1]);return ret;},domReady:domReady,toString:toString});if(jQ){jQuery.prototype.flashembed=function(params,flashvars){return this.each(function(){flashembed(this,params,flashvars);});};}})();
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer-3.0.0-rc2.min.js
___________________________________________________________________
Added: svn:eol-style
117 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer.controls-3.0.1.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer.controls-3.0.1.swf
___________________________________________________________________
Added: svn:mime-type
218 + application/octet-stream
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer-3.0.0-rc2.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer-3.0.0-rc2.swf
___________________________________________________________________
Added: svn:mime-type
319 + application/octet-stream
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer.pseudostreaming-3.0.0-beta3.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer.pseudostreaming-3.0.0-beta3.swf
___________________________________________________________________
Added: svn:mime-type
420 + application/octet-stream
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer-3.0.0-rc4.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer-3.0.0-rc4.swf
___________________________________________________________________
Added: svn:mime-type
521 + application/octet-stream
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/README.txt
@@ -0,0 +1,52 @@
 2+Version history:
 3+
 4+RC2
 5+---
 6+- fixed: setting the screen height in configuration did not have any effect
 7+
 8+RC1
 9+-----
 10+- better error message if plugin loading fails, shows the URL used
 11+- validates our redesigned multidomain license key correctly
 12+- fix to prevent the play button going visible when the onBufferEmpty event occurs
 13+- the commercial swf now correctly loads the controls using version information
 14+- fixed: the play button overlay became invisible with long fadeOutSpeeds
 15+
 16+beta6
 17+-----
 18+- removed the onFirstFramePause event
 19+- playing a clip for the second time caused a doubled sound
 20+- pausing on first frame did not work on some FLV files
 21+
 22+beta5
 23+-----
 24+- logo only uses percentage scaling if it's a SWF file (there is ".swf" in it's url)
 25+- context menu now correctly builds up from string entries in configuration
 26+-always closes the previous connection before starting a new clip
 27+
 28+beta4
 29+-----
 30+- now it's possible to load a plugin into the panel without specifying any position/dimensions
 31+ information, the plugin is placed to left: "50%", top: "50%" and using the plugin DisplayObject's width & height
 32+- The Flowplayer API was not fully initialized when onLoad was invoked on Flash plugins
 33+
 34+beta3
 35+-----
 36+- tweaking logo placement
 37+- "play" did not show up after repeated pause/resume
 38+- player now loads the latest controls SWF version, right now the latest SWF is called 'flowplayer.controls-3.0.0-beta2.swf'
 39+
 40+beta2
 41+-----
 42+- fixed support for RTMP stream groups
 43+- changed to loop through available fonts in order to find a suitable font also in IE
 44+- Preloader was broken on IE: When the player SWf was in browser's cache it did not initialize properly
 45+- Context menu now correctly handles menu items that are configured by their string labels only (not using json objects)
 46+- fixed custom logo positioning (was moved to the left edge of screen in fullscreen)
 47+- "play" now always follows the position and size of the screen
 48+- video was stretched below the controls in fullscreen when autoHide: 'never'
 49+- logo now takes 6.5% of the screen height, width is scaled so that the aspect ratio is preserved
 50+
 51+beta1
 52+-----
 53+- First public beta release
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/README.txt
___________________________________________________________________
Added: svn:eol-style
154 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer.controls-3.0.0-beta5.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer.controls-3.0.0-beta5.swf
___________________________________________________________________
Added: svn:mime-type
255 + application/octet-stream
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer-3.0.0-rc2.js
@@ -0,0 +1,1520 @@
 2+/**
 3+ * flowplayer.js 3.0.0-rc2. The Flowplayer API.
 4+ *
 5+ * This file is part of Flowplayer, http://flowplayer.org
 6+ *
 7+ * Author: Tero Piirainen, <support@flowplayer.org>
 8+ * Copyright (c) 2008 Flowplayer Ltd
 9+ *
 10+ * Released under the MIT License:
 11+ * http://www.opensource.org/licenses/mit-license.php
 12+ *
 13+ * Version: 3.0.0-rc2 - Fri Nov 07 2008 16:50:59 GMT-0000 (GMT+00:00)
 14+ */
 15+(function() {
 16+
 17+/*
 18+ FEATURES
 19+ --------
 20+ - handling multiple instances
 21+ - Flowplayer programming API
 22+ - Flowplayer event model
 23+ - player loading / unloading
 24+ - $f() function
 25+ - jQuery support
 26+*/
 27+
 28+
 29+/*jslint glovar: true, browser: true */
 30+/*global flowplayer, $f */
 31+
 32+// {{{ private utility methods
 33+
 34+ function log(args) {
 35+
 36+ // write into opera console
 37+ if (typeof opera == 'object') {
 38+ opera.postError("$f.fireEvent: " + args.join(" | "));
 39+
 40+
 41+ } else if (typeof console == 'object') {
 42+ console.log("$f.fireEvent", [].slice.call(args));
 43+ }
 44+ }
 45+
 46+
 47+ // thanks: http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone
 48+ function clone(obj) {
 49+ if (!obj || typeof obj != 'object') { return obj; }
 50+ var temp = new obj.constructor();
 51+ for (var key in obj) {
 52+ if (obj.hasOwnProperty(key)) {
 53+ temp[key] = clone(obj[key]);
 54+ }
 55+ }
 56+ return temp;
 57+ }
 58+
 59+ // stripped from jQuery, thanks John Resig
 60+ function each(obj, fn) {
 61+ if (!obj) { return; }
 62+
 63+ var name, i = 0, length = obj.length;
 64+
 65+ // object
 66+ if (length === undefined) {
 67+ for (name in obj) {
 68+ if (fn.call(obj[name], name, obj[name]) === false) { break; }
 69+ }
 70+
 71+ // array
 72+ } else {
 73+ for (var value = obj[0];
 74+ i < length && fn.call( value, i, value ) !== false; value = obj[++i]) {
 75+ }
 76+ }
 77+
 78+ return obj;
 79+ }
 80+
 81+
 82+ // convenience
 83+ function el(id) {
 84+ return document.getElementById(id);
 85+ }
 86+
 87+
 88+ // used extensively. a very simple implementation.
 89+ function extend(to, from, skipFuncs) {
 90+ if (to && from) {
 91+ each(from, function(name, value) {
 92+ if (!skipFuncs || typeof value != 'function') {
 93+ to[name] = value;
 94+ }
 95+ });
 96+ }
 97+ }
 98+
 99+ // var arr = select("elem.className");
 100+ function select(query) {
 101+ var index = query.indexOf(".");
 102+ if (index != -1) {
 103+ var tag = query.substring(0, index) || "*";
 104+ var klass = query.substring(index + 1, query.length);
 105+ var els = [];
 106+ each(document.getElementsByTagName(tag), function() {
 107+ if (this.className && this.className.indexOf(klass) != -1) {
 108+ els.push(this);
 109+ }
 110+ });
 111+ return els;
 112+ }
 113+ }
 114+
 115+ // fix event inconsistencies across browsers
 116+ function stopEvent(e) {
 117+ e = e || window.event;
 118+
 119+ if (e.preventDefault) {
 120+ e.stopPropagation();
 121+ e.preventDefault();
 122+
 123+ } else {
 124+ e.returnValue = false;
 125+ e.cancelBubble = true;
 126+ }
 127+ return false;
 128+ }
 129+
 130+ // push an event listener into existing array of listeners
 131+ function bind(to, evt, fn) {
 132+ to[evt] = to[evt] || [];
 133+ to[evt].push(fn);
 134+ }
 135+
 136+
 137+ // generates an unique id
 138+ function makeId() {
 139+ return "_" + ("" + Math.random()).substring(2, 10);
 140+ }
 141+
 142+//}}}
 143+
 144+
 145+// {{{ Clip
 146+
 147+ var Clip = function(json, index, player) {
 148+
 149+ // private variables
 150+ var self = this;
 151+ var cuepoints = {};
 152+ var listeners = {};
 153+ this.index = index;
 154+
 155+ // instance variables
 156+ if (typeof json == 'string') {
 157+ json = {url:json};
 158+ }
 159+
 160+ extend(this, json, true);
 161+
 162+ // event handling
 163+ each(("Start*,MetaData,Pause*,Resume*,Seek*,Stop*,Finish,LastSecond,Update,BufferFull,BufferEmpty").split(","),
 164+ function() {
 165+
 166+ var evt = "on" + this;
 167+
 168+ // before event
 169+ if (evt.indexOf("*") != -1) {
 170+ evt = evt.substring(0, evt.length -1);
 171+ var before = "onBefore" + evt.substring(2);
 172+
 173+ self[before] = function(fn) {
 174+ bind(listeners, before, fn);
 175+ return self;
 176+ };
 177+ }
 178+
 179+ self[evt] = function(fn) {
 180+ bind(listeners, evt, fn);
 181+ return self;
 182+ };
 183+
 184+
 185+ // set common clip event listeners to player level
 186+ if (index == -1) {
 187+ if (self[before]) {
 188+ player[before] = self[before];
 189+ }
 190+ if (self[evt]) {
 191+ player[evt] = self[evt];
 192+ }
 193+ }
 194+
 195+ });
 196+
 197+ extend(this, {
 198+
 199+
 200+ onCuepoint: function(points, fn) {
 201+
 202+ // embedded cuepoints
 203+ if (arguments.length == 1) {
 204+ cuepoints.embedded = [null, points];
 205+ return self;
 206+ }
 207+
 208+ if (typeof points == 'number') {
 209+ points = [points];
 210+ }
 211+
 212+ var fnId = makeId();
 213+ cuepoints[fnId] = [points, fn];
 214+
 215+ if (player.isLoaded()) {
 216+ player._api().fp_addCuepoints(points, index, fnId);
 217+ }
 218+
 219+ return self;
 220+ },
 221+
 222+ update: function(json) {
 223+ extend(self, json);
 224+
 225+ if (player.isLoaded()) {
 226+ player._api().fp_updateClip(json, index);
 227+ }
 228+ var conf = player._config();
 229+ var clip = (index == -1) ? conf.clip : conf.playlist[index];
 230+ extend(clip, json, true);
 231+ },
 232+
 233+
 234+ // internal event for performing clip tasks. should be made private someday
 235+ _fireEvent: function(evt, arg1, arg2, target) {
 236+
 237+ if (evt == 'onLoad') {
 238+ each(cuepoints, function(key, val) {
 239+ player._api().fp_addCuepoints(val[0], index, key);
 240+ });
 241+ return false;
 242+ }
 243+
 244+ // target clip we are working against
 245+ if (index != -1) {
 246+ target = self;
 247+ }
 248+
 249+ if (evt == 'onCuepoint') {
 250+ var fn = cuepoints[arg1];
 251+ if (fn) {
 252+ return fn[1].call(player, target, arg2);
 253+ }
 254+ }
 255+
 256+ if (evt == 'onMetaData' || evt == 'onUpdate') {
 257+
 258+ extend(target, arg1);
 259+
 260+ if (!target.duration) {
 261+ target.duration = arg1.metaData.duration;
 262+ } else {
 263+ target.fullDuration = arg1.metaData.duration;
 264+ }
 265+ }
 266+
 267+ var ret = true;
 268+ each(listeners[evt], function() {
 269+ ret = this.call(player, target, arg1);
 270+ });
 271+ return ret;
 272+ }
 273+
 274+ });
 275+
 276+
 277+ // get cuepoints from config
 278+ if (json.onCuepoint) {
 279+ self.onCuepoint.apply(self, json.onCuepoint);
 280+ delete json.onCuepoint;
 281+ }
 282+
 283+ // get other events
 284+ each(json, function(key, val) {
 285+ if (typeof val == 'function') {
 286+ bind(listeners, key, val);
 287+ delete json[key];
 288+ }
 289+ });
 290+
 291+
 292+ // setup common clip event callbacks for Player object too (shortcuts)
 293+ if (index == -1) {
 294+ player.onCuepoint = this.onCuepoint;
 295+ }
 296+
 297+ };
 298+
 299+//}}}
 300+
 301+
 302+// {{{ Plugin
 303+
 304+ var Plugin = function(name, json, player, fn) {
 305+
 306+ var listeners = {};
 307+ var self = this;
 308+ var hasMethods = false;
 309+
 310+ if (fn) {
 311+ extend(listeners, fn);
 312+ }
 313+
 314+ // custom callback functions in configuration
 315+ each(json, function(key, val) {
 316+ if (typeof val == 'function') {
 317+ listeners[key] = val;
 318+ delete json[key];
 319+ }
 320+ });
 321+
 322+ // core plugin methods
 323+ extend(this, {
 324+
 325+ animate: function(props, speed, fn) {
 326+ if (!props) {
 327+ return self;
 328+ }
 329+
 330+ if (typeof speed == 'function') {
 331+ fn = speed;
 332+ speed = 500;
 333+ }
 334+
 335+ if (typeof props == 'string') {
 336+ var key = props;
 337+ props = {};
 338+ props[key] = speed;
 339+ speed = 500;
 340+ }
 341+
 342+ if (fn) {
 343+ var fnId = makeId();
 344+ listeners[fnId] = fn;
 345+ }
 346+
 347+ if (speed === undefined) { speed = 500; }
 348+ json = player._api().fp_animate(name, props, speed, fnId);
 349+ return self;
 350+ },
 351+
 352+ css: function(props, val) {
 353+ if (val !== undefined) {
 354+ var css = {};
 355+ css[props] = val;
 356+ props = css;
 357+ }
 358+ json = player._api().fp_css(name, props);
 359+ extend(self, json);
 360+ return self;
 361+ },
 362+
 363+ show: function() {
 364+ this.display = 'block';
 365+ player._api().fp_showPlugin(name);
 366+ return self;
 367+ },
 368+
 369+ hide: function() {
 370+ this.display = 'none';
 371+ player._api().fp_hidePlugin(name);
 372+ return self;
 373+ },
 374+
 375+ toggle: function() {
 376+ this.display = player._api().fp_togglePlugin(name);
 377+ return self;
 378+ },
 379+
 380+ fadeTo: function(o, speed, fn) {
 381+
 382+ if (typeof speed == 'function') {
 383+ fn = speed;
 384+ speed = 500;
 385+ }
 386+
 387+ if (fn) {
 388+ var fnId = makeId();
 389+ listeners[fnId] = fn;
 390+ }
 391+ this.display = player._api().fp_fadeTo(name, o, speed, fnId);
 392+ this.opacity = o;
 393+ return self;
 394+ },
 395+
 396+ fadeIn: function(speed, fn) {
 397+ return self.fadeTo(1, speed, fn);
 398+ },
 399+
 400+ fadeOut: function(speed, fn) {
 401+ return self.fadeTo(0, speed, fn);
 402+ },
 403+
 404+ getName: function() {
 405+ return name;
 406+ },
 407+
 408+
 409+ // internal method not meant to be used by clients
 410+ _fireEvent: function(evt, arg) {
 411+
 412+
 413+ // update plugins properties & methods
 414+ if (evt == 'onUpdate') {
 415+ var json = arg || player._api().fp_getPlugin(name);
 416+ if (!json) { return; }
 417+
 418+ extend(self, json);
 419+ delete self.methods;
 420+
 421+ if (!hasMethods) {
 422+ each(json.methods, function() {
 423+ var method = "" + this;
 424+
 425+ self[method] = function() {
 426+ var a = [].slice.call(arguments);
 427+ var ret = player._api().fp_invoke(name, method, a);
 428+ return ret == 'undefined' ? self : ret;
 429+ };
 430+ });
 431+ hasMethods = true;
 432+ }
 433+ }
 434+
 435+ // plugin callbacks
 436+ var fn = listeners[evt];
 437+
 438+ if (fn) {
 439+
 440+ fn.call(self, arg);
 441+
 442+ // "one-shot" callback
 443+ if (evt.substring(0, 1) == "_") {
 444+ delete listeners[evt];
 445+ }
 446+ }
 447+ }
 448+
 449+ });
 450+
 451+ };
 452+
 453+
 454+//}}}
 455+
 456+
 457+function Player(wrapper, params, conf) {
 458+
 459+ // private variables (+ arguments)
 460+ var
 461+ self = this,
 462+ api = null,
 463+ html,
 464+ commonClip,
 465+ playlist = [],
 466+ plugins = {},
 467+ listeners = {},
 468+ playerId,
 469+ apiId,
 470+ activeIndex,
 471+ swfHeight;
 472+
 473+
 474+// {{{ public methods
 475+
 476+ extend(self, {
 477+
 478+ id: function() {
 479+ return playerId;
 480+ },
 481+
 482+ isLoaded: function() {
 483+ return (api !== null);
 484+ },
 485+
 486+ getParent: function() {
 487+ return wrapper;
 488+ },
 489+
 490+ hide: function() {
 491+ if (api) { api.style.height = "0px"; }
 492+ return self;
 493+ },
 494+
 495+ show: function() {
 496+ if (api) { api.style.height = swfHeight + "px"; }
 497+ return self;
 498+ },
 499+
 500+ isHidden: function() {
 501+ return api && parseInt(api.style.height, 10) === 0;
 502+ },
 503+
 504+
 505+ load: function(fn) {
 506+
 507+ if (!api && self._fireEvent("onBeforeLoad") !== false) {
 508+
 509+ // unload all instances
 510+ each(players, function() {
 511+ this.unload();
 512+ });
 513+
 514+ html = wrapper.innerHTML;
 515+ flashembed(wrapper, params, {config: conf});
 516+
 517+ // function argument
 518+ if (fn) {
 519+ fn.cached = true;
 520+ bind(listeners, "onLoad", fn);
 521+ }
 522+ }
 523+
 524+ return self;
 525+ },
 526+
 527+ unload: function() {
 528+
 529+ if (api && html.replace(/\s/g, '') !== '' && !api.fp_isFullscreen() &&
 530+ self._fireEvent("onBeforeUnload") !== false) {
 531+ api.fp_close();
 532+ wrapper.innerHTML = html;
 533+ self._fireEvent("onUnload");
 534+ api = null;
 535+ }
 536+
 537+ return self;
 538+ },
 539+
 540+ getClip: function(index) {
 541+ if (index === undefined) {
 542+ index = activeIndex;
 543+ }
 544+ return playlist[index];
 545+ },
 546+
 547+
 548+ getCommonClip: function() {
 549+ return commonClip;
 550+ },
 551+
 552+ getPlaylist: function() {
 553+ return playlist;
 554+ },
 555+
 556+ getPlugin: function(name) {
 557+ var plugin = plugins[name];
 558+
 559+ // create plugin if nessessary
 560+ if (!plugin && self.isLoaded()) {
 561+ var json = self._api().fp_getPlugin(name);
 562+ if (json) {
 563+ plugin = new Plugin(name, json, self);
 564+ plugins[name] = plugin;
 565+ }
 566+ }
 567+ return plugin;
 568+ },
 569+
 570+ getScreen: function() {
 571+ return self.getPlugin("screen");
 572+ },
 573+
 574+ getControls: function() {
 575+ return self.getPlugin("controls");
 576+ },
 577+
 578+ getConfig: function() {
 579+ return clone(conf);
 580+ },
 581+
 582+ getFlashParams: function() {
 583+ return params;
 584+ },
 585+
 586+ loadPlugin: function(name, url, props, fn) {
 587+
 588+ // properties not supplied
 589+ if (typeof props == 'function') {
 590+ fn = props;
 591+ props = {};
 592+ }
 593+
 594+ // if fn not given, make a fake id so that plugin's onUpdate get's fired
 595+ var fnId = fn ? makeId() : "_";
 596+ self._api().fp_loadPlugin(name, url, props, fnId);
 597+
 598+ // create new plugin
 599+ var arg = {};
 600+ arg[fnId] = fn;
 601+ var p = new Plugin(name, null, self, arg);
 602+ plugins[name] = p;
 603+ return p;
 604+ },
 605+
 606+
 607+ getState: function() {
 608+ return api ? api.fp_getState() : -1;
 609+ },
 610+
 611+ // "lazy" play
 612+ play: function(clip) {
 613+
 614+ function play() {
 615+ if (clip !== undefined) {
 616+ self._api().fp_play(clip);
 617+ } else {
 618+ self._api().fp_play();
 619+ }
 620+ }
 621+
 622+ if (api) {
 623+ play();
 624+
 625+ } else {
 626+ self.load(function() {
 627+ play();
 628+ });
 629+ }
 630+
 631+ return self;
 632+ },
 633+
 634+ getVersion: function() {
 635+ var js = "flowplayer.js 3.0.0-rc2";
 636+ if (api) {
 637+ var ver = api.fp_getVersion();
 638+ ver.push(js);
 639+ return ver;
 640+ }
 641+ return js;
 642+ },
 643+
 644+ _api: function() {
 645+ if (!api) {
 646+ throw "Flowplayer " +self.id()+ " not loaded. Try moving your call to player's onLoad event";
 647+ }
 648+ return api;
 649+ },
 650+
 651+ _config: function() {
 652+ return conf;
 653+ }
 654+
 655+ });
 656+
 657+
 658+ // event handlers
 659+ each(("Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,Fullscreen*,FullscreenExit,Error").split(","),
 660+ function() {
 661+ var name = "on" + this;
 662+
 663+ // before event
 664+ if (name.indexOf("*") != -1) {
 665+ name = name.substring(0, name.length -1);
 666+ var name2 = "onBefore" + name.substring(2);
 667+ self[name2] = function(fn) {
 668+ bind(listeners, name2, fn);
 669+ return self;
 670+ };
 671+ }
 672+
 673+ // normal event
 674+ self[name] = function(fn) {
 675+ bind(listeners, name, fn);
 676+ return self;
 677+ };
 678+ }
 679+ );
 680+
 681+
 682+ // core API methods
 683+ each(("pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,reset").split(","),
 684+ function() {
 685+ var name = this;
 686+
 687+ self[name] = function(arg) {
 688+ if (!api) { return self; }
 689+ var ret = (arg === undefined) ? api["fp_" + name]() : api["fp_" + name](arg);
 690+ return ret == 'undefined' ? self : ret;
 691+ };
 692+ }
 693+ );
 694+
 695+//}}}
 696+
 697+
 698+// {{{ public method: _fireEvent
 699+
 700+ self._fireEvent = function(evt, arg0, arg1, arg2) {
 701+
 702+ if (conf.debug) {
 703+ log(arguments);
 704+ }
 705+
 706+ // internal onLoad
 707+ if (evt == 'onLoad' && !api) {
 708+
 709+ api = api || el(apiId);
 710+ swfHeight = api.clientHeight;
 711+
 712+ each(playlist, function() {
 713+ this._fireEvent("onLoad");
 714+ });
 715+
 716+ each(plugins, function(name, p) {
 717+ p._fireEvent("onUpdate");
 718+ });
 719+
 720+
 721+ commonClip._fireEvent("onLoad");
 722+ }
 723+
 724+ if (evt == 'onContextMenu') {
 725+ each(conf.contextMenu[arg0], function(key, fn) {
 726+ fn.call(self);
 727+ });
 728+ return;
 729+ }
 730+
 731+ if (evt == 'onPluginEvent') {
 732+ var name = arg0.name || arg0;
 733+ var p = plugins[name];
 734+ if (p) {
 735+ if (arg0.name) {
 736+ p._fireEvent("onUpdate", arg0);
 737+ }
 738+ p._fireEvent(arg1);
 739+ }
 740+ return;
 741+ }
 742+
 743+ // onPlaylistReplace
 744+ if (evt == 'onPlaylistReplace') {
 745+ playlist = [];
 746+ var index = 0;
 747+ each(arg0, function() {
 748+ playlist.push(new Clip(this, index++));
 749+ });
 750+ }
 751+
 752+ var ret = true;
 753+
 754+ // clip event
 755+ if (arg0 === 0 || (arg0 && arg0 >= 0)) {
 756+
 757+ activeIndex = arg0;
 758+ var clip = playlist[arg0];
 759+
 760+ if (!clip || clip._fireEvent(evt, arg1, arg2) !== false) {
 761+
 762+ // clip argument is given for common clip, because it behaves as the target
 763+ ret = commonClip._fireEvent(evt, arg1, arg2, clip);
 764+ }
 765+ }
 766+
 767+ // player event
 768+ var i = 0;
 769+ each(listeners[evt], function() {
 770+ ret = this.call(self, arg0);
 771+
 772+ // remove cached entry
 773+ if (this.cached) {
 774+ listeners[evt].splice(i, 1);
 775+ }
 776+
 777+ // break loop
 778+ if (ret === false) { return false; }
 779+ i++;
 780+
 781+ });
 782+
 783+ return ret;
 784+ };
 785+
 786+//}}}
 787+
 788+
 789+// {{{ init
 790+
 791+ function init() {
 792+
 793+ if ($f(wrapper)) {
 794+ return null;
 795+ }
 796+
 797+ // register this player into global array of instances
 798+ players.push(self);
 799+
 800+
 801+ // flashembed parameters
 802+ if (typeof params == 'string') {
 803+ params = {src: params};
 804+ }
 805+
 806+ // playerId
 807+ playerId = wrapper.id || "fp" + makeId();
 808+ apiId = params.id || playerId + "_api";
 809+ params.id = apiId;
 810+ conf.playerId = playerId;
 811+
 812+
 813+ // plain url is given as config
 814+ if (typeof conf == 'string') {
 815+ conf = {clip:{url:conf}};
 816+ }
 817+
 818+ // common clip is always there
 819+ conf.clip = conf.clip || {};
 820+ commonClip = new Clip(conf.clip, -1, self);
 821+
 822+
 823+ // wrapper href as playlist
 824+ if (wrapper.getAttribute("href")) {
 825+ conf.playlist = [{url:wrapper.getAttribute("href", 2)}];
 826+ }
 827+
 828+ // playlist
 829+ conf.playlist = conf.playlist || [conf.clip];
 830+
 831+ var index = 0;
 832+ each(conf.playlist, function() {
 833+
 834+ var clip = this;
 835+
 836+ // clip is an array, we don't allow that
 837+ if (typeof clip == 'object' && clip.length) {
 838+ clip = "" + clip;
 839+ }
 840+
 841+ if (!clip.url && typeof clip == 'string') {
 842+ clip = {url: clip};
 843+ }
 844+
 845+ // populate common clip properties to each clip
 846+ extend(clip, conf.clip, true);
 847+
 848+ // modify configuration playlist
 849+ conf.playlist[index] = clip;
 850+
 851+ // populate playlist array
 852+ clip = new Clip(clip, index, self);
 853+ playlist.push(clip);
 854+ index++;
 855+ });
 856+
 857+
 858+ // event listeners
 859+ each(conf, function(key, val) {
 860+ if (typeof val == 'function') {
 861+ bind(listeners, key, val);
 862+ delete conf[key];
 863+ }
 864+ });
 865+
 866+
 867+ // plugins
 868+ each(conf.plugins, function(name, val) {
 869+ if (val) {
 870+ plugins[name] = new Plugin(name, val, self);
 871+ }
 872+ });
 873+
 874+
 875+ // setup controlbar plugin if not explicitly defined
 876+ if (!conf.plugins || conf.plugins.controls === undefined) {
 877+ plugins.controls = new Plugin("controls", null, self);
 878+ }
 879+
 880+ // Flowplayer uses black background by default
 881+ params.bgcolor = params.bgcolor || "#000000";
 882+
 883+
 884+ // setup default settings for express install
 885+ params.version = params.version || [9,0];
 886+ params.expressInstall = 'http://www.flowplayer.org/swf/expressinstall.swf';
 887+
 888+
 889+ // click function
 890+ function doClick(e) {
 891+ if (self._fireEvent("onBeforeClick") !== false) {
 892+ self.load();
 893+ }
 894+ return stopEvent(e);
 895+ }
 896+
 897+ // defer loading upon click
 898+ html = wrapper.innerHTML;
 899+ if (html.replace(/\s/g, '') !== '') {
 900+
 901+ if (wrapper.addEventListener) {
 902+ wrapper.addEventListener("click", doClick, false);
 903+
 904+ } else if (wrapper.attachEvent) {
 905+ wrapper.attachEvent("onclick", doClick);
 906+ }
 907+
 908+ // player is loaded upon page load
 909+ } else {
 910+
 911+ // prevent default action from wrapper (safari problem) loaded
 912+ if (wrapper.addEventListener) {
 913+ wrapper.addEventListener("click", stopEvent, false);
 914+ }
 915+
 916+ // load player
 917+ self.load();
 918+ }
 919+
 920+ }
 921+
 922+ // possibly defer initialization until DOM get's loaded
 923+ if (typeof wrapper == 'string') {
 924+ flashembed.domReady(function() {
 925+ var node = el(wrapper);
 926+
 927+ if (!node) {
 928+ throw "Flowplayer cannot access element: " + wrapper;
 929+ } else {
 930+ wrapper = node;
 931+ init();
 932+ }
 933+ });
 934+
 935+ // we have a DOM element so page is already loaded
 936+ } else {
 937+ init();
 938+ }
 939+
 940+
 941+//}}}
 942+
 943+
 944+}
 945+
 946+
 947+// {{{ flowplayer() & statics
 948+
 949+// container for player instances
 950+var players = [];
 951+
 952+
 953+// this object is returned when multiple player's are requested
 954+function Iterator(arr) {
 955+
 956+ this.length = arr.length;
 957+
 958+ this.each = function(fn) {
 959+ each(arr, fn);
 960+ };
 961+
 962+ this.size = function() {
 963+ return arr.length;
 964+ };
 965+}
 966+
 967+// these two variables are the only global variables
 968+window.flowplayer = window.$f = function() {
 969+
 970+ var instance = null;
 971+ var arg = arguments[0];
 972+
 973+
 974+ // $f()
 975+ if (!arguments.length) {
 976+ each(players, function() {
 977+ if (this.isLoaded()) {
 978+ instance = this;
 979+ return false;
 980+ }
 981+ });
 982+
 983+ return instance || players[0];
 984+ }
 985+
 986+ if (arguments.length == 1) {
 987+
 988+ // $f(index);
 989+ if (typeof arg == 'number') {
 990+ return players[arg];
 991+
 992+
 993+ // $f(wrapper || 'containerId' || '*');
 994+ } else {
 995+
 996+ // $f("*");
 997+ if (arg == '*') {
 998+ return new Iterator(players);
 999+ }
 1000+
 1001+ // $f(wrapper || 'containerId');
 1002+ each(players, function() {
 1003+ if (this.id() == arg.id || this.id() == arg || this.getParent() == arg) {
 1004+ instance = this;
 1005+ return false;
 1006+ }
 1007+ });
 1008+
 1009+ return instance;
 1010+ }
 1011+ }
 1012+
 1013+ // instance builder
 1014+ if (arguments.length > 1) {
 1015+
 1016+ var swf = arguments[1];
 1017+ var conf = (arguments.length == 3) ? arguments[2] : {};
 1018+
 1019+ if (typeof arg == 'string') {
 1020+
 1021+ // select arg by classname
 1022+ if (arg.indexOf(".") != -1) {
 1023+ var instances = [];
 1024+
 1025+ each(select(arg), function() {
 1026+ instances.push(new Player(this, clone(swf), clone(conf)));
 1027+ });
 1028+
 1029+ return new Iterator(instances);
 1030+
 1031+ // select node by id
 1032+ } else {
 1033+ var node = el(arg);
 1034+ return new Player(node !== null ? node : arg, swf, conf);
 1035+ }
 1036+
 1037+
 1038+ // arg is a DOM element
 1039+ } else if (arg) {
 1040+ return new Player(arg, swf, conf);
 1041+ }
 1042+
 1043+ }
 1044+
 1045+ return null;
 1046+};
 1047+
 1048+extend(window.$f, {
 1049+
 1050+ // called by Flash External Interface
 1051+ fireEvent: function(id, evt, a0, a1, a2) {
 1052+ var p = $f(id);
 1053+ return p ? p._fireEvent(evt, a0, a1, a2) : null;
 1054+ },
 1055+
 1056+
 1057+ // create plugins by modifying Player's prototype
 1058+ addPlugin: function(name, fn) {
 1059+ Player.prototype[name] = fn;
 1060+ return $f;
 1061+ },
 1062+
 1063+ // utility methods for plugin developers
 1064+ each: each,
 1065+
 1066+ extend: extend
 1067+
 1068+});
 1069+
 1070+//}}}
 1071+
 1072+
 1073+//{{{ jQuery support
 1074+
 1075+if (typeof jQuery == 'function') {
 1076+
 1077+ jQuery.prototype.flowplayer = function(params, conf) {
 1078+
 1079+ // select instances
 1080+ if (!arguments.length || typeof arguments[0] == 'number') {
 1081+ var arr = [];
 1082+ this.each(function() {
 1083+ var p = $f(this);
 1084+ if (p) {
 1085+ arr.push(p);
 1086+ }
 1087+ });
 1088+ return arguments.length ? arr[arguments[0]] : new Iterator(arr);
 1089+ }
 1090+
 1091+ // create flowplayer instances
 1092+ return this.each(function() {
 1093+ $f(this, clone(params), conf ? clone(conf) : {});
 1094+ });
 1095+
 1096+ };
 1097+
 1098+}
 1099+
 1100+//}}}
 1101+
 1102+
 1103+})();
 1104+/**
 1105+ * flashembed 0.33. Adobe Flash embedding script
 1106+ *
 1107+ * http://flowplayer.org/tools/flash-embed.html
 1108+ *
 1109+ * Copyright (c) 2008 Tero Piirainen (support@flowplayer.org)
 1110+ *
 1111+ * Released under the MIT License:
 1112+ * http://www.opensource.org/licenses/mit-license.php
 1113+ *
 1114+ * >> Basically you can do anything you want but leave this header as is <<
 1115+ *
 1116+ * first version 0.01 - 03/11/2008
 1117+ * version 0.33 - Mon Nov 03 2008 15:37:15 GMT-0000 (GMT+00:00)
 1118+ */
 1119+(function() {
 1120+
 1121+//{{{ utility functions
 1122+
 1123+var jQ = typeof jQuery == 'function';
 1124+
 1125+
 1126+// from "Pro JavaScript techniques" by John Resig
 1127+function isDomReady() {
 1128+ if (domReady.done) { return false; }
 1129+
 1130+ var d = document;
 1131+ if (d && d.getElementsByTagName && d.getElementById && d.body) {
 1132+ clearInterval(domReady.timer);
 1133+ domReady.timer = null;
 1134+
 1135+ for (var i = 0; i < domReady.ready.length; i++) {
 1136+ domReady.ready[i].call();
 1137+ }
 1138+
 1139+ domReady.ready = null;
 1140+ domReady.done = true;
 1141+ }
 1142+}
 1143+
 1144+// if jQuery is present, use it's more effective domReady method
 1145+var domReady = jQ ? jQuery : function(f) {
 1146+
 1147+ if (domReady.done) {
 1148+ return f();
 1149+ }
 1150+
 1151+ if (domReady.timer) {
 1152+ domReady.ready.push(f);
 1153+
 1154+ } else {
 1155+ domReady.ready = [f];
 1156+ domReady.timer = setInterval(isDomReady, 13);
 1157+ }
 1158+};
 1159+
 1160+
 1161+// override extend params function
 1162+function extend(to, from) {
 1163+ if (from) {
 1164+ for (key in from) {
 1165+ if (from.hasOwnProperty(key)) {
 1166+ to[key] = from[key];
 1167+ }
 1168+ }
 1169+ }
 1170+}
 1171+
 1172+
 1173+function concatVars(vars) {
 1174+ var out = "";
 1175+
 1176+ for (var key in vars) {
 1177+ if (vars[key]) {
 1178+ out += [key] + '=' + toString(vars[key]) + '&';
 1179+ }
 1180+ }
 1181+ return out.substring(0, out.length -1);
 1182+}
 1183+
 1184+
 1185+
 1186+// JSON.toString() function
 1187+function toString(obj) {
 1188+
 1189+ switch (typeOf(obj)){
 1190+ case 'string':
 1191+ obj = obj.replace(new RegExp('(["\\\\])', 'g'), '\\$1');
 1192+
 1193+ // flash does not handle %- characters well. transforms "50%" to "50pct" (a dirty hack, I admit)
 1194+ obj = obj.replace(/^\s?(\d+)%/, "$1pct");
 1195+ return '"' +obj+ '"';
 1196+
 1197+ case 'array':
 1198+ return '['+ map(obj, function(el) {
 1199+ return toString(el);
 1200+ }).join(',') +']';
 1201+
 1202+ case 'function':
 1203+ return '"function()"';
 1204+
 1205+ case 'object':
 1206+ var str = [];
 1207+ for (var prop in obj) {
 1208+ if (obj.hasOwnProperty(prop)) {
 1209+ str.push('"'+prop+'":'+ toString(obj[prop]));
 1210+ }
 1211+ }
 1212+ return '{'+str.join(',')+'}';
 1213+ }
 1214+
 1215+ // replace ' --> " and remove spaces
 1216+ return String(obj).replace(/\s/g, " ").replace(/\'/g, "\"");
 1217+}
 1218+
 1219+
 1220+// private functions
 1221+function typeOf(obj) {
 1222+ if (obj === null || obj === undefined) { return false; }
 1223+ var type = typeof obj;
 1224+ return (type == 'object' && obj.push) ? 'array' : type;
 1225+}
 1226+
 1227+
 1228+// version 9 bugfix: (http://blog.deconcept.com/2006/07/28/swfobject-143-released/)
 1229+if (window.attachEvent) {
 1230+ window.attachEvent("onbeforeunload", function() {
 1231+ __flash_unloadHandler = function() {};
 1232+ __flash_savedUnloadHandler = function() {};
 1233+ });
 1234+}
 1235+
 1236+function map(arr, func) {
 1237+ var newArr = [];
 1238+ for (var i in arr) {
 1239+ if (arr.hasOwnProperty(i)) {
 1240+ newArr[i] = func(arr[i]);
 1241+ }
 1242+ }
 1243+ return newArr;
 1244+}
 1245+
 1246+//}}}
 1247+
 1248+
 1249+window.flashembed = function(root, userParams, flashvars) {
 1250+
 1251+
 1252+//{{{ getHTML
 1253+
 1254+ function getHTML() {
 1255+
 1256+ var html = "";
 1257+ if (typeof flashvars == 'function') { flashvars = flashvars(); }
 1258+
 1259+
 1260+ // sometimes ie fails to load flash if it's on cache
 1261+ params.src += ((params.src.indexOf("?") != -1 ? "&" : "?") + Math.random());
 1262+
 1263+
 1264+ // mozilla
 1265+ if (navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length) {
 1266+
 1267+ html = '<embed type="application/x-shockwave-flash" ';
 1268+
 1269+ if (params.id) {
 1270+ extend(params, {name:params.id});
 1271+ }
 1272+
 1273+ for (var key in params) {
 1274+ if (params[key] !== null) {
 1275+ html += [key] + '="' +params[key]+ '"\n\t';
 1276+ }
 1277+ }
 1278+
 1279+ if (flashvars) {
 1280+ html += 'flashvars=\'' + concatVars(flashvars) + '\'';
 1281+ }
 1282+
 1283+ // thanks Tom Price (07/17/2008)
 1284+ html += '/>';
 1285+
 1286+ // ie
 1287+ } else {
 1288+
 1289+ html = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';
 1290+ html += 'width="' + params.width + '" height="' + params.height + '"';
 1291+
 1292+ // force id for IE. otherwise embedded Flash object cannot be returned
 1293+ if (!params.id && document.all) {
 1294+ params.id = "_" + ("" + Math.random()).substring(5);
 1295+ }
 1296+
 1297+ if (params.id) {
 1298+ html += ' id="' + params.id + '"';
 1299+ }
 1300+
 1301+ html += '>';
 1302+ html += '\n\t<param name="movie" value="'+ params.src +'" />';
 1303+
 1304+ params.id = params.src = params.width = params.height = null;
 1305+
 1306+ for (var k in params) {
 1307+ if (params[k] !== null) {
 1308+ html += '\n\t<param name="'+ k +'" value="'+ params[k] +'" />';
 1309+ }
 1310+ }
 1311+
 1312+ if (flashvars) {
 1313+ html += '\n\t<param name="flashvars" value=\'' + concatVars(flashvars) + '\' />';
 1314+ }
 1315+
 1316+ html += "</object>";
 1317+ if (debug) {
 1318+ alert(html);
 1319+ }
 1320+
 1321+ }
 1322+
 1323+ return html;
 1324+ }
 1325+
 1326+ //}}}
 1327+
 1328+
 1329+//{{{ construction
 1330+
 1331+ // setup params
 1332+ var params = {
 1333+
 1334+ // very common params
 1335+ src: '#',
 1336+ width: '100%',
 1337+ height: '100%',
 1338+
 1339+ // flashembed specific options
 1340+ version:null,
 1341+ onFail:null,
 1342+ expressInstall:null,
 1343+ debug: false,
 1344+
 1345+ // flashembed defaults
 1346+ // bgcolor: 'transparent',
 1347+ allowfullscreen: true,
 1348+ allowscriptaccess: 'always',
 1349+ quality: 'high',
 1350+ type: 'application/x-shockwave-flash',
 1351+ pluginspage: 'http://www.adobe.com/go/getflashplayer'
 1352+ };
 1353+
 1354+
 1355+ if (typeof userParams == 'string') {
 1356+ userParams = {src: userParams};
 1357+ }
 1358+
 1359+ extend(params, userParams);
 1360+
 1361+ var version = flashembed.getVersion();
 1362+ var required = params.version;
 1363+ var express = params.expressInstall;
 1364+ var debug = params.debug;
 1365+
 1366+
 1367+ if (typeof root == 'string') {
 1368+ var el = document.getElementById(root);
 1369+ if (el) {
 1370+ root = el;
 1371+ } else {
 1372+ domReady(function() {
 1373+ flashembed(root, userParams, flashvars);
 1374+ });
 1375+ return;
 1376+ }
 1377+ }
 1378+
 1379+ if (!root) { return; }
 1380+
 1381+
 1382+ // is supported
 1383+ if (!required || flashembed.isSupported(required)) {
 1384+ params.onFail = params.version = params.expressInstall = params.debug = null;
 1385+
 1386+ // root.innerHTML may cause broplems: http://domscripting.com/blog/display/99
 1387+ // thanks to: Ryan Rud
 1388+ // var tmp = document.createElement("extradiv");
 1389+ // tmp.innerHTML = getHTML();
 1390+ // root.appendChild(tmp);
 1391+
 1392+ root.innerHTML = getHTML();
 1393+
 1394+ // return our API
 1395+ return root.firstChild;
 1396+
 1397+ // custom fail event
 1398+ } else if (params.onFail) {
 1399+ var ret = params.onFail.call(params, flashembed.getVersion(), flashvars);
 1400+ if (ret === true) { root.innerHTML = ret; }
 1401+
 1402+
 1403+ // express install
 1404+ } else if (required && express && flashembed.isSupported([6,65])) {
 1405+
 1406+ extend(params, {src: express});
 1407+
 1408+ flashvars = {
 1409+ MMredirectURL: location.href,
 1410+ MMplayerType: 'PlugIn',
 1411+ MMdoctitle: document.title
 1412+ };
 1413+
 1414+ root.innerHTML = getHTML();
 1415+
 1416+ // not supported
 1417+ } else {
 1418+
 1419+ // minor bug fixed here 08.04.2008 (thanks JRodman)
 1420+
 1421+ if (root.innerHTML.replace(/\s/g, '') !== '') {
 1422+ // custom content was supplied
 1423+
 1424+ } else {
 1425+ root.innerHTML =
 1426+ "<h2>Flash version " + required + " or greater is required</h2>" +
 1427+ "<h3>" +
 1428+ (version[0] > 0 ? "Your version is " + version : "You have no flash plugin installed") +
 1429+ "</h3>" +
 1430+ "<p>Download latest version from <a href='" + params.pluginspage + "'>here</a></p>";
 1431+ }
 1432+ }
 1433+
 1434+ return root;
 1435+
 1436+//}}}
 1437+
 1438+
 1439+};
 1440+
 1441+
 1442+//{{{ static methods
 1443+
 1444+extend(window.flashembed, {
 1445+
 1446+ // arr[major, minor, fix]
 1447+ getVersion: function() {
 1448+
 1449+ var version = [0, 0];
 1450+
 1451+ if (navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object") {
 1452+ var _d = navigator.plugins["Shockwave Flash"].description;
 1453+ if (typeof _d != "undefined") {
 1454+ _d = _d.replace(/^.*\s+(\S+\s+\S+$)/, "$1");
 1455+ var _m = parseInt(_d.replace(/^(.*)\..*$/, "$1"), 10);
 1456+ var _r = /r/.test(_d) ? parseInt(_d.replace(/^.*r(.*)$/, "$1"), 10) : 0;
 1457+ version = [_m, _r];
 1458+ }
 1459+
 1460+ } else if (window.ActiveXObject) {
 1461+
 1462+ try { // avoid fp 6 crashes
 1463+ var _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");
 1464+
 1465+ } catch(e) {
 1466+ try {
 1467+ _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");
 1468+ version = [6, 0];
 1469+ _a.AllowScriptAccess = "always"; // throws if fp < 6.47
 1470+
 1471+ } catch(ee) {
 1472+ if (version[0] == 6) { return; }
 1473+ }
 1474+ try {
 1475+ _a = new ActiveXObject("ShockwaveFlash.ShockwaveFlash");
 1476+ } catch(eee) {
 1477+
 1478+ }
 1479+
 1480+ }
 1481+
 1482+ if (typeof _a == "object") {
 1483+ _d = _a.GetVariable("$version"); // bugs in fp 6.21 / 6.23
 1484+ if (typeof _d != "undefined") {
 1485+ _d = _d.replace(/^\S+\s+(.*)$/, "$1").split(",");
 1486+ version = [parseInt(_d[0], 10), parseInt(_d[2], 10)];
 1487+ }
 1488+ }
 1489+ }
 1490+
 1491+ return version;
 1492+ },
 1493+
 1494+ isSupported: function(version) {
 1495+ var now = flashembed.getVersion();
 1496+ var ret = (now[0] > version[0]) || (now[0] == version[0] && now[1] >= version[1]);
 1497+ return ret;
 1498+ },
 1499+
 1500+ domReady: domReady,
 1501+
 1502+ // returns a String representation from JSON object
 1503+ toString: toString
 1504+
 1505+});
 1506+
 1507+//}}}
 1508+
 1509+
 1510+// setup jquery support
 1511+if (jQ) {
 1512+
 1513+ jQuery.prototype.flashembed = function(params, flashvars) {
 1514+ return this.each(function() {
 1515+ flashembed(this, params, flashvars);
 1516+ });
 1517+ };
 1518+
 1519+}
 1520+
 1521+})();
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer-3.0.0-rc2.js
___________________________________________________________________
Added: svn:eol-style
11522 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer-3.0.1.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/flowplayer/flowplayer-3.0.1.swf
___________________________________________________________________
Added: svn:mime-type
21523 + application/octet-stream
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/hxmdct.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/hxmdct.swf
___________________________________________________________________
Added: svn:mime-type
31524 + application/octet-stream
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/ogg/EndOfOggStreamError.as
@@ -0,0 +1,29 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.ogg {
 21+
 22+ public class EndOfOggStreamError extends Error {
 23+
 24+ public function EndOfOggStreamError(message:String = null) {
 25+ super(message);
 26+ }
 27+
 28+ }
 29+
 30+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/ogg/EndOfOggStreamError.as
___________________________________________________________________
Added: svn:eol-style
131 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/ogg/LogicalOggStream.as
@@ -0,0 +1,72 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.ogg {
 21+
 22+ import org.omtk.util.BitByteArray;
 23+ import flash.utils.Endian;
 24+
 25+ public class LogicalOggStream {
 26+
 27+ private var source:UncachedUrlStream;
 28+
 29+ private var pageIndex:int;
 30+ private var currentPage:OggPage;
 31+ private var currentSegmentIndex:int;
 32+
 33+ public function LogicalOggStream(source:UncachedUrlStream) {
 34+ this.source = source;
 35+ }
 36+
 37+ public function getNextOggPacket(): OggPacket {
 38+
 39+ var res:BitByteArray = new BitByteArray();
 40+
 41+ var segmentLength:int = 0;
 42+
 43+ if(currentPage == null) {
 44+ currentPage = source.getNextOggPage();
 45+ }
 46+
 47+ do {
 48+ if(currentSegmentIndex >= currentPage.segmentOffsets.length) {
 49+ currentSegmentIndex=0;
 50+
 51+ if(currentPage.eos) {
 52+ throw new EndOfOggStreamError("End of OGG stream");
 53+ }
 54+
 55+ currentPage = source.getNextOggPage();
 56+ }
 57+
 58+ segmentLength = currentPage.segmentLengths[currentSegmentIndex];
 59+ res.writeBytes(currentPage.data, currentPage.segmentOffsets[currentSegmentIndex], segmentLength);
 60+ currentSegmentIndex++;
 61+ }
 62+ while(segmentLength==255);
 63+
 64+ res.position = 0;
 65+
 66+ var lastPacket: Boolean = currentPage.eos && currentSegmentIndex == currentPage.segmentOffsets.length;
 67+ var lastGranulePosition: int = currentPage.absoluteGranulePosition;
 68+
 69+ return new OggPacket(res, lastPacket, lastGranulePosition);
 70+ }
 71+
 72+ }
 73+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/ogg/LogicalOggStream.as
___________________________________________________________________
Added: svn:eol-style
174 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/ogg/OggPacket.as
@@ -0,0 +1,49 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.ogg {
 21+
 22+ import org.omtk.util.BitByteArray;
 23+
 24+ public class OggPacket {
 25+
 26+ private var _data: BitByteArray;
 27+ private var _lastPacket: Boolean;
 28+ private var _lastGranulePosition: int;
 29+
 30+ public function OggPacket(data: BitByteArray, lastPacket: Boolean, lastGranulePosition: int) {
 31+ _data = data;
 32+ _lastPacket = lastPacket;
 33+ _lastGranulePosition = lastGranulePosition;
 34+ }
 35+
 36+ public function get data(): BitByteArray {
 37+ return _data;
 38+ }
 39+
 40+ public function get lastPacket(): Boolean {
 41+ return _lastPacket;
 42+ }
 43+
 44+ public function get lastGranulePosition(): int {
 45+ return _lastGranulePosition;
 46+ }
 47+
 48+ }
 49+
 50+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/ogg/OggPacket.as
___________________________________________________________________
Added: svn:eol-style
151 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/ogg/OggPage.as
@@ -0,0 +1,116 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.ogg {
 21+
 22+ import flash.net.*;
 23+ import flash.utils.ByteArray;
 24+
 25+ public class OggPage {
 26+
 27+ private var _version:int;
 28+ private var _continued:Boolean;
 29+ private var _bos:Boolean;
 30+ private var _eos:Boolean;
 31+ private var _absoluteGranulePosition:int;
 32+ private var _streamSerialNumber:int;
 33+ private var _pageSequenceNumber:int;
 34+ private var _pageCheckSum:int;
 35+ private var _segmentOffsets:Array;
 36+ private var _segmentLengths:Array;
 37+ private var _totalLength:int;
 38+ private var _data:ByteArray;
 39+
 40+ public function OggPage(stream:URLStream) {
 41+
 42+ var capture:int = stream.readInt();
 43+ if(capture != 0x5367674f) {
 44+ throw new Error("Ogg page does not start with 'OggS': "+capture);
 45+ }
 46+
 47+ _version = stream.readByte()&0xff;
 48+ var tmp:int = stream.readByte();
 49+
 50+ _continued = (tmp&1)!=0;;
 51+ _bos = (tmp&2)!=0;
 52+ _eos = (tmp&4)!=0;
 53+
 54+ // absoluteGranulePosition is really 64 bits
 55+ _absoluteGranulePosition = stream.readUnsignedInt();
 56+ stream.readUnsignedInt(); // last 32 bits of _absoluteGranulePosition
 57+
 58+ _streamSerialNumber = stream.readUnsignedInt();
 59+ _pageSequenceNumber = stream.readUnsignedInt();
 60+ _pageCheckSum = stream.readUnsignedInt();
 61+
 62+ //trace("_pageSequenceNumber: " + _pageSequenceNumber);
 63+
 64+ var pageSegments:int = stream.readUnsignedByte();
 65+
 66+ //stream.waitFor(pageSegments);
 67+
 68+ _segmentOffsets = [];
 69+ _segmentLengths = [];
 70+ _data = new ByteArray();
 71+
 72+ var totalLength:int;
 73+
 74+ var i:int;
 75+ var l:int;
 76+
 77+ for( i= 0 ; i < pageSegments ; i++ ) {
 78+ l = stream.readUnsignedByte();
 79+ _segmentLengths.push( l );
 80+ _segmentOffsets.push( totalLength );
 81+ totalLength += l;
 82+ }
 83+
 84+ stream.readBytes(_data, 0, totalLength);
 85+ }
 86+
 87+ public function get absoluteGranulePosition():int {
 88+ return _absoluteGranulePosition;
 89+ }
 90+
 91+ public function get segmentOffsets():Array {
 92+ return _segmentOffsets;
 93+ }
 94+
 95+ public function get segmentLengths():Array {
 96+ return _segmentLengths;
 97+ }
 98+
 99+ public function get data():ByteArray {
 100+ return _data;
 101+ }
 102+
 103+ public function get eos():Boolean {
 104+ return _eos;
 105+ }
 106+
 107+ public function get bos():Boolean {
 108+ return _bos;
 109+ }
 110+
 111+ public function get continued():Boolean {
 112+ return _continued;
 113+ }
 114+
 115+ }
 116+
 117+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/ogg/OggPage.as
___________________________________________________________________
Added: svn:eol-style
1118 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/ogg/UncachedUrlStream.as
@@ -0,0 +1,52 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.ogg {
 21+
 22+ import flash.net.*;
 23+ import flash.utils.Endian;
 24+ import flash.events.HTTPStatusEvent;
 25+ import flash.events.ProgressEvent;
 26+
 27+ public class UncachedUrlStream {
 28+
 29+ private var source:URLStream;
 30+
 31+ public function UncachedUrlStream(source: URLStream) {
 32+ this.source = source;
 33+ }
 34+
 35+ public function get bytesAvailable():int {
 36+ return source.bytesAvailable;
 37+ }
 38+
 39+ public function addEventListener(type:String, listener:Function):void {
 40+ source.addEventListener(type, listener);
 41+ }
 42+
 43+ public function getLogicalOggStream():LogicalOggStream {
 44+ return new LogicalOggStream(this);
 45+ }
 46+
 47+ public function getNextOggPage():OggPage {
 48+ return new OggPage(source);
 49+ }
 50+
 51+ }
 52+
 53+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/ogg/UncachedUrlStream.as
___________________________________________________________________
Added: svn:eol-style
154 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/util/HuffmanNode.as
@@ -0,0 +1,92 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+package org.omtk.util {
 20+
 21+ public class HuffmanNode {
 22+
 23+ private var _parent:HuffmanNode;
 24+
 25+ public var _o0:HuffmanNode;
 26+ public var _o1:HuffmanNode;
 27+
 28+ private var _depth:int;
 29+
 30+ public var _value:int;
 31+ public var hasValue: Boolean;
 32+ private var _full:Boolean = false;
 33+
 34+ public function HuffmanNode(parent:HuffmanNode = null, value:int = -1) {
 35+ _parent = parent;
 36+ if(_parent != null) {
 37+ _depth = _parent.depth+1;
 38+ }
 39+ _value = value;
 40+ _full = value >= 0;
 41+ hasValue = value >= 0;
 42+ }
 43+
 44+ public function setNewValue(depth:int, value:uint):Boolean {
 45+ if (full) {
 46+ return false;
 47+ }
 48+ if (depth == 1) {
 49+ if (_o0 == null) {
 50+ _o0 = new HuffmanNode(this, value);
 51+ return true;
 52+ } else if (_o1 == null) {
 53+ _o1 = new HuffmanNode(this, value);
 54+ return true;
 55+ } else {
 56+ return false;
 57+ }
 58+ } else {
 59+ return o0.setNewValue(depth - 1, value)
 60+ ? true : o1.setNewValue(depth - 1, value);
 61+ }
 62+ }
 63+
 64+ public function get value():uint {
 65+ return _value;
 66+ }
 67+
 68+ public function get o0():HuffmanNode {
 69+ if(_o0 == null) {
 70+ _o0 = new HuffmanNode(this);
 71+ }
 72+ return _o0;
 73+ }
 74+
 75+ public function get o1():HuffmanNode {
 76+ if(_o1 == null) {
 77+ _o1 = new HuffmanNode(this);
 78+ }
 79+ return _o1;
 80+ }
 81+
 82+ public function get depth():int {
 83+ return _depth;
 84+ }
 85+
 86+ public function get full():Boolean {
 87+ return _full ? true
 88+ : (_full = (_o0 != null && _o0.full && _o1 != null && _o1.full));
 89+ }
 90+
 91+ }
 92+
 93+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/util/HuffmanNode.as
___________________________________________________________________
Added: svn:eol-style
194 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/util/BitByteArray.as
@@ -0,0 +1,75 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.util {
 21+
 22+ import flash.utils.ByteArray;
 23+ import flash.utils.Endian;
 24+ import flash.errors.IllegalOperationError;
 25+
 26+ public class BitByteArray extends ByteArray {
 27+
 28+ private var currentByte:uint;
 29+ private var bitIndex:int = 8;
 30+
 31+ public function BitByteArray() {
 32+ this.endian = Endian.LITTLE_ENDIAN;
 33+ }
 34+
 35+ public function readBit():Boolean {
 36+ if (bitIndex > 7) {
 37+ bitIndex = 0;
 38+ currentByte = readUnsignedByte();
 39+ }
 40+ return (currentByte & (1 << (bitIndex++))) != 0;
 41+ }
 42+
 43+ public function readUnsignedBitwiseInt(bits:int):uint {
 44+
 45+ var res:uint = 0;
 46+
 47+ for (var i : int = 0; i < bits; i++) {
 48+ if (bitIndex > 7) {
 49+ bitIndex = 0;
 50+ currentByte = readUnsignedByte();
 51+ }
 52+ if((currentByte & (1 << (bitIndex++))) != 0) {
 53+ res |= (1 << i);
 54+ }
 55+ }
 56+
 57+ return res;
 58+ }
 59+
 60+ public function readUnsignedHuffmanInt(root:HuffmanNode):uint {
 61+
 62+ while (!root.hasValue) {
 63+ if (bitIndex > 7) {
 64+ bitIndex = 0;
 65+ currentByte = readUnsignedByte();
 66+ }
 67+ root = (currentByte & (1 << (bitIndex++))) != 0 ? root._o1 : root._o0;
 68+ }
 69+
 70+ return root._value;
 71+ }
 72+
 73+ }
 74+
 75+
 76+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/util/BitByteArray.as
___________________________________________________________________
Added: svn:eol-style
177 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Mode.as
@@ -0,0 +1,70 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.errors.IllegalOperationError;
 23+ import flash.utils.Dictionary;
 24+ import org.omtk.util.BitByteArray;
 25+
 26+ public class Mode
 27+ {
 28+ private var _blockFlag:Boolean;
 29+ private var _windowType:uint;
 30+ private var _transformType:uint;
 31+ private var _mapping:uint;
 32+
 33+ public function Mode(source:BitByteArray, header:SetupHeader) {
 34+
 35+ _blockFlag=source.readBit();
 36+ _windowType=source.readUnsignedBitwiseInt(16);
 37+ _transformType=source.readUnsignedBitwiseInt(16);
 38+ _mapping=source.readUnsignedBitwiseInt(8);
 39+
 40+ if(_windowType!=0) {
 41+ throw new Error("Window type = "+windowType+", != 0");
 42+ }
 43+
 44+ if(_transformType!=0) {
 45+ throw new Error("Transform type = "+transformType+", != 0");
 46+ }
 47+
 48+ if(_mapping > header.mappings.length) {
 49+ throw new Error("Mode mapping number is higher than total number of mappings.");
 50+ }
 51+ }
 52+
 53+ public function get blockFlag():Boolean {
 54+ return _blockFlag;
 55+ }
 56+
 57+ public function get windowType():uint {
 58+ return _windowType;
 59+ }
 60+
 61+ public function get transformType():uint {
 62+ return _transformType;
 63+ }
 64+
 65+ public function get mapping():uint {
 66+ return _mapping;
 67+ }
 68+
 69+ }
 70+
 71+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Mode.as
___________________________________________________________________
Added: svn:eol-style
172 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/CodeBook.as
@@ -0,0 +1,223 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.errors.IllegalOperationError;
 23+ import org.omtk.util.*;
 24+
 25+ public class CodeBook {
 26+
 27+ private var entries:uint;
 28+ private var entryLengths:Vector.<int>;
 29+ private var valueVector:Vector.<Vector.<Number>>;
 30+
 31+ private var codeBookLookupType:int = -1;
 32+
 33+ public var huffmanRoot:HuffmanNode;
 34+ public var dimensions:uint;
 35+
 36+ public function CodeBook( source: BitByteArray ) {
 37+
 38+ var i:int;
 39+ var j:int;
 40+
 41+ var syncPattern:uint = source.readUnsignedBitwiseInt(24);
 42+ if(syncPattern !=0x564342) {
 43+ throw new IllegalOperationError("Illegal codebook sync pattern: "+syncPattern);
 44+ }
 45+
 46+ dimensions = source.readUnsignedBitwiseInt(16);
 47+ entries = source.readUnsignedBitwiseInt(24);
 48+
 49+ entryLengths = new Vector.<int>(entries);
 50+
 51+ var ordered:Boolean = source.readBit();
 52+
 53+ if(ordered) {
 54+ var cl:int = source.readUnsignedBitwiseInt(5)+1;
 55+ for(i=0; i<entryLengths.length; ) {
 56+ var num:int = source.readUnsignedBitwiseInt(Util.ilog(entryLengths.length-i));
 57+ if(i+num>entryLengths.length) {
 58+ throw new Error("The codebook entry length list is longer than the actual number of entry lengths.");
 59+ }
 60+ for(j=i; j<i+num; j++) {
 61+ entryLengths[j] = cl;
 62+ }
 63+ //Arrays.fill(entryLengths, i, i+num, cl);
 64+ cl++;
 65+ i+=num;
 66+ }
 67+ }
 68+ else {
 69+ // !ordered
 70+ var sparse:Boolean = source.readBit();
 71+
 72+ if(sparse) {
 73+ for(i=0; i<entryLengths.length; i++) {
 74+ if(source.readBit()) {
 75+ entryLengths[i]=source.readUnsignedBitwiseInt(5)+1;
 76+ }
 77+ else {
 78+ entryLengths[i]=-1;
 79+ }
 80+ }
 81+ }
 82+ else {
 83+ // !sparse
 84+ //Alert.show("entryLengths.length: "+entryLengths.length, "CodeBook");
 85+ for(i=0; i<entryLengths.length; i++) {
 86+ entryLengths[i]=source.readUnsignedBitwiseInt(5)+1;
 87+ }
 88+ }
 89+
 90+ }
 91+
 92+ if (!createHuffmanTree(entryLengths)) {
 93+ throw new Error("An exception was thrown when building the codebook Huffman tree.");
 94+ }
 95+
 96+ codeBookLookupType = source.readUnsignedBitwiseInt(4);
 97+
 98+ switch(codeBookLookupType) {
 99+ case 0:
 100+ // codebook has no scalar vectors to be calculated
 101+ break;
 102+ case 1:
 103+ case 2:
 104+ var codeBookMinimumValue:Number = Util.float32unpack(source.readUnsignedBitwiseInt(32));
 105+ var codeBookDeltaValue:Number = Util.float32unpack(source.readUnsignedBitwiseInt(32));
 106+
 107+ var codeBookValueBits:uint = source.readUnsignedBitwiseInt(4)+1;
 108+ var codeBookSequenceP:Boolean = source.readBit();
 109+
 110+ var codeBookLookupValues:uint = 0;
 111+
 112+ if(codeBookLookupType==1) {
 113+ codeBookLookupValues=Util.lookup1Values(entries, dimensions);
 114+ }
 115+ else {
 116+ codeBookLookupValues=entries*dimensions;
 117+ }
 118+
 119+ var codeBookMultiplicands:Vector.<int> = new Vector.<int>(codeBookLookupValues);
 120+
 121+ for(i=0; i < codeBookMultiplicands.length; i++) {
 122+ codeBookMultiplicands[i]=source.readUnsignedBitwiseInt(codeBookValueBits);
 123+ }
 124+
 125+ valueVector = new Vector.<Vector.<Number>>(entries);
 126+
 127+ if(codeBookLookupType==1) {
 128+ for(i=0; i<entries; i++) {
 129+ valueVector[i] = new Vector.<Number>(dimensions);
 130+ var last:Number = 0.0;
 131+ var indexDivisor:uint = 1;
 132+ for(j=0; j<dimensions; j++) {
 133+ var multiplicandOffset:int = (i/indexDivisor)%codeBookLookupValues;
 134+ valueVector[i][j]=
 135+ codeBookMultiplicands[multiplicandOffset]*codeBookDeltaValue+codeBookMinimumValue+last;
 136+ if(codeBookSequenceP) {
 137+ last = valueVector[i][j];
 138+ }
 139+ indexDivisor*=codeBookLookupValues;
 140+ }
 141+ }
 142+ }
 143+ else {
 144+ throw new Error("Unsupported codebook lookup type: "+codeBookLookupType);
 145+ /** @todo implement */
 146+ }
 147+ break;
 148+ default:
 149+ throw new Error("Unsupported codebook lookup type: "+codeBookLookupType);
 150+ }
 151+ }
 152+
 153+ private function createHuffmanTree(entryLengths:Vector.<int>):Boolean {
 154+
 155+ var i:int;
 156+
 157+ huffmanRoot = new HuffmanNode();
 158+ for(i=0; i<entryLengths.length; i++) {
 159+ var el:int = entryLengths[i];
 160+ if(el>0) {
 161+ if(!huffmanRoot.setNewValue(el, i)) {
 162+ return false;
 163+ }
 164+ }
 165+ }
 166+ return true;
 167+ }
 168+
 169+
 170+ public function readVvAdd(a0:Vector.<Number>, a1:Vector.<Number>, left:Boolean, right:Boolean, source:BitByteArray, offset:int, length:int):void {
 171+
 172+ var i:int;
 173+ var j:int;
 174+
 175+ if (!left && !right) {
 176+ return;
 177+ }
 178+
 179+ // 1 or 2 channels
 180+ var ch:int =
 181+ left && right ? 2 : 1;
 182+
 183+ var lim:int;
 184+ var ix:int;
 185+ var ve:Vector.<Number>;
 186+
 187+ if(left && right) {
 188+ lim = (offset + length) / 2;
 189+ var chptr:int = 0;
 190+ for (i = offset / 2; i < lim;) {
 191+ ix = source.readUnsignedHuffmanInt(huffmanRoot);
 192+ ve = valueVector[ix];
 193+ for (j = 0; j < dimensions; j++) {
 194+ if(chptr == 0) {
 195+ a0[i] += ve[j];
 196+ }
 197+ else {
 198+ a1[i] += ve[j];
 199+ }
 200+ chptr++;
 201+ if(chptr == 2) {
 202+ chptr = 0;
 203+ i++;
 204+ }
 205+ }
 206+ }
 207+ }
 208+ else {
 209+ var a : Vector.<Number> = left ? a0 : a1;
 210+ lim = offset + length;
 211+ for (i = offset; i < lim;) {
 212+ ve = valueVector[source.readUnsignedHuffmanInt(huffmanRoot)];
 213+ for (j = 0; j < dimensions; j++) {
 214+ a[i] += ve[j];
 215+ i++;
 216+ }
 217+ }
 218+ }
 219+
 220+ }
 221+
 222+ }
 223+
 224+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/CodeBook.as
___________________________________________________________________
Added: svn:eol-style
1225 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Mdct.as
@@ -0,0 +1,62 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.events.*;
 23+ import flash.system.*;
 24+ import flash.display.*;
 25+ import flash.net.*;
 26+ import flash.utils.getTimer;
 27+
 28+ /*
 29+ * Wrapper for the haXe compiled class org.omtk.vorbis.MdctHX
 30+ */
 31+ public class Mdct {
 32+
 33+ public static var initialized : Boolean = false;
 34+ private static var hxClass : Class;
 35+
 36+ public static function initialize() : void {
 37+ var ldr:Loader = new Loader();
 38+ var swfUrl:String = "hxmdct.swf";
 39+ var req:URLRequest = new URLRequest(swfUrl);
 40+ var ldrContext:LoaderContext =
 41+ new LoaderContext(false, ApplicationDomain.currentDomain);
 42+ ldr.load(req, ldrContext);
 43+ ldr.contentLoaderInfo.addEventListener(Event.COMPLETE, swfLoaded);
 44+
 45+ function swfLoaded(e:Event):void {
 46+ hxClass = ApplicationDomain.currentDomain.getDefinition("org.omtk.vorbis.MdctHX") as Class;
 47+ initialized = true;
 48+ }
 49+ }
 50+
 51+ private var delegate : Object;
 52+
 53+ public function Mdct(n:int) {
 54+ delegate = new hxClass(n);
 55+ }
 56+
 57+ public function imdct(frq:Vector.<Number>, window:Vector.<Number>, pcm:Vector.<Number>):void {
 58+ delegate.imdct(frq, window, pcm);
 59+ }
 60+
 61+ }
 62+
 63+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Mdct.as
___________________________________________________________________
Added: svn:eol-style
164 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/AudioPacket.as
@@ -0,0 +1,340 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.utils.getTimer;
 23+ import flash.utils.ByteArray;
 24+ import org.omtk.ogg.*;
 25+ import org.omtk.util.BitByteArray;
 26+
 27+ public class AudioPacket {
 28+
 29+ private var modeNumber:int;
 30+ private var mode:Mode;
 31+ private var mapping:Mapping;
 32+ private var n:int;
 33+
 34+ private var blockFlag:Boolean;
 35+ private var previousWindowFlag:Boolean;
 36+ private var nextWindowFlag:Boolean;
 37+
 38+ private var windowCenter:int;
 39+ private var leftWindowStart:int;
 40+ private var leftWindowEnd:int;
 41+ private var leftN:int;
 42+ private var rightWindowStart:int;
 43+ private var rightWindowEnd:int;
 44+ private var rightN:int;
 45+
 46+ private var window:Vector.<Number>;
 47+ private var freq0:Vector.<Number>;
 48+ private var freq1:Vector.<Number>;
 49+ private var pcm0:Vector.<Number>;
 50+ private var pcm1:Vector.<Number>;
 51+
 52+ private var channelFloors:Vector.<Floor>;
 53+ private var noResidues:Vector.<Boolean>;
 54+
 55+ private var _lastPacket: Boolean;
 56+ private var _lastGranulePosition: int;
 57+
 58+ public function AudioPacket(vorbis:VorbisStream, packet: OggPacket, currentGranulePosition: int) {
 59+
 60+ var source: BitByteArray = packet.data;
 61+ _lastPacket = packet.lastPacket;
 62+ _lastGranulePosition = packet.lastGranulePosition;
 63+
 64+ var i:int;
 65+ var j:int;
 66+ var k:int;
 67+
 68+ var sHeader:SetupHeader = vorbis.setupHeader;
 69+ var iHeader:IdentificationHeader = vorbis.identificationHeader;
 70+ var modes:Vector.<Mode> = sHeader.modes;
 71+ var mappings:Vector.<Mapping> = sHeader.mappings;
 72+ var residues:Vector.<Residue> = sHeader.residues;
 73+ var channels:int = iHeader.channels;
 74+
 75+ if (source.readUnsignedBitwiseInt(1) != 0) {
 76+ throw new Error("Packet type mismatch when trying to create an audio packet.");
 77+ }
 78+
 79+ modeNumber = source.readUnsignedBitwiseInt(Util.ilog(modes.length - 1));
 80+
 81+ mode = modes[modeNumber];
 82+
 83+ if(mode == null) {
 84+ throw new Error("Reference to invalid mode in audio packet.");
 85+ }
 86+
 87+ mapping = mappings[mode.mapping];
 88+
 89+ var magnitudes:Vector.<int> = mapping.magnitudes;
 90+ var angles:Vector.<int> = mapping.angles;
 91+
 92+ blockFlag = mode.blockFlag;
 93+
 94+ var blockSize0:int = iHeader.blockSize0;
 95+ var blockSize1:int = iHeader.blockSize1;
 96+
 97+ n = blockFlag ? blockSize1 : blockSize0;
 98+
 99+ if (blockFlag) {
 100+ previousWindowFlag = source.readBit();
 101+ nextWindowFlag = source.readBit();
 102+ }
 103+
 104+ windowCenter = n / 2;
 105+
 106+ if (blockFlag && !previousWindowFlag) {
 107+ leftWindowStart = n / 4 - blockSize0 / 4;
 108+ leftWindowEnd = n / 4 + blockSize0 / 4;
 109+ leftN = blockSize0 / 2;
 110+ } else {
 111+ leftWindowStart = 0;
 112+ leftWindowEnd = n / 2;
 113+ leftN = windowCenter;
 114+ }
 115+
 116+ if (blockFlag && !nextWindowFlag) {
 117+ rightWindowStart = n * 3 / 4 - blockSize0 / 4;
 118+ rightWindowEnd = n * 3 / 4 + blockSize0 / 4;
 119+ rightN = blockSize0 / 2;
 120+ } else {
 121+ rightWindowStart = windowCenter;
 122+ rightWindowEnd = n;
 123+ rightN = n / 2;
 124+ }
 125+
 126+ window = getComputedWindow(vorbis);
 127+
 128+ channelFloors = new Vector.<Floor>(channels, true);
 129+ noResidues = new Vector.<Boolean>(channels, true);
 130+
 131+ freq0 = new Vector.<Number>(n, true);
 132+ freq1 = new Vector.<Number>(n, true);
 133+ pcm0 = new Vector.<Number>(n, true);
 134+ pcm1 = new Vector.<Number>(n, true);
 135+
 136+ var allFloorsEmpty: Boolean = true;
 137+ var submapNumber: int;
 138+ var floorNumber: int;
 139+ var decodedFloor: Floor;
 140+
 141+ for(i = 0; i < channels; i++) {
 142+ submapNumber = mapping.mux[i];
 143+ floorNumber = mapping.submapFloors[submapNumber];
 144+ decodedFloor = sHeader.floors[floorNumber].decodeFloor(vorbis, source);
 145+ channelFloors[i] = decodedFloor;
 146+ noResidues[i] = decodedFloor == null;
 147+ if (decodedFloor != null) {
 148+ allFloorsEmpty = false;
 149+ }
 150+ }
 151+
 152+ if(allFloorsEmpty) {
 153+ return;
 154+ }
 155+
 156+ var mag: int;
 157+ var ang: int;
 158+
 159+ for(i = 0; i < magnitudes.length; i++) {
 160+ mag = magnitudes[i];
 161+ ang = angles[i];
 162+ if (!noResidues[mag] || !noResidues[ang]) {
 163+ noResidues[mag] = false;
 164+ noResidues[ang] = false;
 165+ }
 166+ }
 167+
 168+ var ch: int;
 169+ var doNotDecodeFlags: Vector.<Boolean>;
 170+ var residue:Residue;
 171+
 172+ for(i = 0; i < mapping.submaps; i++) {
 173+
 174+ doNotDecodeFlags = new Vector.<Boolean>();
 175+
 176+ for(j = 0; j < channels; j++) {
 177+ if(mapping.mux[j] == i) {
 178+ doNotDecodeFlags.push(noResidues[j]);
 179+ }
 180+ }
 181+
 182+ residue = residues[mapping.submapResidues[i]];
 183+
 184+ residue.decodeResidue(vorbis, source, mode, ch, doNotDecodeFlags, freq0, freq1);
 185+ }
 186+
 187+ var a: Number;
 188+ var m: Number;
 189+
 190+ for(i = mapping.couplingSteps - 1; i >= 0; i--) {
 191+
 192+ mag = magnitudes[i];
 193+ ang = angles[i];
 194+
 195+ for (j = 0; j < freq0.length; j++) {
 196+
 197+ a = ang == 0 ? freq0[j] : freq1[j];
 198+ m = mag == 0 ? freq0[j] : freq1[j];
 199+
 200+ if(a > 0) {
 201+ if(ang == 0) {
 202+ freq0[j] = m > 0 ? m - a : m + a;
 203+ }
 204+ else {
 205+ freq1[j] = m > 0 ? m - a : m + a;
 206+ }
 207+ }
 208+ else {
 209+ if(mag == 0) {
 210+ freq0[j] = m > 0 ? m + a : m - a;
 211+ }
 212+ else {
 213+ freq1[j] = m > 0 ? m + a : m - a;
 214+ }
 215+
 216+ if(ang == 0) {
 217+ freq0[j] = m;
 218+ }
 219+ else {
 220+ freq1[j] = m;
 221+ }
 222+ }
 223+ }
 224+ }
 225+
 226+ if(channelFloors[0] != null) {
 227+ Floor(channelFloors[0]).computeFloor(freq0);
 228+ }
 229+
 230+ if(channelFloors[1] != null) {
 231+ Floor(channelFloors[1]).computeFloor(freq1);
 232+ }
 233+
 234+ // perform an inverse mdct to all channels
 235+ var mdct: Mdct = blockFlag ? iHeader.mdct1 : iHeader.mdct0;
 236+ mdct.imdct(freq0, window, pcm0);
 237+ mdct.imdct(freq1, window, pcm1);
 238+
 239+ if(_lastPacket) {
 240+ if(leftWindowEnd - leftWindowStart > _lastGranulePosition - currentGranulePosition) {
 241+ leftWindowEnd = leftWindowStart + _lastGranulePosition - currentGranulePosition
 242+ }
 243+ if(rightWindowStart - leftWindowStart > _lastGranulePosition - currentGranulePosition) {
 244+ rightWindowStart = leftWindowStart + _lastGranulePosition - currentGranulePosition
 245+ }
 246+ }
 247+
 248+ }
 249+
 250+ private function getComputedWindow(vorbis:VorbisStream):Vector.<Number> {
 251+
 252+ var i:int;
 253+
 254+ var ix:int = (blockFlag ? 4 : 0) + (previousWindowFlag ? 2 : 0) + (nextWindowFlag ? 1 : 0);
 255+ var w:Vector.<Number> = vorbis.windows[ix];
 256+
 257+ var x:Number;
 258+
 259+ if (w == null) {
 260+ w = new Vector.<Number>(n);
 261+
 262+ for(i = 0; i < leftWindowStart; i++) {
 263+ w[i] = 0;
 264+ }
 265+
 266+ for (i = 0; i < leftN; i++) {
 267+ x = (i + .5) / leftN * Math.PI / 2.;
 268+ x = Math.sin(x);
 269+ x *= x;
 270+ x *= Math.PI / 2.;
 271+ x = Math.sin(x);
 272+ w[i + leftWindowStart] = x;
 273+ }
 274+
 275+ for (i = leftWindowEnd; i < rightWindowStart; i++) {
 276+ w[i] = 1;
 277+ }
 278+
 279+ for (i = 0; i < rightN; i++) {
 280+ x = (rightN - i - .5) / rightN * Math.PI / 2.;
 281+ x = Math.sin(x);
 282+ x *= x;
 283+ x *= Math.PI / 2.;
 284+ x = Math.sin(x);
 285+ w[i + rightWindowStart] = x;
 286+ }
 287+
 288+ for(i = rightN + rightWindowStart; i < n; i++) {
 289+ w[i] = 0;
 290+ }
 291+
 292+ for(i = 0; i < w.length; i++) {
 293+ w[i] *= 0.5;
 294+ }
 295+
 296+ vorbis.windows[ix] = w;
 297+ }
 298+
 299+ return w;
 300+ }
 301+
 302+
 303+ public function readPcm(previousPacket:AudioPacket, target: ByteArray): int {
 304+
 305+ var j:int;
 306+ var j2:int;
 307+ var ppcm0:Vector.<Number> = previousPacket.pcm0;
 308+ var ppcm1:Vector.<Number> = previousPacket.pcm1;
 309+
 310+ j2 = previousPacket.rightWindowStart;
 311+
 312+ for(j = leftWindowStart; j < leftWindowEnd; j++) {
 313+ target.writeFloat(pcm0[j] + ppcm0[j2]);
 314+ target.writeFloat(pcm1[j] + ppcm1[j2++]);
 315+ }
 316+
 317+ for (j = leftWindowEnd; j < rightWindowStart; j++) {
 318+ target.writeFloat(pcm0[j]);
 319+ target.writeFloat(pcm1[j]);
 320+ }
 321+
 322+ return numberOfSamples;
 323+
 324+ }
 325+
 326+ public function get numberOfSamples():int {
 327+ return rightWindowStart - leftWindowStart;
 328+ }
 329+
 330+ public function get lastPacket(): Boolean {
 331+ return lastPacket;
 332+ }
 333+
 334+ public function get lastGranulePosition(): int {
 335+ return lastGranulePosition;
 336+ }
 337+
 338+ }
 339+
 340+
 341+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/AudioPacket.as
___________________________________________________________________
Added: svn:eol-style
1342 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Mapping.as
@@ -0,0 +1,73 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.errors.IllegalOperationError;
 23+ import org.omtk.util.BitByteArray;
 24+
 25+ public class Mapping {
 26+
 27+ public static function createInstance(stream:VorbisStream, source:BitByteArray, header:SetupHeader):Mapping {
 28+
 29+ var type:int = source.readUnsignedBitwiseInt(16);
 30+ switch (type) {
 31+ case 0:
 32+ return new Mapping0(stream, source, header);
 33+ default:
 34+ throw new Error("Mapping type " + type + " is not supported.");
 35+ }
 36+
 37+ }
 38+
 39+ public function get type():int {
 40+ throw new IllegalOperationError("not implemented");
 41+ }
 42+
 43+ public function get couplingSteps():int {
 44+ throw new IllegalOperationError("not implemented");
 45+ }
 46+
 47+ public function get submaps():int {
 48+ throw new IllegalOperationError("not implemented");
 49+ }
 50+
 51+ public function get angles():Vector.<int> {
 52+ throw new IllegalOperationError("not implemented");
 53+ }
 54+
 55+ public function get magnitudes():Vector.<int> {
 56+ throw new IllegalOperationError("not implemented");
 57+ }
 58+
 59+ public function get mux():Vector.<int> {
 60+ throw new IllegalOperationError("not implemented");
 61+ }
 62+
 63+ public function get submapFloors():Vector.<int> {
 64+ throw new IllegalOperationError("not implemented");
 65+ }
 66+
 67+ public function get submapResidues():Vector.<int> {
 68+ throw new IllegalOperationError("not implemented");
 69+ }
 70+
 71+
 72+ }
 73+
 74+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Mapping.as
___________________________________________________________________
Added: svn:eol-style
175 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Residue.as
@@ -0,0 +1,142 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.errors.IllegalOperationError;
 23+ import flash.utils.Dictionary;
 24+ import org.omtk.util.BitByteArray;
 25+
 26+ public class Residue {
 27+
 28+ private var _begin:int;
 29+ private var _end:int;
 30+ private var _partitionSize:int;
 31+ private var _classifications:int;
 32+ private var _classBook:int;
 33+ private var _cascade:Vector.<int>;
 34+ private var _books:Vector.<Vector.<int>>;
 35+
 36+ private var _looks:Dictionary;
 37+
 38+
 39+ public function Residue(source:BitByteArray, header:SetupHeader) {
 40+
 41+ _begin = source.readUnsignedBitwiseInt(24);
 42+ _end = source.readUnsignedBitwiseInt(24);
 43+ _partitionSize = source.readUnsignedBitwiseInt(24) + 1;
 44+ _classifications = source.readUnsignedBitwiseInt(6) + 1;
 45+ _classBook = source.readUnsignedBitwiseInt(8);
 46+
 47+ _cascade = new Vector.<int>(classifications);
 48+
 49+ var acc:int = 0;
 50+ var i:int;
 51+ var j:int;
 52+
 53+ for (i = 0; i < classifications; i++) {
 54+ var highBits:int = 0;
 55+ var lowBits:int = 0;
 56+
 57+ lowBits = source.readUnsignedBitwiseInt(3);
 58+ if (source.readBit()) {
 59+ highBits = source.readUnsignedBitwiseInt(5);
 60+ }
 61+ _cascade[i] = (highBits << 3) | lowBits;
 62+ acc += Util.icount(cascade[i]);
 63+ }
 64+
 65+ _books = new Vector.<Vector.<int>>(classifications);
 66+
 67+ for (i = 0; i < classifications; i++) {
 68+ books[i] = new Vector.<int>(8);
 69+ for (j = 0; j < 8; j++) {
 70+ if ((cascade[i] & (1 << j)) != 0) {
 71+ books[i][j] = source.readUnsignedBitwiseInt(8);
 72+ if (books[i][j] > header.codeBooks.length) {
 73+ throw new Error(
 74+ "Reference to invalid codebook entry in residue header.");
 75+ }
 76+ }
 77+ }
 78+ }
 79+
 80+ _looks = new Dictionary();
 81+ }
 82+
 83+ public static function createInstance(source:BitByteArray, header:SetupHeader):Residue {
 84+
 85+ var type:int = source.readUnsignedBitwiseInt(16);
 86+ switch (type) {
 87+ case 2:
 88+ return new Residue2(source, header);
 89+ default:
 90+ throw new Error("Residue type " + type + " is not supported.");
 91+ }
 92+ }
 93+
 94+ public function decodeResidue(
 95+ vorbis:VorbisStream, source:BitByteArray,
 96+ mode:Mode, ch:int,
 97+ doNotDecodeFlags:Vector.<Boolean>, vectors0:Vector.<Number>, vectors1:Vector.<Number>):void {
 98+
 99+ throw new IllegalOperationError("not implemented");
 100+ }
 101+
 102+
 103+ public function getLook(stream:VorbisStream, key:Mode):Look {
 104+ var look:Look = _looks[key];
 105+ if (look == null) {
 106+ look = new Look(stream, this, key);
 107+ _looks[key] = look;
 108+ }
 109+ return new Look(stream, this, key);//look;
 110+ }
 111+
 112+
 113+ public function get begin():int {
 114+ return _begin;
 115+ }
 116+
 117+ public function get end():int {
 118+ return _end;
 119+ }
 120+
 121+ public function get partitionSize():int {
 122+ return _partitionSize;
 123+ }
 124+
 125+ public function get classifications():int {
 126+ return _classifications;
 127+ }
 128+
 129+ public function get classBook():int {
 130+ return _classBook;
 131+ }
 132+
 133+ public function get cascade():Vector.<int> {
 134+ return _cascade;
 135+ }
 136+
 137+ public function get books():Vector.<Vector.<int>> {
 138+ return _books;
 139+ }
 140+
 141+ }
 142+
 143+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Residue.as
___________________________________________________________________
Added: svn:eol-style
1144 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Floor0.as
@@ -0,0 +1,56 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.errors.IllegalOperationError;
 23+ import org.omtk.util.BitByteArray;
 24+
 25+ public class Floor0 extends Floor {
 26+
 27+ private var order:int;
 28+ private var rate:int;
 29+ private var barkMapSize:int;
 30+ private var amplitudeBits:int;
 31+ private var amplitudeOffset:int;
 32+
 33+ private var bookList:Vector.<int>;
 34+
 35+ public function Floor0(source:BitByteArray, header:SetupHeader) {
 36+
 37+ order = source.readUnsignedBitwiseInt(8);
 38+ rate = source.readUnsignedBitwiseInt(16);
 39+ barkMapSize = source.readUnsignedBitwiseInt(16);
 40+ amplitudeBits = source.readUnsignedBitwiseInt(6);
 41+ amplitudeOffset = source.readUnsignedBitwiseInt(8);
 42+
 43+ var bookCount:uint = source.readUnsignedBitwiseInt(4) + 1;
 44+ bookList = new Vector.<int>(bookCount);
 45+
 46+ var i:int;
 47+
 48+ for (i = 0; i < bookList.length; i++) {
 49+ bookList[i] = source.readUnsignedBitwiseInt(8);
 50+ if (bookList[i] > header.codeBooks.length) {
 51+ throw new Error("A floor0_book_list entry is higher than the code book count.");
 52+ }
 53+ }
 54+ }
 55+
 56+ }
 57+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Floor0.as
___________________________________________________________________
Added: svn:eol-style
158 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Floor1.as
@@ -0,0 +1,278 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.errors.IllegalOperationError;
 23+ import org.omtk.util.*;
 24+
 25+ public class Floor1 extends Floor {
 26+
 27+ private var partitionClassList:Vector.<int>;
 28+ private var maximumClass:int;
 29+ private var multiplier:int;
 30+ private var rangeBits:int;
 31+ private var classDimensions:Vector.<int>;
 32+ private var classSubclasses:Vector.<int>;
 33+ private var classMasterbooks:Vector.<int>;
 34+ private var subclassBooks:Vector.<Vector.<int>>;
 35+ private var xList:Vector.<int>;
 36+ private var yList:Vector.<int>;
 37+ private var lowNeighbours:Vector.<int>;
 38+ private var highNeighbours:Vector.<int>;
 39+ private static var RANGES:Vector.<int> = Vector.<int>([256, 128, 86, 64]);
 40+
 41+ private var xList2:Vector.<int>;
 42+ private var step2Flags:Vector.<Boolean>;
 43+
 44+ public function Floor1(source:BitByteArray = null, header:SetupHeader = null) {
 45+
 46+ if(source==null && header==null) {
 47+ return;
 48+ }
 49+
 50+ var i:int;
 51+ var j:int;
 52+
 53+ maximumClass = -1;
 54+ var partitions:int = source.readUnsignedBitwiseInt(5);
 55+ partitionClassList = new Vector.<int>(partitions);
 56+
 57+ for (i = 0; i < partitionClassList.length; i++) {
 58+ partitionClassList[i] = source.readUnsignedBitwiseInt(4);
 59+ if (partitionClassList[i] > maximumClass) {
 60+ maximumClass = partitionClassList[i];
 61+ }
 62+ }
 63+
 64+ classDimensions = new Vector.<int>(maximumClass + 1);
 65+ classSubclasses = new Vector.<int>(maximumClass + 1);
 66+ classMasterbooks = new Vector.<int>(maximumClass + 1);
 67+ subclassBooks = new Vector.<Vector.<int>>(maximumClass + 1);
 68+
 69+ var xListLength:int = 2;
 70+
 71+ for (i = 0; i <= maximumClass; i++) {
 72+ classDimensions[i] = source.readUnsignedBitwiseInt(3) + 1;
 73+ xListLength += classDimensions[i];
 74+ classSubclasses[i] = source.readUnsignedBitwiseInt(2);
 75+
 76+ if (classDimensions[i] > header.codeBooks.length || classSubclasses[i] > header.codeBooks.length) {
 77+ throw new Error("There is a class dimension or class subclasses entry higher than the number of codebooks in the setup header.");
 78+ }
 79+ if (classSubclasses[i] != 0) {
 80+ classMasterbooks[i] = source.readUnsignedBitwiseInt(8);
 81+ }
 82+ subclassBooks[i] = new Vector.<int>(1 << classSubclasses[i]);
 83+ for (j = 0; j < subclassBooks[i].length; j++) {
 84+ subclassBooks[i][j] = source.readUnsignedBitwiseInt(8) - 1;
 85+ }
 86+ }
 87+
 88+ multiplier = source.readUnsignedBitwiseInt(2) + 1;
 89+ rangeBits = source.readUnsignedBitwiseInt(4);
 90+
 91+ var floorValues:int = 0;
 92+
 93+ xList = Vector.<int>([0, 1<<rangeBits]);
 94+
 95+ for (i = 0; i < partitions; i++) {
 96+ for (j = 0; j < classDimensions[partitionClassList[i]]; j++) {
 97+ xList.push(source.readUnsignedBitwiseInt(rangeBits));
 98+ }
 99+ }
 100+
 101+ lowNeighbours = new Vector.<int>(xList.length);
 102+ highNeighbours = new Vector.<int>(xList.length);
 103+
 104+ for (i = 0; i < xList.length; i++) {
 105+ lowNeighbours[i] = Util.lowNeighbour(xList, i);
 106+ highNeighbours[i] = Util.highNeighbour(xList, i);
 107+ }
 108+
 109+ xList2 = new Vector.<int>(xList.length, true);
 110+ step2Flags = new Vector.<Boolean>(xList.length, true);
 111+ }
 112+
 113+ public override function get type():int {
 114+ return 1;
 115+ }
 116+
 117+ public override function decodeFloor(vorbis:VorbisStream, source:BitByteArray):Floor1 {
 118+
 119+ var i:int;
 120+ var j:int;
 121+ var offset:int;
 122+
 123+ if (!source.readBit()) {
 124+ return null;
 125+ }
 126+
 127+ var clone:Floor1 = clone();
 128+
 129+ clone.yList = new Vector.<int>(xList.length);
 130+
 131+ var range:int = RANGES[multiplier - 1];
 132+
 133+ clone.yList[0] = source.readUnsignedBitwiseInt(Util.ilog(range - 1));
 134+ clone.yList[1] = source.readUnsignedBitwiseInt(Util.ilog(range - 1));
 135+
 136+ offset = 2;
 137+
 138+ for (i = 0; i < partitionClassList.length; i++) {
 139+ var cls:int = partitionClassList[i];
 140+ var cdim:int = classDimensions[cls];
 141+ var cbits:int = classSubclasses[cls];
 142+ var csub:int = (1 << cbits) - 1;
 143+ var cval:int = 0;
 144+ if (cbits > 0) {
 145+ cval = source.readUnsignedHuffmanInt(vorbis.setupHeader.codeBooks[classMasterbooks[cls]].huffmanRoot);
 146+ }
 147+
 148+ for (j = 0; j < cdim; j++) {
 149+ var book:int = subclassBooks[cls][cval & csub];
 150+ cval >>>= cbits;
 151+ if (book >= 0) {
 152+ clone.yList[j + offset] = source.readUnsignedHuffmanInt(vorbis.setupHeader.codeBooks[book].huffmanRoot);
 153+ } else {
 154+ clone.yList[j + offset] = 0;
 155+ }
 156+ }
 157+ offset += cdim;
 158+ }
 159+
 160+ return clone;
 161+ }
 162+
 163+ public override function computeFloor(vector:Vector.<Number>):void {
 164+
 165+ var i:int;
 166+ var j:int;
 167+
 168+ var n:int = vector.length;
 169+ var values:int = xList.length;
 170+ //var step2Flags:Vector.<Boolean> = new Vector.<Boolean>(values);
 171+
 172+ var range:int = RANGES[multiplier - 1];
 173+
 174+ for (i = 2; i < values; i++) {
 175+
 176+ var lowNeighbourOffset:int = lowNeighbours[i];
 177+ var highNeighbourOffset:int = highNeighbours[i];
 178+
 179+ var predicted:int = Util.renderPoint(
 180+ xList[lowNeighbourOffset], xList[highNeighbourOffset],
 181+ yList[lowNeighbourOffset], yList[highNeighbourOffset], xList[i]);
 182+
 183+ var val:int = yList[i];
 184+ var highRoom:int = range - predicted;
 185+ var lowRoom:int = predicted;
 186+ var room:int = highRoom < lowRoom ? highRoom * 2 : lowRoom * 2;
 187+
 188+ if (val != 0) {
 189+ step2Flags[lowNeighbourOffset] = true;
 190+ step2Flags[highNeighbourOffset] = true;
 191+ step2Flags[i] = true;
 192+ if (val >= room) {
 193+ yList[i] = highRoom > lowRoom ? val - lowRoom + predicted
 194+ : -val + highRoom + predicted - 1;
 195+ } else {
 196+ yList[i] = (val & 1) == 1 ? predicted - ((val + 1) >> 1)
 197+ : predicted + (val >> 1);
 198+ }
 199+ } else {
 200+ step2Flags[i] = false;
 201+ yList[i] = predicted;
 202+ }
 203+ }
 204+
 205+ for(i=0; i<xList.length; i++) {
 206+ xList2[i] = xList[i];
 207+ }
 208+
 209+ sort(xList2, yList, step2Flags);
 210+
 211+ var hx:int = 0;
 212+ var hy:int = 0;
 213+ var lx:int = 0;
 214+ var ly:int = yList[0] * multiplier;
 215+
 216+ for (i = 1; i < values; i++) {
 217+ if (step2Flags[i]) {
 218+ hy = yList[i] * multiplier;
 219+ hx = xList2[i];
 220+ Util.renderLine(lx, ly, hx, hy, vector);
 221+ lx = hx;
 222+ ly = hy;
 223+ }
 224+ }
 225+
 226+ var r:Number = DB_STATIC_TABLE[hy];
 227+
 228+ while(hx < n/2) {
 229+ vector[hx++] = r;
 230+ }
 231+
 232+ }
 233+
 234+ public function clone():Floor1 {
 235+ var clone:Floor1 = new Floor1();
 236+ clone.classDimensions = classDimensions;
 237+ clone.classMasterbooks = classMasterbooks;
 238+ clone.classSubclasses = classSubclasses;
 239+ clone.maximumClass = maximumClass;
 240+ clone.multiplier = multiplier;
 241+ clone.partitionClassList = partitionClassList;
 242+ clone.rangeBits = rangeBits;
 243+ clone.subclassBooks = subclassBooks;
 244+ clone.xList = xList;
 245+ clone.yList = yList;
 246+ clone.lowNeighbours = lowNeighbours;
 247+ clone.highNeighbours = highNeighbours;
 248+ clone.xList2 = xList2;
 249+ clone.step2Flags = step2Flags;
 250+ return clone;
 251+ }
 252+
 253+ private function sort(x:Vector.<int>, y:Vector.<int>, b:Vector.<Boolean>):void {
 254+ var off:int = 0;
 255+ var len:int = x.length;
 256+ var lim:int = len + off;
 257+ var itmp:int;
 258+ var btmp:Boolean;
 259+ var i:int;
 260+ var j:int;
 261+ // Insertion sort on smallest arrays
 262+ for (i = off; i < lim; i++) {
 263+ for (j = i; j > off && x[j - 1] > x[j]; j--) {
 264+ itmp = x[j];
 265+ x[j] = x[j - 1];
 266+ x[j - 1] = itmp;
 267+ itmp = y[j];
 268+ y[j] = y[j - 1];
 269+ y[j - 1] = itmp;
 270+ btmp = b[j];
 271+ b[j] = b[j - 1];
 272+ b[j - 1] = btmp;
 273+ }
 274+ }
 275+ }
 276+
 277+ }
 278+
 279+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Floor1.as
___________________________________________________________________
Added: svn:eol-style
1280 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/IdentificationHeader.as
@@ -0,0 +1,87 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.utils.ByteArray;
 23+
 24+ public class IdentificationHeader {
 25+
 26+ private var _version:uint;
 27+ private var _channels:uint;
 28+ private var _sampleRate:uint;
 29+ private var _bitrateMaximum:int;
 30+ private var _bitrateMinimum:int;
 31+ private var _bitrateNominal:int;
 32+ private var _blockSize0:uint;
 33+ private var _blockSize1:uint;
 34+
 35+ private var _mdct:Vector.<Mdct>;
 36+
 37+ public function IdentificationHeader(source:ByteArray) {
 38+
 39+ source.readByte();
 40+ source.readByte();
 41+ source.readByte();
 42+ source.readByte();
 43+ source.readByte();
 44+ source.readByte();
 45+
 46+ _version = source.readUnsignedInt();
 47+ _channels = source.readUnsignedByte();
 48+ _sampleRate = source.readUnsignedInt();
 49+ _bitrateMaximum = source.readUnsignedInt();
 50+ _bitrateNominal = source.readUnsignedInt();
 51+ _bitrateMinimum = source.readUnsignedInt();
 52+ var bs:int = source.readUnsignedByte();
 53+ _blockSize0 = 1<<(bs&0xf);
 54+ _blockSize1 = 1<<(bs>>4);
 55+
 56+ _mdct = new Vector.<Mdct>(2, false);
 57+ _mdct[0] = new Mdct(_blockSize0);
 58+ _mdct[1] = new Mdct(_blockSize1);
 59+ }
 60+
 61+ public function get channels():uint {
 62+ return _channels;
 63+ }
 64+
 65+ public function get sampleRate():uint {
 66+ return _sampleRate;
 67+ }
 68+
 69+ public function get blockSize0():uint {
 70+ return _blockSize0;
 71+ }
 72+
 73+ public function get blockSize1():uint {
 74+ return _blockSize1;
 75+ }
 76+
 77+ public function get mdct0():Mdct {
 78+ return _mdct[0];
 79+ }
 80+
 81+ public function get mdct1():Mdct {
 82+ return _mdct[1];
 83+ }
 84+
 85+ }
 86+
 87+
 88+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/IdentificationHeader.as
___________________________________________________________________
Added: svn:eol-style
189 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Look.as
@@ -0,0 +1,136 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import org.omtk.util.BitByteArray;
 23+
 24+ public class Look {
 25+
 26+ private var _map:int;
 27+ private var _parts:int;
 28+ private var _stages:int;
 29+ private var _fullbooks:Vector.<CodeBook>;
 30+ private var _phrasebook:CodeBook;
 31+ private var _partbooks:Vector.<Vector.<int>>;
 32+ private var _partvals:int;
 33+ private var _decodemap:Vector.<Vector.<int>>;
 34+ private var _postbits:int;
 35+ private var _phrasebits:int;
 36+ private var _frames:int;
 37+
 38+ public function Look(source:VorbisStream, residue:Residue, mode:Mode) {
 39+
 40+ var i:int;
 41+ var j:int;
 42+ var k:int;
 43+
 44+ var dim:int = 0;
 45+ var acc:int = 0;
 46+ var maxstage:int = 0;
 47+
 48+ _map = mode.mapping;
 49+
 50+ _parts = residue.classifications;
 51+ _fullbooks = source.setupHeader.codeBooks;
 52+ _phrasebook = _fullbooks[residue.classBook];
 53+ dim = _phrasebook.dimensions;
 54+
 55+ _partbooks = new Vector.<Vector.<int>>(_parts);
 56+
 57+ for (j = 0; j < _parts; j++) {
 58+ var s:int = Util.ilog(residue.cascade[j]);
 59+ if (s != 0) {
 60+ if (s > maxstage) {
 61+ maxstage = s;
 62+ }
 63+ _partbooks[j] = new Vector.<int>(s);
 64+ for (k = 0; k < s; k++) {
 65+ if ((residue.cascade[j] & (1 << k)) != 0) {
 66+ _partbooks[j][k] = residue.books[j][k];
 67+ }
 68+ }
 69+ }
 70+ }
 71+
 72+ _partvals = Math.round(Math.pow(_parts, dim));
 73+ _stages = maxstage;
 74+
 75+ _decodemap = new Vector.<Vector.<int>>(_partvals, true);
 76+
 77+ for (j = 0; j < _partvals; j++) {
 78+ var val:int = j;
 79+ var mult:int = _partvals / _parts;
 80+ _decodemap[j] = new Vector.<int>(dim);
 81+
 82+ for (k = 0; k < dim; k++) {
 83+ var deco:int = val / mult;
 84+ val -= deco * mult;
 85+ mult /= _parts;
 86+ _decodemap[j][k] = deco;
 87+ }
 88+ }
 89+ }
 90+
 91+ public function get map():int {
 92+ return _map;
 93+ }
 94+
 95+ public function get parts():int {
 96+ return _parts;
 97+ }
 98+
 99+ public function get stages():int {
 100+ return _stages;
 101+ }
 102+
 103+ public function get fullbooks():Vector.<CodeBook> {
 104+ return _fullbooks;
 105+ }
 106+
 107+ public function get phrasebook():CodeBook {
 108+ return _phrasebook;
 109+ }
 110+
 111+ public function get partbooks():Vector.<Vector.<int>> {
 112+ return _partbooks;
 113+ }
 114+
 115+ public function get partvals():int {
 116+ return _partvals;
 117+ }
 118+
 119+ public function get decodemap():Vector.<Vector.<int>> {
 120+ return _decodemap;
 121+ }
 122+
 123+ public function get postbits():int {
 124+ return _postbits;
 125+ }
 126+
 127+ public function get phrasebits():int {
 128+ return _phrasebits;
 129+ }
 130+
 131+ public function get frames():int {
 132+ return _frames;
 133+ }
 134+
 135+ }
 136+
 137+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Look.as
___________________________________________________________________
Added: svn:eol-style
1138 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/SetupHeader.as
@@ -0,0 +1,118 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import org.omtk.util.BitByteArray;
 23+
 24+ public class SetupHeader {
 25+
 26+ private var _codeBooks:Vector.<CodeBook>;
 27+ private var _floors:Vector.<Floor>;
 28+ private var _residues:Vector.<Residue>;
 29+ private var _mappings:Vector.<Mapping>;
 30+ private var _modes:Vector.<Mode>;
 31+
 32+ public function SetupHeader(stream:VorbisStream, source:BitByteArray) {
 33+
 34+ var i:int;
 35+
 36+ source.readByte();
 37+ source.readByte();
 38+ source.readByte();
 39+ source.readByte();
 40+ source.readByte();
 41+ source.readByte();
 42+
 43+ var codeBookCount:uint = source.readUnsignedBitwiseInt(8)+1;
 44+ _codeBooks = new Vector.<CodeBook>(codeBookCount);
 45+
 46+ for(i = 0; i < codeBookCount; i++) {
 47+ _codeBooks[i] = new CodeBook(source);
 48+ }
 49+
 50+ // read the time domain transformations,
 51+ // these should all be 0
 52+
 53+ var timeCount:int = source.readUnsignedBitwiseInt(6) + 1;
 54+ for (i = 0; i < timeCount; i++) {
 55+ if (source.readUnsignedBitwiseInt(16) != 0) {
 56+ throw new Error(
 57+ "Time domain transformation != 0");
 58+ }
 59+ }
 60+
 61+ // read floor entries
 62+
 63+ var floorCount:int = source.readUnsignedBitwiseInt(6) + 1;
 64+ _floors = new Vector.<Floor>(floorCount);
 65+
 66+ for (i = 0; i < floorCount; i++) {
 67+ _floors[i] = Floor.createInstance(source, this);
 68+ }
 69+
 70+ var residueCount:int = source.readUnsignedBitwiseInt(6) + 1;
 71+ _residues = new Vector.<Residue>(residueCount);
 72+
 73+ for (i = 0; i < residueCount; i++) {
 74+ _residues[i] = Residue.createInstance(source, this);
 75+ }
 76+
 77+ var mappingCount:int = source.readUnsignedBitwiseInt(6) + 1;
 78+ _mappings = new Vector.<Mapping>(mappingCount);
 79+
 80+ for (i = 0; i < mappingCount; i++) {
 81+ _mappings[i] = Mapping.createInstance(stream, source, this);
 82+ }
 83+
 84+ var modeCount:int = source.readUnsignedBitwiseInt(6) + 1;
 85+ _modes = new Vector.<Mode>(modeCount);
 86+
 87+ for (i = 0; i < modeCount; i++) {
 88+ _modes[i] = new Mode(source, this);
 89+ }
 90+
 91+ if (!source.readBit()) {
 92+ throw new Error("The setup header framing bit is incorrect.");
 93+ }
 94+ }
 95+
 96+ public function get codeBooks():Vector.<CodeBook> {
 97+ return _codeBooks;
 98+ }
 99+
 100+ public function get floors():Vector.<Floor> {
 101+ return _floors;
 102+ }
 103+
 104+ public function get mappings():Vector.<Mapping> {
 105+ return _mappings;
 106+ }
 107+
 108+ public function get residues():Vector.<Residue> {
 109+ return _residues;
 110+ }
 111+
 112+ public function get modes():Vector.<Mode> {
 113+ return _modes;
 114+ }
 115+
 116+ }
 117+
 118+
 119+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/SetupHeader.as
___________________________________________________________________
Added: svn:eol-style
1120 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Mapping0.as
@@ -0,0 +1,136 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.errors.IllegalOperationError;
 23+ import org.omtk.util.BitByteArray;
 24+
 25+ public class Mapping0 extends Mapping {
 26+
 27+ private var _magnitudes:Vector.<int>;
 28+ private var _angles:Vector.<int>;
 29+ private var _mux:Vector.<int>;
 30+ private var _submapFloors:Vector.<int>;
 31+ private var _submapResidues:Vector.<int>;
 32+
 33+ public function Mapping0(stream:VorbisStream, source:BitByteArray, header:SetupHeader) {
 34+
 35+ var i:int;
 36+ var j:int;
 37+
 38+ var submaps:int = 1;
 39+
 40+ if (source.readBit()) {
 41+ submaps = source.readUnsignedBitwiseInt(4) + 1;
 42+ }
 43+
 44+ var channels:int = stream.identificationHeader.channels;
 45+ var ilogChannels:int = Util.ilog(channels - 1);
 46+
 47+ if (source.readBit()) {
 48+ var couplingSteps:int = source.readUnsignedBitwiseInt(8) + 1;
 49+ _magnitudes = new Vector.<int>(couplingSteps);
 50+ _angles = new Vector.<int>(couplingSteps);
 51+
 52+ for (i = 0; i < couplingSteps; i++) {
 53+ magnitudes[i] = source.readUnsignedBitwiseInt(ilogChannels);
 54+ angles[i] = source.readUnsignedBitwiseInt(ilogChannels);
 55+ if (magnitudes[i] == angles[i] || magnitudes[i] >= channels
 56+ || angles[i] >= channels) {
 57+ throw new Error("The channel magnitude and/or angle mismatch.");
 58+ }
 59+ }
 60+ } else {
 61+ _magnitudes = Vector.<int>([]);
 62+ _angles = Vector.<int>([]);
 63+ }
 64+
 65+ if (source.readUnsignedBitwiseInt(2) != 0) {
 66+ throw new Error("A reserved mapping field has an invalid value.");
 67+ }
 68+
 69+ _mux = new Vector.<int>(channels);
 70+ if (submaps > 1) {
 71+ for (i = 0; i < channels; i++) {
 72+ _mux[i] = source.readUnsignedBitwiseInt(4);
 73+ if (_mux[i] > submaps) {
 74+ throw new Error("A mapping mux value is higher than the number of submaps");
 75+ }
 76+ }
 77+ } else {
 78+ for (i = 0; i < channels; i++) {
 79+ _mux[i] = 0;
 80+ }
 81+ }
 82+
 83+ _submapFloors = new Vector.<int>(submaps);
 84+ _submapResidues = new Vector.<int>(submaps);
 85+
 86+ var floorCount:int = header.floors.length;
 87+ var residueCount:int = header.residues.length;
 88+
 89+ for (i = 0; i < submaps; i++) {
 90+ source.readUnsignedBitwiseInt(8); // discard time placeholder
 91+ _submapFloors[i] = source.readUnsignedBitwiseInt(8);
 92+ _submapResidues[i] = source.readUnsignedBitwiseInt(8);
 93+
 94+ if (_submapFloors[i] > floorCount) {
 95+ throw new Error("A mapping floor value is higher than the number of floors.");
 96+ }
 97+
 98+ if (_submapResidues[i] > residueCount) {
 99+ throw new Error("A mapping residue value is higher than the number of residues.");
 100+ }
 101+ }
 102+ }
 103+
 104+ public override function get type():int {
 105+ return 0;
 106+ }
 107+
 108+ public override function get couplingSteps():int {
 109+ return _angles.length;
 110+ }
 111+
 112+ public override function get submaps():int {
 113+ return _submapFloors.length;
 114+ }
 115+
 116+ public override function get angles():Vector.<int> {
 117+ return _angles;
 118+ }
 119+
 120+ public override function get magnitudes():Vector.<int> {
 121+ return _magnitudes;
 122+ }
 123+
 124+ public override function get mux():Vector.<int> {
 125+ return _mux;
 126+ }
 127+
 128+ public override function get submapFloors():Vector.<int> {
 129+ return _submapFloors;
 130+ }
 131+
 132+ public override function get submapResidues():Vector.<int> {
 133+ return _submapResidues;
 134+ }
 135+ }
 136+
 137+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Mapping0.as
___________________________________________________________________
Added: svn:eol-style
1138 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/CommentHeader.as
@@ -0,0 +1,81 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.utils.ByteArray;
 23+ import flash.utils.Endian;
 24+ import flash.utils.Dictionary;
 25+ import org.omtk.ogg.*;
 26+
 27+ public class CommentHeader {
 28+
 29+ private var _vendor:String;
 30+ private var _comments:Dictionary = new Dictionary();
 31+
 32+ public function CommentHeader(source:ByteArray)
 33+ {
 34+ init( source );
 35+ }
 36+
 37+ private function init( source: ByteArray ): void
 38+ {
 39+ source.readByte();
 40+ source.readByte();
 41+ source.readByte();
 42+ source.readByte();
 43+ source.readByte();
 44+ source.readByte();
 45+
 46+ _vendor = readUtf8String(source);
 47+
 48+ var ucLength:int = source.readUnsignedInt();
 49+
 50+ for(var i:int = 0; i < ucLength; i++) {
 51+ var comment:String = readUtf8String(source);
 52+ var ix:int = comment.indexOf('=');
 53+ var key:String = comment.substring(0, ix);
 54+ var value:String = comment.substring(ix+1);
 55+ _comments[key.toUpperCase()]=value;
 56+ }
 57+ }
 58+
 59+ private function readUtf8String(source:ByteArray):String {
 60+ var length:uint = source.readUnsignedInt();
 61+ return source.readUTFBytes(length);
 62+ }
 63+
 64+ public function get vendor():String {
 65+ return _vendor;
 66+ }
 67+
 68+ public function get comments():Dictionary {
 69+ return _comments;
 70+ }
 71+
 72+ public function get artist():String {
 73+ return _comments["ARTIST"];
 74+ }
 75+
 76+ public function get title():String {
 77+ return _comments["TITLE"];
 78+ }
 79+
 80+ }
 81+
 82+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/CommentHeader.as
___________________________________________________________________
Added: svn:eol-style
183 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/VorbisSound.as
@@ -0,0 +1,136 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.net.URLRequest;
 23+ import flash.net.URLStream;
 24+ import flash.utils.ByteArray;
 25+ import flash.utils.Endian;
 26+ import flash.events.Event;
 27+ import flash.events.ProgressEvent;
 28+ import flash.events.SampleDataEvent;
 29+
 30+ import flash.external.ExternalInterface;
 31+
 32+ import flash.media.Sound;
 33+
 34+ import org.omtk.ogg.UncachedUrlStream;
 35+ import org.omtk.ogg.EndOfOggStreamError;
 36+ import flash.utils.setTimeout;
 37+
 38+ public class VorbisSound extends Sound {
 39+
 40+ public static var METADATA_UPDATE: String = "metadata_update";
 41+
 42+ private var urlStream: URLStream;
 43+
 44+ private var oggStream:UncachedUrlStream;
 45+ private var vorbisStream:VorbisStream;
 46+
 47+ private var bytesAvailable:int;
 48+
 49+ private var initialized:Boolean = false;
 50+ private var playing:Boolean = false;
 51+
 52+ private var fill1:Boolean = true;
 53+ private var fill2:Boolean = true;
 54+
 55+ private var stopped: Boolean = false;
 56+ private var completeEventDispatched: Boolean = false;
 57+
 58+ public function VorbisSound(url: URLRequest ) {
 59+ urlStream = new URLStream();
 60+ urlStream.endian = Endian.LITTLE_ENDIAN;
 61+ urlStream.load(url);
 62+
 63+ Mdct.initialize();
 64+
 65+ oggStream = new UncachedUrlStream(urlStream);
 66+ oggStream.addEventListener('progress', progress);
 67+ bytesAvailable = oggStream.bytesAvailable;
 68+ addEventListener("sampleData", sampleGenerator);
 69+ }
 70+
 71+ private function initialize():void {
 72+ vorbisStream = new VorbisStream(oggStream.getLogicalOggStream());
 73+ setTimeout(dispatchEvent, 100, new Event(METADATA_UPDATE));
 74+ initialized = true;
 75+ }
 76+
 77+ private var samplesPlayed: int = 0;
 78+
 79+ private function sampleGenerator(event:SampleDataEvent):void {
 80+
 81+ if(stopped) {
 82+ return;
 83+ }
 84+
 85+ if(Mdct.initialized && !initialized && bytesAvailable > 64*1024) {
 86+ initialize();
 87+ }
 88+
 89+ if(initialized && bytesAvailable > 16*1024 && !vorbisStream.finished) {
 90+ var cnt: int;
 91+ cnt = vorbisStream.readPcm(event.data);
 92+ samplesPlayed += cnt;
 93+ if(cnt < 2048 && oggStream.bytesAvailable > 0) {
 94+ vorbisStream = new VorbisStream(oggStream.getLogicalOggStream());
 95+ setTimeout(dispatchEvent, 100, new Event(METADATA_UPDATE));
 96+ samplesPlayed += vorbisStream.readPcm(event.data);
 97+ }
 98+ }
 99+ else if(vorbisStream == null || !vorbisStream.finished) {
 100+ for(var c:int=0; c<2048; c++) {
 101+ event.data.writeFloat(0);
 102+ event.data.writeFloat(0);
 103+ }
 104+ }
 105+
 106+ if(initialized && vorbisStream.finished && oggStream.bytesAvailable == 0 && !completeEventDispatched) {
 107+ dispatchEvent(new Event(Event.COMPLETE));
 108+ completeEventDispatched = true;
 109+ }
 110+
 111+ //trace("samples played: " + samplesPlayed + "/" + oggStream.bytesAvailable);
 112+
 113+ }
 114+
 115+ public function stop(): void {
 116+ stopped = true;
 117+ }
 118+
 119+ public function progress(event:ProgressEvent):void {
 120+ bytesAvailable = oggStream.bytesAvailable;
 121+ }
 122+
 123+ public function get position(): int {
 124+ return samplesPlayed * 1000 / 44100;
 125+ }
 126+
 127+ public function getMetaData(key: String):String {
 128+ if(vorbisStream != null) {
 129+ return vorbisStream.commentHeader.comments[key];
 130+ }
 131+ else {
 132+ return null;
 133+ }
 134+ }
 135+ }
 136+
 137+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/VorbisSound.as
___________________________________________________________________
Added: svn:eol-style
1138 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Util.as
@@ -0,0 +1,122 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ public class Util {
 23+
 24+ public static function ilog(x:uint):uint {
 25+ var res:int = 0;
 26+ for(; x>0; x>>=1, res++);
 27+ return res;
 28+ }
 29+
 30+ public static function float32unpack(x:uint):Number {
 31+ var mantissa:Number = x&0x1fffff;
 32+ var e:Number = (x&0x7fe00000)>>21;
 33+ if((x&0x80000000)!=0) {
 34+ mantissa=-mantissa;
 35+ }
 36+ return mantissa*Math.pow(2.0, e-788.0);
 37+ }
 38+
 39+ public static function lookup1Values(a:int, b:int):uint {
 40+ var res:uint = Math.pow(Math.E, Math.log(a)/b);
 41+ return intPow(res+1, b)<=a?res+1:res;
 42+ }
 43+
 44+ public static function intPow(base:uint, e:uint):uint {
 45+ var res:uint = 1;
 46+ for(; e>0; e--, res*=base);
 47+ return res;
 48+ }
 49+
 50+ public static function isBitSet(value:uint, bit:uint):Boolean {
 51+ return (value&(1<<bit))!=0;
 52+ }
 53+
 54+ public static function icount(value:uint):uint {
 55+ var res:uint = 0;
 56+ while (value > 0) {
 57+ res += value & 1;
 58+ value >>= 1;
 59+ }
 60+ return res;
 61+ }
 62+
 63+ public static function lowNeighbour(v:Vector.<int>, x:int):int {
 64+
 65+ var max:int = -1;
 66+ var n:int = 0;
 67+ var i:int;
 68+
 69+ for (i = 0; i < v.length && i < x; i++) {
 70+ if (v[i] > max && v[i] < v[x]) {
 71+ max = v[i];
 72+ n = i;
 73+ }
 74+ }
 75+ return n;
 76+ }
 77+
 78+ public static function highNeighbour(v:Vector.<int>, x:int):int {
 79+
 80+ var min:int = int.MAX_VALUE;
 81+ var n:int = 0;
 82+ var i:int;
 83+
 84+ for (i = 0; i < v.length && i < x; i++) {
 85+ if (v[i] < min && v[i] > v[x]) {
 86+ min = v[i];
 87+ n = i;
 88+ }
 89+ }
 90+ return n;
 91+ }
 92+
 93+ public static function renderPoint(x0:int, x1:int, y0:int, y1:int, x:int):int {
 94+ return y0 + int(((y1-y0) * (x - x0)) / (x1 - x0));
 95+ }
 96+
 97+ public static function renderLine(x0:int, y0:int, x1:int, y1:int, v:Vector.<Number>):void {
 98+
 99+ var dy:int = y1 - y0;
 100+ var adx:int = x1 - x0;
 101+ var b:int = dy / adx;
 102+ var sy:int = dy < 0 ? b - 1 : b + 1;
 103+ var x:int = x0;
 104+ var y:int = y0;
 105+ var err:int = 0;
 106+ var ady:int = (dy < 0 ? -dy : dy) - (b > 0 ? b * adx : -b * adx);
 107+
 108+ v[x] *= Floor.DB_STATIC_TABLE[y];
 109+ for (x = x0 + 1; x < x1; x++) {
 110+ err += ady;
 111+ if (err >= adx) {
 112+ err -= adx;
 113+ v[x] *= Floor.DB_STATIC_TABLE[y += sy];
 114+ } else {
 115+ v[x] *= Floor.DB_STATIC_TABLE[y += b];
 116+ }
 117+ }
 118+
 119+ }
 120+
 121+ }
 122+
 123+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Util.as
___________________________________________________________________
Added: svn:eol-style
1124 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/VorbisStream.as
@@ -0,0 +1,130 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.events.SampleDataEvent;
 23+ import flash.utils.ByteArray;
 24+ import flash.utils.Endian;
 25+ import org.omtk.util.*;
 26+ import org.omtk.ogg.*;
 27+
 28+ public class VorbisStream {
 29+
 30+ private const IDENTIFICATION_HEADER:int = 1;
 31+ private const COMMENT_HEADER:int = 3;
 32+ private const SETUP_HEADER:int = 5;
 33+
 34+ private var source:LogicalOggStream;
 35+
 36+ private var _identificationHeader:IdentificationHeader;
 37+ private var _commentHeader:CommentHeader;
 38+ private var _setupHeader:SetupHeader;
 39+
 40+ private var _lastAudioPacket:AudioPacket;
 41+
 42+ private var _currentGranulePosition:int=0;
 43+ private var packetCounter:int;
 44+
 45+ private var _finished: Boolean = false;
 46+
 47+ public var windows:Vector.<Vector.<Number>> = new Vector.<Vector.<Number>>(8);
 48+
 49+ public function VorbisStream(source:LogicalOggStream) {
 50+
 51+ this.source = source;
 52+
 53+ for (var i:int = 0; i < 3; i++) {
 54+
 55+ var data:BitByteArray = source.getNextOggPacket().data;
 56+ var headerType:int = data.readUnsignedByte();
 57+
 58+ switch(headerType) {
 59+ case IDENTIFICATION_HEADER:
 60+ _identificationHeader = new IdentificationHeader(data);
 61+ break;
 62+ case COMMENT_HEADER:
 63+ _commentHeader = new CommentHeader(data);
 64+ break;
 65+ case SETUP_HEADER:
 66+ _setupHeader = new SetupHeader(this, data);
 67+ break;
 68+ }
 69+ }
 70+
 71+ }
 72+
 73+ public function get identificationHeader():IdentificationHeader {
 74+ return _identificationHeader;
 75+ }
 76+
 77+ public function get commentHeader():CommentHeader {
 78+ return _commentHeader;
 79+ }
 80+
 81+ public function get setupHeader():SetupHeader {
 82+ return _setupHeader;
 83+ }
 84+
 85+ public function readPcm(data:ByteArray): int {
 86+
 87+ var total:int;
 88+ var i:int;
 89+
 90+ if(_lastAudioPacket == null) {
 91+ _lastAudioPacket = getNextAudioPacket();
 92+ }
 93+
 94+ total = 0;
 95+
 96+ while(total < 2048 && !_finished) {
 97+ try {
 98+ var ap:AudioPacket = getNextAudioPacket();
 99+ total += ap.readPcm(_lastAudioPacket, data);
 100+ _lastAudioPacket = ap;
 101+ }
 102+ catch(e: EndOfOggStreamError) {
 103+ // ok, stream finished
 104+ _finished = true;
 105+ }
 106+ }
 107+
 108+ return total;
 109+ }
 110+
 111+ private function getNextAudioPacket():AudioPacket {
 112+ packetCounter++;
 113+ var packet:OggPacket = source.getNextOggPacket();
 114+ var res:AudioPacket = new AudioPacket(this, packet, _currentGranulePosition);
 115+ if(_lastAudioPacket != null) {
 116+ // don't count the first packet, since it doesn't contain any "real" samples
 117+ _currentGranulePosition += res.numberOfSamples;
 118+ }
 119+ return res;
 120+ }
 121+
 122+ public function get finished() : Boolean {
 123+ return _finished;
 124+ }
 125+
 126+ public function get currentGranulePosition(): int {
 127+ return _currentGranulePosition;
 128+ }
 129+ }
 130+
 131+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/VorbisStream.as
___________________________________________________________________
Added: svn:eol-style
1132 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Floor.as
@@ -0,0 +1,122 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.errors.IllegalOperationError;
 23+ import org.omtk.util.BitByteArray;
 24+
 25+ public class Floor {
 26+
 27+ public static const DB_STATIC_TABLE:Vector.<Number> = Vector.<Number>([
 28+ 1.0649863e-07, 1.1341951e-07, 1.2079015e-07, 1.2863978e-07,
 29+ 1.3699951e-07, 1.4590251e-07, 1.5538408e-07, 1.6548181e-07,
 30+ 1.7623575e-07, 1.8768855e-07, 1.9988561e-07, 2.128753e-07,
 31+ 2.2670913e-07, 2.4144197e-07, 2.5713223e-07, 2.7384213e-07,
 32+ 2.9163793e-07, 3.1059021e-07, 3.3077411e-07, 3.5226968e-07,
 33+ 3.7516214e-07, 3.9954229e-07, 4.2550680e-07, 4.5315863e-07,
 34+ 4.8260743e-07, 5.1396998e-07, 5.4737065e-07, 5.8294187e-07,
 35+ 6.2082472e-07, 6.6116941e-07, 7.0413592e-07, 7.4989464e-07,
 36+ 7.9862701e-07, 8.5052630e-07, 9.0579828e-07, 9.6466216e-07,
 37+ 1.0273513e-06, 1.0941144e-06, 1.1652161e-06, 1.2409384e-06,
 38+ 1.3215816e-06, 1.4074654e-06, 1.4989305e-06, 1.5963394e-06,
 39+ 1.7000785e-06, 1.8105592e-06, 1.9282195e-06, 2.0535261e-06,
 40+ 2.1869758e-06, 2.3290978e-06, 2.4804557e-06, 2.6416497e-06,
 41+ 2.8133190e-06, 2.9961443e-06, 3.1908506e-06, 3.3982101e-06,
 42+ 3.6190449e-06, 3.8542308e-06, 4.1047004e-06, 4.3714470e-06,
 43+ 4.6555282e-06, 4.9580707e-06, 5.2802740e-06, 5.6234160e-06,
 44+ 5.9888572e-06, 6.3780469e-06, 6.7925283e-06, 7.2339451e-06,
 45+ 7.7040476e-06, 8.2047000e-06, 8.7378876e-06, 9.3057248e-06,
 46+ 9.9104632e-06, 1.0554501e-05, 1.1240392e-05, 1.1970856e-05,
 47+ 1.2748789e-05, 1.3577278e-05, 1.4459606e-05, 1.5399272e-05,
 48+ 1.6400004e-05, 1.7465768e-05, 1.8600792e-05, 1.9809576e-05,
 49+ 2.1096914e-05, 2.2467911e-05, 2.3928002e-05, 2.5482978e-05,
 50+ 2.7139006e-05, 2.8902651e-05, 3.0780908e-05, 3.2781225e-05,
 51+ 3.4911534e-05, 3.7180282e-05, 3.9596466e-05, 4.2169667e-05,
 52+ 4.4910090e-05, 4.7828601e-05, 5.0936773e-05, 5.4246931e-05,
 53+ 5.7772202e-05, 6.1526565e-05, 6.5524908e-05, 6.9783085e-05,
 54+ 7.4317983e-05, 7.9147585e-05, 8.4291040e-05, 8.9768747e-05,
 55+ 9.5602426e-05, 0.00010181521, 0.00010843174, 0.00011547824,
 56+ 0.00012298267, 0.00013097477, 0.00013948625, 0.00014855085,
 57+ 0.00015820453, 0.00016848555, 0.00017943469, 0.00019109536,
 58+ 0.00020351382, 0.00021673929, 0.00023082423, 0.00024582449,
 59+ 0.00026179955, 0.00027881276, 0.00029693158, 0.00031622787,
 60+ 0.00033677814, 0.00035866388, 0.00038197188, 0.00040679456,
 61+ 0.00043323036, 0.00046138411, 0.00049136745, 0.00052329927,
 62+ 0.00055730621, 0.00059352311, 0.00063209358, 0.00067317058,
 63+ 0.00071691700, 0.00076350630, 0.00081312324, 0.00086596457,
 64+ 0.00092223983, 0.00098217216, 0.0010459992, 0.0011139742,
 65+ 0.0011863665, 0.0012634633, 0.0013455702, 0.0014330129,
 66+ 0.0015261382, 0.0016253153, 0.0017309374, 0.0018434235,
 67+ 0.0019632195, 0.0020908006, 0.0022266726, 0.0023713743,
 68+ 0.0025254795, 0.0026895994, 0.0028643847, 0.0030505286,
 69+ 0.0032487691, 0.0034598925, 0.0036847358, 0.0039241906,
 70+ 0.0041792066, 0.0044507950, 0.0047400328, 0.0050480668,
 71+ 0.0053761186, 0.0057254891, 0.0060975636, 0.0064938176,
 72+ 0.0069158225, 0.0073652516, 0.0078438871, 0.0083536271,
 73+ 0.0088964928, 0.009474637, 0.010090352, 0.010746080,
 74+ 0.011444421, 0.012188144, 0.012980198, 0.013823725,
 75+ 0.014722068, 0.015678791, 0.016697687, 0.017782797,
 76+ 0.018938423, 0.020169149, 0.021479854, 0.022875735,
 77+ 0.024362330, 0.025945531, 0.027631618, 0.029427276,
 78+ 0.031339626, 0.033376252, 0.035545228, 0.037855157,
 79+ 0.040315199, 0.042935108, 0.045725273, 0.048696758,
 80+ 0.051861348, 0.055231591, 0.058820850, 0.062643361,
 81+ 0.066714279, 0.071049749, 0.075666962, 0.080584227,
 82+ 0.085821044, 0.091398179, 0.097337747, 0.10366330,
 83+ 0.11039993, 0.11757434, 0.12521498, 0.13335215,
 84+ 0.14201813, 0.15124727, 0.16107617, 0.17154380,
 85+ 0.18269168, 0.19456402, 0.20720788, 0.22067342,
 86+ 0.23501402, 0.25028656, 0.26655159, 0.28387361,
 87+ 0.30232132, 0.32196786, 0.34289114, 0.36517414,
 88+ 0.38890521, 0.41417847, 0.44109412, 0.46975890,
 89+ 0.50028648, 0.53279791, 0.56742212, 0.60429640,
 90+ 0.64356699, 0.68538959, 0.72993007, 0.77736504,
 91+ 0.82788260, 0.88168307, 0.9389798, 1.0]);
 92+
 93+ public static function createInstance(source:BitByteArray, header:SetupHeader):Floor {
 94+
 95+ var type:int = source.readUnsignedBitwiseInt(16);
 96+
 97+ switch (type) {
 98+ case 0:
 99+ return new Floor0(source, header);
 100+ case 1:
 101+ return new Floor1(source, header);
 102+ default:
 103+ throw new Error("Floor type " + type + " is not supported.");
 104+ }
 105+ }
 106+
 107+ public function get type():int {
 108+ throw new IllegalOperationError("operation not implemented");
 109+ }
 110+
 111+ public function decodeFloor(vorbis:VorbisStream, source:BitByteArray):Floor1 {
 112+ throw new IllegalOperationError("operation not implemented");
 113+ }
 114+
 115+ public function computeFloor(vector:Vector.<Number>):void {
 116+ throw new IllegalOperationError("operation not implemented");
 117+ }
 118+
 119+
 120+ }
 121+
 122+
 123+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Floor.as
___________________________________________________________________
Added: svn:eol-style
1124 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Residue2.as
@@ -0,0 +1,109 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis {
 21+
 22+ import flash.errors.IllegalOperationError;
 23+ import flash.utils.Dictionary;
 24+ import org.omtk.util.BitByteArray;
 25+
 26+ public class Residue2 extends Residue {
 27+
 28+ public function Residue2(source:BitByteArray, header:SetupHeader) {
 29+ super(source, header);
 30+ }
 31+
 32+ public override function decodeResidue(
 33+ vorbis:VorbisStream, source:BitByteArray,
 34+ mode:Mode, ch:int,
 35+ doNotDecodeFlags:Vector.<Boolean>, vectors0:Vector.<Number>, vectors1:Vector.<Number>):void {
 36+
 37+ var i:int;
 38+ var j:int;
 39+ var k:int;
 40+ var l:int;
 41+ var s:int;
 42+ var slim:int;
 43+
 44+ var look:Look = getLook(vorbis, mode);
 45+
 46+ var codeBook:CodeBook = vorbis.setupHeader.codeBooks[classBook];
 47+
 48+ var classvalsPerCodeword:int = codeBook.dimensions;
 49+ var nToRead:int = end - begin;
 50+ var partitionsToRead:int = nToRead / partitionSize; // partvals
 51+
 52+ var samplesPerPartition:int = partitionSize;
 53+ var partitionsPerWord:int = look.phrasebook.dimensions;
 54+
 55+ var partWords:int = (partitionsToRead + partitionsPerWord - 1) / partitionsPerWord;
 56+
 57+ var offset:int;
 58+
 59+ var left:Boolean = false;
 60+ var right:Boolean = false;
 61+
 62+ for (i = 0; i < doNotDecodeFlags.length; i++) {
 63+ if (!doNotDecodeFlags[i]) {
 64+ if(i==0) {
 65+ left = true;
 66+ }
 67+ else if (i==1) {
 68+ right = true;
 69+ }
 70+ }
 71+ }
 72+
 73+ var partword:Array = new Array(partWords);
 74+
 75+ var pb:int = source.position;
 76+
 77+ slim = look.stages;
 78+ for (s = 0; s < slim; s++) {
 79+
 80+ for (i = 0, l = 0; i < partitionsToRead; l++) {
 81+
 82+ if (s == 0) {
 83+ var temp:int = source.readUnsignedHuffmanInt(look.phrasebook.huffmanRoot);
 84+ if (temp == -1) {
 85+ throw new Error("Foo??");
 86+ }
 87+ partword[l] = look.decodemap[temp];
 88+ if (partword[l] == null) {
 89+ throw new Error("Foo??");
 90+ }
 91+ }
 92+
 93+ for (k = 0; k < partitionsPerWord && i < partitionsToRead; k++, i++) {
 94+ offset = begin + i * samplesPerPartition;
 95+
 96+ if ((cascade[partword[l][k]] & (1 << s)) != 0) {
 97+ var stagebook:CodeBook =
 98+ vorbis.setupHeader.codeBooks[look.partbooks[partword[l][k]][s]];
 99+ if (stagebook != null) {
 100+ stagebook.readVvAdd(vectors0, vectors1, left, right, source, offset, samplesPerPartition);
 101+ }
 102+ }
 103+ }
 104+ }
 105+ }
 106+
 107+ }
 108+
 109+ }
 110+}
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/org/omtk/vorbis/Residue2.as
___________________________________________________________________
Added: svn:eol-style
1111 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/Player.as
@@ -0,0 +1,106 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package {
 21+
 22+ import org.omtk.vorbis.VorbisSound;
 23+
 24+ import flash.display.Shape;
 25+ import flash.display.Sprite;
 26+ import flash.display.StageAlign;
 27+ import flash.display.StageQuality;
 28+ import flash.display.StageScaleMode;
 29+ import flash.net.*;
 30+ import flash.events.Event;
 31+ import flash.text.TextField;
 32+ import flash.utils.ByteArray;
 33+ import flash.utils.Endian;
 34+ import flash.utils.getTimer;
 35+ import flash.utils.setTimeout;
 36+ import flash.utils.setInterval;
 37+ import flash.external.ExternalInterface;
 38+
 39+ [ SWF( backgroundColor = '#ffffff', width = '1', height = '1' ) ]
 40+
 41+ public class Player extends Sprite {
 42+
 43+ private var sound: VorbisSound;
 44+ private var initialized: Boolean = false;
 45+
 46+ public function Player() {
 47+ if(stage != null) {
 48+ stage.frameRate = 20;
 49+ }
 50+
 51+ setTimeout(registerJSCallbacks, 100);
 52+ initialized = true;
 53+ }
 54+
 55+ private function registerJSCallbacks(): void {
 56+ if (ExternalInterface.available) {
 57+ ExternalInterface.addCallback("play", playJS);
 58+ ExternalInterface.addCallback("getMetaData", getMetaDataJS);
 59+ ExternalInterface.addCallback("getPosition", getPositionJS);
 60+ }
 61+ }
 62+
 63+ public function playJS(url: String): void {
 64+ if(sound != null) {
 65+ sound.stop();
 66+ }
 67+ sound = new VorbisSound(new URLRequest(url));
 68+ sound.addEventListener(Event.COMPLETE, complete);
 69+ sound.addEventListener(VorbisSound.METADATA_UPDATE, metadataUpdate);
 70+ sound.play();
 71+ }
 72+
 73+ public function getMetaDataJS(key: String): String {
 74+ if(sound == null) {
 75+ return null;
 76+ }
 77+ else {
 78+ return sound.getMetaData(key);
 79+ }
 80+ }
 81+
 82+ public function getPositionJS(): int {
 83+ if(sound == null) {
 84+ return -1;
 85+ }
 86+ else {
 87+ return sound.position;
 88+ }
 89+ }
 90+
 91+ private function complete(event: Event):void {
 92+ trace("complete");
 93+ if(ExternalInterface.available) {
 94+ ExternalInterface.call("OMTK_P_complete");
 95+ }
 96+ }
 97+
 98+ private function metadataUpdate(event: Event):void {
 99+ trace("metadata update: " + sound.getMetaData("TITLE"));
 100+ if(ExternalInterface.available) {
 101+ ExternalInterface.call("OMTK_P_metadataUpdate");
 102+ }
 103+ }
 104+
 105+ }
 106+
 107+}
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/as/Player.as
___________________________________________________________________
Added: svn:eol-style
1108 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/haXe/build.hxml
@@ -0,0 +1,3 @@
 2+-main org.omtk.vorbis.MdctHX
 3+-swf-version 10
 4+-swf hxmdct.swf
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/haXe/build.hxml
___________________________________________________________________
Added: svn:eol-style
15 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/haXe/org/omtk/vorbis/MdctHX.hx
@@ -0,0 +1,337 @@
 2+/*
 3+
 4+Copyright 2008 Tor-Einar Jarnbjo
 5+
 6+ Licensed under the Apache License, Version 2.0 (the "License");
 7+ you may not use this file except in compliance with the License.
 8+ You may obtain a copy of the License at
 9+
 10+ http://www.apache.org/licenses/LICENSE-2.0
 11+
 12+ Unless required by applicable law or agreed to in writing, software
 13+ distributed under the License is distributed on an "AS IS" BASIS,
 14+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15+ See the License for the specific language governing permissions and
 16+ limitations under the License.
 17+
 18+*/
 19+
 20+package org.omtk.vorbis;
 21+
 22+import flash.Vector;
 23+
 24+class MdctHX {
 25+
 26+ private static var cPI1_8:Float = 0.92387953251128675613;
 27+ private static var cPI2_8:Float = 0.70710678118654752441;
 28+ private static var cPI3_8:Float = 0.38268343236508977175;
 29+
 30+ private var n:Int;
 31+ private var log2n:Int;
 32+ private var trig:Vector<Float>;
 33+ private var bitrev:Vector<Int>;
 34+
 35+ private var dtmp1:Float;
 36+ private var dtmp2:Float;
 37+ private var dtmp3:Float;
 38+ private var dtmp4:Float;
 39+
 40+ private var x:Vector<Float>;
 41+ private var w:Vector<Float>;
 42+
 43+ public function new(n:Int) {
 44+ this.n = n;
 45+
 46+ var i:Int;
 47+ var j:Int;
 48+
 49+ bitrev = new Vector<Int>();
 50+ trig = new Vector<Float>(Std.int(n+n/4), true);
 51+
 52+ for(i in 0...Std.int(n+n/4)) {
 53+ trig[i] = 0;
 54+ }
 55+
 56+ x = new Vector<Float>(Std.int(n/2), true);
 57+ w = new Vector<Float>(Std.int(n/2), true);
 58+
 59+ for(i in 0...Std.int(n/2)) {
 60+ x[i] = 0;
 61+ w[i] = 0;
 62+ }
 63+
 64+ var n2:Int = n >>> 1;
 65+ log2n = Math.round(Math.log(n) / Math.log(2));
 66+
 67+ var AE:Int = 0;
 68+ var AO:Int = 1;
 69+ var BE:Int = Std.int(AE + n / 2);
 70+ var BO:Int = BE + 1;
 71+ var CE:Int = Std.int(BE + n / 2);
 72+ var CO:Int = CE + 1;
 73+
 74+ for (i in 0...Std.int(n/4)) {
 75+ trig[AE + i * 2] = Math.cos((Math.PI / n) * (4 * i));
 76+ trig[AO + i * 2] = -Math.sin((Math.PI / n) * (4 * i));
 77+ trig[BE + i * 2] = Math.cos((Math.PI / (2 * n)) * (2 * i + 1));
 78+ trig[BO + i * 2] = Math.sin((Math.PI / (2 * n)) * (2 * i + 1));
 79+ }
 80+
 81+ for (i in 0...Std.int(n/8)) {
 82+ trig[CE + i * 2] = Math.cos((Math.PI / n) * (4 * i + 2));
 83+ trig[CO + i * 2] = -Math.sin((Math.PI / n) * (4 * i + 2));
 84+ }
 85+
 86+ var mask:Int = (1 << (log2n - 1)) - 1;
 87+ var msb:Int = 1 << (log2n - 2);
 88+
 89+ for (i in 0...Std.int(n/8)) {
 90+ var acc:Int = 0;
 91+ j = 0;
 92+ while(msb>>>j!=0) {
 93+ if (((msb >>> j) & i) != 0) {
 94+ acc |= 1 << j;
 95+ }
 96+ j++;
 97+ }
 98+ bitrev[i * 2] = ((~acc) & mask);
 99+ bitrev[i * 2 + 1] = acc;
 100+ }
 101+
 102+ }
 103+
 104+ public function imdct(frq:Vector<Float>, window:Vector<Float>, pcm:Vector<Float>):Void {
 105+
 106+ var i:Int;
 107+
 108+ var n2:Int;
 109+ var n4:Int;
 110+ var n8:Int;
 111+
 112+ var inO:Int;
 113+ var xO:Int;
 114+ var A:Int;
 115+
 116+ var temp1:Float;
 117+ var temp2:Float;
 118+
 119+ var B:Int;
 120+ var o1:Int;
 121+ var o2:Int;
 122+ var o3:Int;
 123+ var o4:Int;
 124+
 125+ var xx:Int;
 126+ var xxx:Vector<Float>;
 127+
 128+ n2 = n >> 1;
 129+ n4 = n >> 2;
 130+ n8 = n >> 3;
 131+
 132+ inO = -1;
 133+ xO = 0;
 134+ A = n2;
 135+
 136+ temp1 = 0.0;
 137+ temp2 = 0.0;
 138+
 139+ for (i in 0...n8) {
 140+ dtmp1 = frq[inO += 2];
 141+ dtmp2 = frq[inO += 2];
 142+ dtmp3 = trig[--A];
 143+ dtmp4 = trig[--A];
 144+ x[xO++] = -dtmp2 * dtmp3 - dtmp1 * dtmp4;
 145+ x[xO++] = dtmp1 * dtmp3 - dtmp2 * dtmp4;
 146+ }
 147+
 148+ inO = n2;
 149+
 150+ for(i in 0...n8) {
 151+ dtmp1 = frq[inO -= 2];
 152+ dtmp2 = frq[inO -= 2];
 153+ dtmp3 = trig[--A];
 154+ dtmp4 = trig[--A];
 155+ x[xO++] = dtmp2 * dtmp3 + dtmp1 * dtmp4;
 156+ x[xO++] = dtmp2 * dtmp4 - dtmp1 * dtmp3;
 157+ }
 158+
 159+ xxx = kernel(x, w, n, n2, n4, n8);
 160+ xx = 0;
 161+
 162+ B = n2;
 163+ o1 = n4;
 164+ o2 = o1 - 1;
 165+ o3 = n4 + n2;
 166+ o4 = o3 - 1;
 167+
 168+ for (i in 0...n4) {
 169+ dtmp1 = xxx[xx++];
 170+ dtmp2 = xxx[xx++];
 171+ dtmp3 = trig[B++];
 172+ dtmp4 = trig[B++];
 173+
 174+ temp1 = (dtmp1 * dtmp4 - dtmp2 * dtmp3);
 175+ temp2 = -(dtmp1 * dtmp3 + dtmp2 * dtmp4);
 176+
 177+ pcm[o1] = -temp1 * window[o1];
 178+ pcm[o2] = temp1 * window[o2];
 179+ pcm[o3] = temp2 * window[o3];
 180+ pcm[o4] = temp2 * window[o4];
 181+
 182+ o1++;
 183+ o2--;
 184+ o3++;
 185+ o4--;
 186+ }
 187+
 188+ }
 189+
 190+ private inline function kernel(x:Vector<Float>, w:Vector<Float>, n:Int, n2:Int, n4:Int, n8:Int):Vector<Float> {
 191+
 192+ var i:Int;
 193+ var r:Int;
 194+ var s:Int;
 195+ var rlim:Int;
 196+ var slim:Int;
 197+
 198+ var xA:Int = n4;
 199+ var xB:Int = 0;
 200+ var w1:Int = 0;
 201+ var w2:Int = n4;
 202+ var A:Int = n2;
 203+
 204+ var x0:Float;
 205+ var x1:Float;
 206+ var wA:Float;
 207+ var wB:Float;
 208+ var wC:Float;
 209+ var wD:Float;
 210+ var k0:Int;
 211+ var k1:Int;
 212+ var t1:Int;
 213+ var t2:Int;
 214+
 215+ var wbase:Int;
 216+ var temp:Vector<Float>;
 217+
 218+ var wACE:Float;
 219+ var wBCE:Float;
 220+ var wACO:Float;
 221+ var wBCO:Float;
 222+
 223+ var AEv:Float;
 224+ var AOv:Float;
 225+
 226+ i=0;
 227+ while(i < n4) {
 228+ x0 = x[xA] - x[xB];
 229+
 230+ w[w2 + i] = x[xA++] + x[xB++];
 231+
 232+ x1 = x[xA] - x[xB];
 233+ A -= 4;
 234+
 235+ w[i++] = x0 * trig[A] + x1 * trig[A + 1];
 236+ w[i] = x1 * trig[A] - x0 * trig[A + 1];
 237+
 238+ w[w2 + i] = x[xA++] + x[xB++];
 239+ i++;
 240+ }
 241+
 242+ for (i in 0...log2n-3) {
 243+ k0 = n >>> (i + 2);
 244+ k1 = 1 << (i + 3);
 245+ wbase = n2 - 2;
 246+
 247+ A = 0;
 248+
 249+ rlim = k0 >>> 2;
 250+ for (r in 0...rlim) {
 251+
 252+ w1 = wbase;
 253+ w2 = w1 - (k0 >> 1);
 254+ AEv = trig[A];
 255+ AOv = trig[A + 1];
 256+ wbase -= 2;
 257+
 258+ k0++;
 259+
 260+ slim = 2 << i;
 261+ for (s in 0...slim) {
 262+ dtmp1 = w[w1];
 263+ dtmp2 = w[w2];
 264+ wB = dtmp1 - dtmp2;
 265+ x[w1] = dtmp1 + dtmp2;
 266+ dtmp1 = w[++w1];
 267+ dtmp2 = w[++w2];
 268+ wA = dtmp1 - dtmp2;
 269+ x[w1] = dtmp1 + dtmp2;
 270+ x[w2] = wA * AEv - wB * AOv;
 271+ x[w2-1] = wB * AEv + wA * AOv;
 272+ w1 -= k0;
 273+ w2 -= k0;
 274+ }
 275+ k0--;
 276+ A += k1;
 277+ }
 278+
 279+ temp = w;
 280+ w = x;
 281+ x = temp;
 282+ }
 283+
 284+
 285+ var C:Int = n;
 286+ var bit:Int = 0;
 287+ var xx1:Int = 0;
 288+ var xx2:Int = n2 - 1;
 289+
 290+ var wt1: Float;
 291+ var wt2: Float;
 292+ var wt12: Float;
 293+ var wt21: Float;
 294+ var trigV: Float;
 295+
 296+ for (i in 0...n8) {
 297+ t1 = bitrev[bit++];
 298+ t2 = bitrev[bit++];
 299+
 300+ wt1 = w[t1];
 301+ wt2 = w[t2];
 302+ wt12 = w[t1-1];
 303+ wt21 = w[t2+1];
 304+
 305+ wA = wt1 - wt21;
 306+ wB = wt12 + wt2;
 307+ wC = wt1 + wt21;
 308+ wD = wt12 - wt2;
 309+
 310+ trigV = trig[C];
 311+
 312+ wACE = wA * trigV;
 313+ wBCE = wB * trigV;
 314+
 315+ trigV = trig[++C];
 316+
 317+ wACO = wA * trigV;
 318+ wBCO = wB * trigV;
 319+
 320+ ++C;
 321+
 322+ x[xx1++] = (wC + wACO + wBCE);
 323+ x[xx2--] = (-wD + wBCO - wACE);
 324+ x[xx1++] = (wD + wBCO - wACE);
 325+ x[xx2--] = (wC - wACO - wBCE);
 326+ }
 327+
 328+ return x;
 329+ }
 330+
 331+ /*
 332+ * Dummy function required for the haXe compiler to build this to
 333+ * a .SWF file.
 334+ */
 335+ public static function main() : Void {
 336+ }
 337+
 338+}
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/src/haXe/org/omtk/vorbis/MdctHX.hx
___________________________________________________________________
Added: svn:eol-style
1339 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/omtkp.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/omtkp.swf
___________________________________________________________________
Added: svn:mime-type
2340 + application/octet-stream
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/README.txt
@@ -0,0 +1,17 @@
 2+
 3+ *** PRELIMINARY SOFTWARE ***
 4+
 5+Please note that this is a prerelease of the OMTK Flash library. No
 6+quality of this software can be guaranteed.
 7+
 8+
 9+ *** haXe notes ***
 10+
 11+You need at least haXe 2.01 (with support for the new Flash 10 types)
 12+to compile the haXe source.
 13+
 14+ *** Flash notes ***
 15+
 16+I am not able to create a .SWC library from the haXe .SWF file. It's
 17+therefore dynamically linked at runtime and hxmdct.swf must be placed
 18+in the same directory as the "real" Flash movie.
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/README.txt
___________________________________________________________________
Added: svn:eol-style
119 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/LICENSE.txt
@@ -0,0 +1,201 @@
 2+ Apache License
 3+ Version 2.0, January 2004
 4+ http://www.apache.org/licenses/
 5+
 6+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
 7+
 8+ 1. Definitions.
 9+
 10+ "License" shall mean the terms and conditions for use, reproduction,
 11+ and distribution as defined by Sections 1 through 9 of this document.
 12+
 13+ "Licensor" shall mean the copyright owner or entity authorized by
 14+ the copyright owner that is granting the License.
 15+
 16+ "Legal Entity" shall mean the union of the acting entity and all
 17+ other entities that control, are controlled by, or are under common
 18+ control with that entity. For the purposes of this definition,
 19+ "control" means (i) the power, direct or indirect, to cause the
 20+ direction or management of such entity, whether by contract or
 21+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
 22+ outstanding shares, or (iii) beneficial ownership of such entity.
 23+
 24+ "You" (or "Your") shall mean an individual or Legal Entity
 25+ exercising permissions granted by this License.
 26+
 27+ "Source" form shall mean the preferred form for making modifications,
 28+ including but not limited to software source code, documentation
 29+ source, and configuration files.
 30+
 31+ "Object" form shall mean any form resulting from mechanical
 32+ transformation or translation of a Source form, including but
 33+ not limited to compiled object code, generated documentation,
 34+ and conversions to other media types.
 35+
 36+ "Work" shall mean the work of authorship, whether in Source or
 37+ Object form, made available under the License, as indicated by a
 38+ copyright notice that is included in or attached to the work
 39+ (an example is provided in the Appendix below).
 40+
 41+ "Derivative Works" shall mean any work, whether in Source or Object
 42+ form, that is based on (or derived from) the Work and for which the
 43+ editorial revisions, annotations, elaborations, or other modifications
 44+ represent, as a whole, an original work of authorship. For the purposes
 45+ of this License, Derivative Works shall not include works that remain
 46+ separable from, or merely link (or bind by name) to the interfaces of,
 47+ the Work and Derivative Works thereof.
 48+
 49+ "Contribution" shall mean any work of authorship, including
 50+ the original version of the Work and any modifications or additions
 51+ to that Work or Derivative Works thereof, that is intentionally
 52+ submitted to Licensor for inclusion in the Work by the copyright owner
 53+ or by an individual or Legal Entity authorized to submit on behalf of
 54+ the copyright owner. For the purposes of this definition, "submitted"
 55+ means any form of electronic, verbal, or written communication sent
 56+ to the Licensor or its representatives, including but not limited to
 57+ communication on electronic mailing lists, source code control systems,
 58+ and issue tracking systems that are managed by, or on behalf of, the
 59+ Licensor for the purpose of discussing and improving the Work, but
 60+ excluding communication that is conspicuously marked or otherwise
 61+ designated in writing by the copyright owner as "Not a Contribution."
 62+
 63+ "Contributor" shall mean Licensor and any individual or Legal Entity
 64+ on behalf of whom a Contribution has been received by Licensor and
 65+ subsequently incorporated within the Work.
 66+
 67+ 2. Grant of Copyright License. Subject to the terms and conditions of
 68+ this License, each Contributor hereby grants to You a perpetual,
 69+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 70+ copyright license to reproduce, prepare Derivative Works of,
 71+ publicly display, publicly perform, sublicense, and distribute the
 72+ Work and such Derivative Works in Source or Object form.
 73+
 74+ 3. Grant of Patent License. Subject to the terms and conditions of
 75+ this License, each Contributor hereby grants to You a perpetual,
 76+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
 77+ (except as stated in this section) patent license to make, have made,
 78+ use, offer to sell, sell, import, and otherwise transfer the Work,
 79+ where such license applies only to those patent claims licensable
 80+ by such Contributor that are necessarily infringed by their
 81+ Contribution(s) alone or by combination of their Contribution(s)
 82+ with the Work to which such Contribution(s) was submitted. If You
 83+ institute patent litigation against any entity (including a
 84+ cross-claim or counterclaim in a lawsuit) alleging that the Work
 85+ or a Contribution incorporated within the Work constitutes direct
 86+ or contributory patent infringement, then any patent licenses
 87+ granted to You under this License for that Work shall terminate
 88+ as of the date such litigation is filed.
 89+
 90+ 4. Redistribution. You may reproduce and distribute copies of the
 91+ Work or Derivative Works thereof in any medium, with or without
 92+ modifications, and in Source or Object form, provided that You
 93+ meet the following conditions:
 94+
 95+ (a) You must give any other recipients of the Work or
 96+ Derivative Works a copy of this License; and
 97+
 98+ (b) You must cause any modified files to carry prominent notices
 99+ stating that You changed the files; and
 100+
 101+ (c) You must retain, in the Source form of any Derivative Works
 102+ that You distribute, all copyright, patent, trademark, and
 103+ attribution notices from the Source form of the Work,
 104+ excluding those notices that do not pertain to any part of
 105+ the Derivative Works; and
 106+
 107+ (d) If the Work includes a "NOTICE" text file as part of its
 108+ distribution, then any Derivative Works that You distribute must
 109+ include a readable copy of the attribution notices contained
 110+ within such NOTICE file, excluding those notices that do not
 111+ pertain to any part of the Derivative Works, in at least one
 112+ of the following places: within a NOTICE text file distributed
 113+ as part of the Derivative Works; within the Source form or
 114+ documentation, if provided along with the Derivative Works; or,
 115+ within a display generated by the Derivative Works, if and
 116+ wherever such third-party notices normally appear. The contents
 117+ of the NOTICE file are for informational purposes only and
 118+ do not modify the License. You may add Your own attribution
 119+ notices within Derivative Works that You distribute, alongside
 120+ or as an addendum to the NOTICE text from the Work, provided
 121+ that such additional attribution notices cannot be construed
 122+ as modifying the License.
 123+
 124+ You may add Your own copyright statement to Your modifications and
 125+ may provide additional or different license terms and conditions
 126+ for use, reproduction, or distribution of Your modifications, or
 127+ for any such Derivative Works as a whole, provided Your use,
 128+ reproduction, and distribution of the Work otherwise complies with
 129+ the conditions stated in this License.
 130+
 131+ 5. Submission of Contributions. Unless You explicitly state otherwise,
 132+ any Contribution intentionally submitted for inclusion in the Work
 133+ by You to the Licensor shall be under the terms and conditions of
 134+ this License, without any additional terms or conditions.
 135+ Notwithstanding the above, nothing herein shall supersede or modify
 136+ the terms of any separate license agreement you may have executed
 137+ with Licensor regarding such Contributions.
 138+
 139+ 6. Trademarks. This License does not grant permission to use the trade
 140+ names, trademarks, service marks, or product names of the Licensor,
 141+ except as required for reasonable and customary use in describing the
 142+ origin of the Work and reproducing the content of the NOTICE file.
 143+
 144+ 7. Disclaimer of Warranty. Unless required by applicable law or
 145+ agreed to in writing, Licensor provides the Work (and each
 146+ Contributor provides its Contributions) on an "AS IS" BASIS,
 147+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 148+ implied, including, without limitation, any warranties or conditions
 149+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
 150+ PARTICULAR PURPOSE. You are solely responsible for determining the
 151+ appropriateness of using or redistributing the Work and assume any
 152+ risks associated with Your exercise of permissions under this License.
 153+
 154+ 8. Limitation of Liability. In no event and under no legal theory,
 155+ whether in tort (including negligence), contract, or otherwise,
 156+ unless required by applicable law (such as deliberate and grossly
 157+ negligent acts) or agreed to in writing, shall any Contributor be
 158+ liable to You for damages, including any direct, indirect, special,
 159+ incidental, or consequential damages of any character arising as a
 160+ result of this License or out of the use or inability to use the
 161+ Work (including but not limited to damages for loss of goodwill,
 162+ work stoppage, computer failure or malfunction, or any and all
 163+ other commercial damages or losses), even if such Contributor
 164+ has been advised of the possibility of such damages.
 165+
 166+ 9. Accepting Warranty or Additional Liability. While redistributing
 167+ the Work or Derivative Works thereof, You may choose to offer,
 168+ and charge a fee for, acceptance of support, warranty, indemnity,
 169+ or other liability obligations and/or rights consistent with this
 170+ License. However, in accepting such obligations, You may act only
 171+ on Your own behalf and on Your sole responsibility, not on behalf
 172+ of any other Contributor, and only if You agree to indemnify,
 173+ defend, and hold each Contributor harmless for any liability
 174+ incurred by, or claims asserted against, such Contributor by reason
 175+ of your accepting any such warranty or additional liability.
 176+
 177+ END OF TERMS AND CONDITIONS
 178+
 179+ APPENDIX: How to apply the Apache License to your work.
 180+
 181+ To apply the Apache License to your work, attach the following
 182+ boilerplate notice, with the fields enclosed by brackets "[]"
 183+ replaced with your own identifying information. (Don't include
 184+ the brackets!) The text should be enclosed in the appropriate
 185+ comment syntax for the file format. We also recommend that a
 186+ file or class name and description of purpose be included on the
 187+ same "printed page" as the copyright notice for easier
 188+ identification within third-party archives.
 189+
 190+ Copyright 2008 Tor-Einar Jarnbjo
 191+
 192+ Licensed under the Apache License, Version 2.0 (the "License");
 193+ you may not use this file except in compliance with the License.
 194+ You may obtain a copy of the License at
 195+
 196+ http://www.apache.org/licenses/LICENSE-2.0
 197+
 198+ Unless required by applicable law or agreed to in writing, software
 199+ distributed under the License is distributed on an "AS IS" BASIS,
 200+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 201+ See the License for the specific language governing permissions and
 202+ limitations under the License.
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/omtk-fx/LICENSE.txt
___________________________________________________________________
Added: svn:eol-style
1203 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/cortado/README
@@ -0,0 +1 @@
 2+This version of cortado comes form http://theora.org/cortado.jar
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/cortado/README
___________________________________________________________________
Added: svn:eol-style
13 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/cortado/cortado-ovt-stripped-0.5.0.jar
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/cortado/cortado-ovt-stripped-0.5.0.jar
___________________________________________________________________
Added: svn:mime-type
24 + application/octet-stream
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/kaltura-player/kdp.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/kaltura-player/kdp.swf
___________________________________________________________________
Added: svn:mime-type
35 + application/octet-stream
Added: svn:executable
46 + *
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/kaltura-player/README
@@ -0,0 +1,11 @@
 2+This Kaltura Dynamic Player +Playlist (KDP) is a sub package of the taken Kaltura Community Edition (CE) Built from Kaltura.org source.
 3+
 4+The full Kaltura Community Edition is licensed under the (GNU Affero General Public License v3)
 5+
 6+And the source code is available on the kaltura.org site:
 7+http://www.kaltura.org/project/kalturaCE
 8+
 9+More info about the KDP:
 10+http://www.kaltura.org/kdp-dynamic-player-and-playlist-widget
 11+
 12+
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/kaltura-player/README
___________________________________________________________________
Added: svn:eol-style
113 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/kaltura-player/wrapper.swf
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers/kaltura-player/wrapper.swf
___________________________________________________________________
Added: svn:mime-type
214 + application/octet-stream
Added: svn:executable
315 + *
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers
___________________________________________________________________
Added: svn:mergeinfo
416 Merged /branches/REL1_15/phase3/js2/mwEmbed/binPlayers:r51646
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/javaEmbed.js
@@ -0,0 +1,177 @@
 2+window.cortadoDomainLocations = {
 3+ 'upload.wikimedia.org' : 'http://upload.wikimedia.org/jars/cortado.jar',
 4+ 'tinyvid.tv' : 'http://tinyvid.tv/static/cortado.jar',
 5+ 'media.tinyvid.tv' : 'http://media.tinyvid.tv/cortado.jar'
 6+}
 7+
 8+var javaEmbed = {
 9+ instanceOf:'javaEmbed',
 10+ iframe_src:'',
 11+ logged_domain_error:false,
 12+ supports: {
 13+ 'play_head':true,
 14+ 'pause':true,
 15+ 'stop':true,
 16+ 'fullscreen':false,
 17+ 'time_display':true,
 18+ 'volume_control':false
 19+ },
 20+ getEmbedHTML : function () {
 21+ // big delay on embed html cuz its just for status updates and ie6 is crazy.
 22+ if ( this.controls )
 23+ setTimeout( 'document.getElementById(\'' + this.id + '\').postEmbedJS()', 500 );
 24+ // set a default duration of 30 seconds: cortao should detect duration.
 25+ return this.wrapEmebedContainer( this.getEmbedObj() );
 26+ },
 27+ getEmbedObj:function() {
 28+ js_log( "java play url:" + this.getURI( this.seek_time_sec ) );
 29+ // get the duration
 30+ this.getDuration();
 31+ // if still unset set to an arbitrary time 60 seconds:
 32+ if ( !this.duration )this.duration = 60;
 33+ // @@todo we should have src property in our base embed object
 34+ var mediaSrc = this.getSrc();
 35+
 36+ if ( mediaSrc.indexOf( '://' ) != -1 & mw.parseUri( document.URL ).host != mw.parseUri( mediaSrc ).host ) {
 37+ if ( window.cortadoDomainLocations[mw.parseUri( mediaSrc ).host] ) {
 38+ applet_loc = window.cortadoDomainLocations[mw.parseUri( mediaSrc ).host];
 39+ } else {
 40+ applet_loc = 'http://theora.org/cortado.jar';
 41+ }
 42+ } else {
 43+ // should be identical to cortado.jar
 44+ applet_loc = mv_embed_path + 'libEmbedPlayer/binPlayers/cortado/cortado-ovt-stripped-0.5.0.jar';
 45+ }
 46+ // load directly in the page..
 47+ // (media must be on the same server or applet must be signed)
 48+ var appplet_code = '' +
 49+ '<applet id="' + this.pid + '" code="com.fluendo.player.Cortado.class" archive="' + applet_loc + '" width="' + this.width + '" height="' + this.height + '"> ' + "\n" +
 50+ '<param name="url" value="' + mediaSrc + '" /> ' + "\n" +
 51+ '<param name="local" value="false"/>' + "\n" +
 52+ '<param name="keepaspect" value="true" />' + "\n" +
 53+ '<param name="video" value="true" />' + "\n" +
 54+ '<param name="showStatus" value="hide" />' + "\n" +
 55+ '<param name="audio" value="true" />' + "\n" +
 56+ '<param name="seekable" value="true" />' + "\n" +
 57+ '<param name="duration" value="' + this.duration + '" />' + "\n" +
 58+ '<param name="bufferSize" value="4096" />' + "\n" +
 59+ '</applet>';
 60+
 61+ // Wrap it in an iframe to avoid hanging the event thread in FF 2/3 and similar
 62+ // Doesn't work in MSIE or Safari/Mac or Opera 9.5
 63+ if ( embedTypes.mozilla ) {
 64+ var iframe = document.createElement( 'iframe' );
 65+ iframe.setAttribute( 'width', params.width );
 66+ iframe.setAttribute( 'height', playerHeight );
 67+ iframe.setAttribute( 'scrolling', 'no' );
 68+ iframe.setAttribute( 'frameborder', 0 );
 69+ iframe.setAttribute( 'marginWidth', 0 );
 70+ iframe.setAttribute( 'marginHeight', 0 );
 71+ iframe.setAttribute( 'id', 'cframe_' + this.id )
 72+ elt.appendChild( iframe );
 73+ var newDoc = iframe.contentDocument;
 74+ newDoc.open();
 75+ newDoc.write( '<html><body>' + appplet_code + '</body></html>' );
 76+ newDoc.close(); // spurious error in some versions of FF, no workaround known
 77+ } else {
 78+ return appplet_code;
 79+ }
 80+ },
 81+ postEmbedJS:function() {
 82+ // reset logged domain error flag:
 83+ this.logged_domain_error = false;
 84+ // start monitor:
 85+ this.monitor();
 86+ },
 87+ monitor:function() {
 88+ this.getJCE();
 89+ if ( this.isPlaying() ) {
 90+ if ( this.jce && this.jce.getPlayPosition ) {
 91+ try {
 92+ // java reads ogg media time.. so no need to add the start or seek offset:
 93+ // js_log(' ct: ' + this.jce.getPlayPosition() + ' ' + this.supportsURLTimeEncoding());
 94+ this.currentTime = this.jce.getPlayPosition();
 95+ if ( this.jce.getPlayPosition() < 0 ) {
 96+ js_log( 'pp:' + this.jce.getPlayPosition() );
 97+ // probably reached clip end
 98+ this.onClipDone();
 99+ }
 100+ } catch ( e ) {
 101+ js_log( 'could not get time from jPlayer: ' + e );
 102+ }
 103+ }
 104+ }
 105+ // once currentTime is updated call parent_monitor
 106+ this.parent_monitor();
 107+ },
 108+ /*
 109+ * (local cortado seek does not seem to work very well)
 110+ */
 111+ doSeek:function( perc ) {
 112+ js_log( 'java:seek:p: ' + perc + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec );
 113+ this.getJCE();
 114+
 115+ if ( this.supportsURLTimeEncoding() ) {
 116+ this.parent_doSeek( perc );
 117+ // this.seek_time_sec = npt2seconds( this.start_ntp ) + parseFloat( perc * this.getDuration() );
 118+ // this.jce.setParam('url', this.getURI( this.seek_time_sec ))
 119+ // this.jce.restart();
 120+ } else if ( this.jce ) {
 121+ // do a (genneraly broken) local seek:
 122+ js_log( "cortado javascript seems to always fail ... but here we go... doSeek(" + ( perc * parseFloat( this.getDuration() ) ) );
 123+ this.jce.doSeek( perc * parseFloat( this.getDuration() ) );
 124+ } else {
 125+ this.doPlayThenSeek( perc );
 126+ }
 127+ },
 128+ doPlayThenSeek:function( perc ) {
 129+ js_log( 'doPlayThenSeek Hack' );
 130+ var _this = this;
 131+ this.play();
 132+ var rfsCount = 0;
 133+ var readyForSeek = function() {
 134+ _this.getJCE();
 135+ // if we have .jre ~in theory~ we can seek (but probably not)
 136+ if ( _this.jce ) {
 137+ _this.doSeek( perc );
 138+ } else {
 139+ // try to get player for 10 seconds:
 140+ if ( rfsCount < 200 ) {
 141+ setTimeout( readyForSeek, 50 );
 142+ rfsCount++;
 143+ } else {
 144+ js_log( 'error:doPlayThenSeek failed' );
 145+ }
 146+ }
 147+ }
 148+ readyForSeek();
 149+ },
 150+ // get java cortado embed object
 151+ getJCE:function() {
 152+ if ( embedTypes.mozilla ) {
 153+ this.jce = window.frames['cframe_' + this.id ].document.getElementById( this.pid );
 154+ } else {
 155+ this.jce = $j( '#' + this.pid ).get( 0 );
 156+ }
 157+ },
 158+ doThumbnailHTML:function() {
 159+ // empty out player html (jquery with java applets does mix) :
 160+ var pelm = document.getElementById( 'dc_' + this.id );
 161+ if ( pelm ) {
 162+ pelm.innerHTML = '';
 163+ }
 164+ this.parent_doThumbnailHTML();
 165+ },
 166+ play:function() {
 167+ this.getJCE();
 168+ this.parent_play();
 169+ if ( this.jce )
 170+ this.jce.doPlay();
 171+ },
 172+ pause:function() {
 173+ this.getJCE();
 174+ this.parent_pause();
 175+ if ( this.jce )
 176+ this.jce.doPause();
 177+ }
 178+};
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/javaEmbed.js
___________________________________________________________________
Added: svn:eol-style
1179 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/flowplayerEmbed.js
@@ -0,0 +1,1726 @@
 2+/**
 3+ * metavid: mv_flashEmbed builds off of flowplayer api (included first in this file)
 4+ * THIS WILL BE DEPRECIATED SOON
 5+ */
 6+
 7+ /**
 8+ * flowplayer.js 3.0.0-rc5. The Flowplayer API.
 9+ *
 10+ * This file is part of Flowplayer, http://flowplayer.org
 11+ *
 12+ * Author: Tero Piirainen, <support@flowplayer.org>
 13+ * Copyright (c) 2008 Flowplayer Ltd
 14+ *
 15+ * Released under the MIT License:
 16+ * http://www.opensource.org/licenses/mit-license.php
 17+ *
 18+ * Version: 3.0.0-rc5 - Thu Nov 20 2008 22:09:49 GMT-0000 (GMT+00:00)
 19+ */
 20+( function() {
 21+
 22+/*
 23+ FEATURES
 24+ --------
 25+ - handling multiple instances
 26+ - Flowplayer programming API
 27+ - Flowplayer event model
 28+ - player loading / unloading
 29+ - $f() function
 30+ - jQuery support
 31+*/
 32+
 33+/*jslint glovar: true, browser: true */
 34+/*global flowplayer, $f */
 35+
 36+// {{{ private utility methods
 37+
 38+ function log( args ) {
 39+
 40+ // write into opera console
 41+ if ( typeof opera == 'object' ) {
 42+ opera.postError( "$f.fireEvent: " + args.join( " | " ) );
 43+
 44+
 45+ } else if ( typeof console == 'object' ) {
 46+ console.log( "$f.fireEvent", [].slice.call( args ) );
 47+ }
 48+ }
 49+
 50+ // thanks: http://keithdevens.com/weblog/archive/2007/Jun/07/javascript.clone
 51+ function clone ( obj ) {
 52+ if ( !obj || typeof obj != 'object' ) { return obj; }
 53+ var temp = new obj.constructor();
 54+ for ( var key in obj ) {
 55+ if ( obj.hasOwnProperty( key ) ) {
 56+ temp[key] = clone ( obj[key] );
 57+ }
 58+ }
 59+ return temp;
 60+ }
 61+
 62+ // stripped from jQuery, thanks John Resig
 63+ function each( obj, fn ) {
 64+ if ( !obj ) { return; }
 65+
 66+ var name, i = 0, length = obj.length;
 67+
 68+ // object
 69+ if ( length === undefined ) {
 70+ for ( name in obj ) {
 71+ if ( fn.call( obj[name], name, obj[name] ) === false ) { break; }
 72+ }
 73+
 74+ // array
 75+ } else {
 76+ for ( var value = obj[0];
 77+ i < length && fn.call( value, i, value ) !== false; value = obj[++i] ) {
 78+ }
 79+ }
 80+
 81+ return obj;
 82+ }
 83+
 84+ // convenience
 85+ function el( id ) {
 86+ return document.getElementById( id );
 87+ }
 88+
 89+ // used extensively. a very simple implementation.
 90+ function extend( to, from, skipFuncs ) {
 91+ if ( to && from ) {
 92+ each( from, function( name, value ) {
 93+ if ( !skipFuncs || typeof value != 'function' ) {
 94+ to[name] = value;
 95+ }
 96+ } );
 97+ }
 98+ }
 99+
 100+ // var arr = select("elem.className");
 101+ function select( query ) {
 102+ var index = query.indexOf( "." );
 103+ if ( index != - 1 ) {
 104+ var tag = query.substring( 0, index ) || "*";
 105+ var klass = query.substring( index + 1, query.length );
 106+ var els = [];
 107+ each( document.getElementsByTagName( tag ), function() {
 108+ if ( this.className && this.className.indexOf( klass ) != - 1 ) {
 109+ els.push( this );
 110+ }
 111+ } );
 112+ return els;
 113+ }
 114+ }
 115+
 116+ // fix event inconsistencies across browsers
 117+ function stopEvent( e ) {
 118+ e = e || window.event;
 119+
 120+ if ( e.preventDefault ) {
 121+ e.stopPropagation();
 122+ e.preventDefault();
 123+
 124+ } else {
 125+ e.returnValue = false;
 126+ e.cancelBubble = true;
 127+ }
 128+ return false;
 129+ }
 130+
 131+ // push an event listener into existing array of listeners
 132+ function bind( to, evt, fn ) {
 133+ to[evt] = to[evt] || [];
 134+ to[evt].push( fn );
 135+ }
 136+
 137+
 138+ // generates an unique id
 139+ function makeId() {
 140+ return "_" + ( "" + Math.random() ).substring( 2, 10 );
 141+ }
 142+
 143+// }}}
 144+// {{{ Clip
 145+ var Clip = function( json, index, player ) {
 146+ // private variables
 147+ var self = this;
 148+ var cuepoints = { };
 149+ var listeners = { };
 150+ this.index = index;
 151+
 152+ // instance variables
 153+ if ( typeof json == 'string' ) {
 154+ json = { url:json };
 155+ }
 156+
 157+ extend( this, json, true );
 158+
 159+ // event handling
 160+ each( ( "Begin*,Start,Pause*,Resume*,Seek*,Stop*,Finish*,LastSecond,Update,BufferFull,BufferEmpty,BufferStop" ).split( "," ),
 161+ function() {
 162+
 163+ var evt = "on" + this;
 164+
 165+ // before event
 166+ if ( evt.indexOf( "*" ) != - 1 ) {
 167+ evt = evt.substring( 0, evt.length - 1 );
 168+ var before = "onBefore" + evt.substring( 2 );
 169+
 170+ self[before] = function( fn ) {
 171+ bind( listeners, before, fn );
 172+ return self;
 173+ };
 174+ }
 175+
 176+ self[evt] = function( fn ) {
 177+ bind( listeners, evt, fn );
 178+ return self;
 179+ };
 180+
 181+ // set common clip event listeners to player level
 182+ if ( index == - 1 ) {
 183+ if ( self[before] ) {
 184+ player[before] = self[before];
 185+ }
 186+ if ( self[evt] ) {
 187+ player[evt] = self[evt];
 188+ }
 189+ }
 190+ } );
 191+
 192+ extend( this, {
 193+ onCuepoint: function( points, fn ) {
 194+
 195+ // embedded cuepoints
 196+ if ( arguments.length == 1 ) {
 197+ cuepoints.embedded = [null, points];
 198+ return self;
 199+ }
 200+
 201+ if ( typeof points == 'number' ) {
 202+ points = [points];
 203+ }
 204+
 205+ var fnId = makeId();
 206+ cuepoints[fnId] = [points, fn];
 207+
 208+ if ( player.isLoaded() ) {
 209+ player._api().fp_addCuepoints( points, index, fnId );
 210+ }
 211+
 212+ return self;
 213+ },
 214+ update: function( json ) {
 215+ extend( self, json );
 216+
 217+ if ( player.isLoaded() ) {
 218+ player._api().fp_updateClip( json, index );
 219+ }
 220+ var conf = player.getConfig();
 221+ var clip = ( index == - 1 ) ? conf.clip : conf.playlist[index];
 222+ extend( clip, json, true );
 223+ },
 224+ // internal event for performing clip tasks. should be made private someday
 225+ _fireEvent: function( evt, arg1, arg2, target ) {
 226+
 227+ if ( evt == 'onLoad' ) {
 228+ each( cuepoints, function( key, val ) {
 229+ player._api().fp_addCuepoints( val[0], index, key );
 230+ } );
 231+ return false;
 232+ }
 233+
 234+ // target clip we are working against
 235+ if ( index != - 1 ) {
 236+ target = self;
 237+ }
 238+
 239+ if ( evt == 'onCuepoint' ) {
 240+ var fn = cuepoints[arg1];
 241+ if ( fn ) {
 242+ return fn[1].call( player, target, arg2 );
 243+ }
 244+ }
 245+
 246+ if ( evt == 'onStart' || evt == 'onUpdate' ) {
 247+
 248+ extend( target, arg1 );
 249+
 250+ if ( !target.duration ) {
 251+ target.duration = arg1.metaData.duration;
 252+ } else {
 253+ target.fullDuration = arg1.metaData.duration;
 254+ }
 255+ }
 256+
 257+ var ret = true;
 258+ each( listeners[evt], function() {
 259+ ret = this.call( player, target, arg1 );
 260+ } );
 261+ return ret;
 262+ }
 263+ } );
 264+
 265+ // get cuepoints from config
 266+ if ( json.onCuepoint ) {
 267+ self.onCuepoint.apply( self, json.onCuepoint );
 268+ delete json.onCuepoint;
 269+ }
 270+
 271+ // get other events
 272+ each( json, function( key, val ) {
 273+ if ( typeof val == 'function' ) {
 274+ bind( listeners, key, val );
 275+ delete json[key];
 276+ }
 277+ } );
 278+
 279+ // setup common clip event callbacks for Player object too (shortcuts)
 280+ if ( index == - 1 ) {
 281+ player.onCuepoint = this.onCuepoint;
 282+ }
 283+ };
 284+
 285+// }}}
 286+// {{{ Plugin
 287+ var Plugin = function( name, json, player, fn ) {
 288+ var listeners = { };
 289+ var self = this;
 290+ var hasMethods = false;
 291+
 292+ if ( fn ) {
 293+ extend( listeners, fn );
 294+ }
 295+
 296+ // custom callback functions in configuration
 297+ each( json, function( key, val ) {
 298+ if ( typeof val == 'function' ) {
 299+ listeners[key] = val;
 300+ delete json[key];
 301+ }
 302+ } );
 303+
 304+ // core plugin methods
 305+ extend( this, {
 306+ animate: function( props, speed, fn ) {
 307+ if ( !props ) {
 308+ return self;
 309+ }
 310+
 311+ if ( typeof speed == 'function' ) {
 312+ fn = speed;
 313+ speed = 500;
 314+ }
 315+
 316+ if ( typeof props == 'string' ) {
 317+ var key = props;
 318+ props = { };
 319+ props[key] = speed;
 320+ speed = 500;
 321+ }
 322+
 323+ if ( fn ) {
 324+ var fnId = makeId();
 325+ listeners[fnId] = fn;
 326+ }
 327+
 328+ if ( speed === undefined ) { speed = 500; }
 329+ json = player._api().fp_animate( name, props, speed, fnId );
 330+ return self;
 331+ },
 332+ css: function( props, val ) {
 333+ if ( val !== undefined ) {
 334+ var css = { };
 335+ css[props] = val;
 336+ props = css;
 337+ }
 338+ try {
 339+ json = player._api().fp_css( name, props );
 340+ extend( self, json );
 341+ return self;
 342+ } catch ( e ) {
 343+ js_log( 'flow player could not set css: ' + json );
 344+ }
 345+ },
 346+ show: function() {
 347+ this.display = 'block';
 348+ player._api().fp_showPlugin( name );
 349+ return self;
 350+ },
 351+ hide: function() {
 352+ this.display = 'none';
 353+ player._api().fp_hidePlugin( name );
 354+ return self;
 355+ },
 356+ toggle: function() {
 357+ this.display = player._api().fp_togglePlugin( name );
 358+ return self;
 359+ },
 360+ fadeTo: function( o, speed, fn ) {
 361+
 362+ if ( typeof speed == 'function' ) {
 363+ fn = speed;
 364+ speed = 500;
 365+ }
 366+
 367+ if ( fn ) {
 368+ var fnId = makeId();
 369+ listeners[fnId] = fn;
 370+ }
 371+ this.display = player._api().fp_fadeTo( name, o, speed, fnId );
 372+ this.opacity = o;
 373+ return self;
 374+ },
 375+ fadeIn: function( speed, fn ) {
 376+ return self.fadeTo( 1, speed, fn );
 377+ },
 378+ fadeOut: function( speed, fn ) {
 379+ return self.fadeTo( 0, speed, fn );
 380+ },
 381+ getName: function() {
 382+ return name;
 383+ },
 384+ // internal method not meant to be used by clients
 385+ _fireEvent: function( evt, arg ) {
 386+ // update plugins properties & methods
 387+ if ( evt == 'onUpdate' ) {
 388+ var json = arg || player._api().fp_getPlugin( name );
 389+ if ( !json ) { return; }
 390+
 391+ Extend( self, json );
 392+ delete self.methods;
 393+
 394+ if ( !hasMethods ) {
 395+ each( json.methods, function() {
 396+ var method = "" + this;
 397+
 398+ self[method] = function() {
 399+ var a = [].slice.call( arguments );
 400+ var ret = player._api().fp_invoke( name, method, a );
 401+ return ret == 'undefined' ? self : ret;
 402+ };
 403+ } );
 404+ hasMethods = true;
 405+ }
 406+ }
 407+
 408+ // plugin callbacks
 409+ var fn = listeners[evt];
 410+
 411+ if ( fn ) {
 412+ fn.call( self, arg );
 413+
 414+ // "one-shot" callback
 415+ if ( evt.substring( 0, 1 ) == "_" ) {
 416+ delete listeners[evt];
 417+ }
 418+ }
 419+ }
 420+
 421+ } );
 422+
 423+ };
 424+
 425+// }}}
 426+function Player( wrapper, params, conf ) {
 427+ // private variables (+ arguments)
 428+ var
 429+ self = this,
 430+ api = null,
 431+ html,
 432+ commonClip,
 433+ playlist = [],
 434+ plugins = { },
 435+ listeners = { },
 436+ playerId,
 437+ apiId,
 438+ activeIndex,
 439+ swfHeight,
 440+ wrapperHeight;
 441+
 442+// {{{ public methods
 443+ extend( self, {
 444+ id: function() {
 445+ return playerId;
 446+ },
 447+ isLoaded: function() {
 448+ return ( api !== null );
 449+ },
 450+ getParent: function() {
 451+ return wrapper;
 452+ },
 453+ hide: function( all ) {
 454+ if ( all ) { wrapper.style.height = "0px"; }
 455+ if ( api ) { api.style.height = "0px"; }
 456+ return self;
 457+ },
 458+ show: function() {
 459+ wrapper.style.height = wrapperHeight + "px";
 460+ if ( api ) { api.style.height = swfHeight + "px"; }
 461+ return self;
 462+ },
 463+ isHidden: function() {
 464+ return api && parseInt( api.style.height, 10 ) === 0;
 465+ },
 466+ load: function( fn ) {
 467+
 468+ if ( !api && self._fireEvent( "onBeforeLoad" ) !== false ) {
 469+
 470+ // unload all instances
 471+ each( players, function() {
 472+ this.unload();
 473+ } );
 474+
 475+ html = wrapper.innerHTML;
 476+ flashembed( wrapper, params, { config: conf } );
 477+
 478+ // function argument
 479+ if ( fn ) {
 480+ fn.cached = true;
 481+ bind( listeners, "onLoad", fn );
 482+ }
 483+ }
 484+
 485+ return self;
 486+ },
 487+ unload: function() {
 488+ if ( api && html.replace( /\s/g, '' ) !== '' && !api.fp_isFullscreen() &&
 489+ self._fireEvent( "onBeforeUnload" ) !== false ) {
 490+ api.fp_close();
 491+ wrapper.innerHTML = html;
 492+ self._fireEvent( "onUnload" );
 493+ api = null;
 494+ }
 495+
 496+ return self;
 497+ },
 498+ getClip: function( index ) {
 499+ if ( index === undefined ) {
 500+ index = activeIndex;
 501+ }
 502+ return playlist[index];
 503+ },
 504+ getCommonClip: function() {
 505+ return commonClip;
 506+ },
 507+ getPlaylist: function() {
 508+ return playlist;
 509+ },
 510+ getPlugin: function( name ) {
 511+ var plugin = plugins[name];
 512+ // create plugin if nessessary
 513+ if ( !plugin && self.isLoaded() ) {
 514+ var json = self._api().fp_getPlugin( name );
 515+ if ( json ) {
 516+ plugin = new Plugin( name, json, self );
 517+ plugins[name] = plugin;
 518+ }
 519+ }
 520+ return plugin;
 521+ },
 522+ getScreen: function() {
 523+ return self.getPlugin( "screen" );
 524+ },
 525+ getControls: function() {
 526+ return self.getPlugin( "controls" );
 527+ },
 528+ getConfig: function() {
 529+ return clone ( conf );
 530+ },
 531+ getFlashParams: function() {
 532+ return params;
 533+ },
 534+ loadPlugin: function( name, url, props, fn ) {
 535+ // properties not supplied
 536+ if ( typeof props == 'function' ) {
 537+ fn = props;
 538+ props = { };
 539+ }
 540+
 541+ // if fn not given, make a fake id so that plugin's onUpdate get's fired
 542+ var fnId = fn ? makeId() : "_";
 543+ self._api().fp_loadPlugin( name, url, props, fnId );
 544+
 545+ // create new plugin
 546+ var arg = { };
 547+ arg[fnId] = fn;
 548+ var p = new Plugin( name, null, self, arg );
 549+ plugins[name] = p;
 550+ return p;
 551+ },
 552+ getState: function() {
 553+ return api ? api.fp_getState() : - 1;
 554+ },
 555+ // "lazy" play
 556+ play: function( clip ) {
 557+ function play() {
 558+ if ( clip !== undefined ) {
 559+ self._api().fp_play( clip );
 560+ } else {
 561+ if ( typeof self._api().fp_play == 'function' )
 562+ self._api().fp_play();
 563+ }
 564+ }
 565+
 566+ if ( api ) {
 567+ play();
 568+ } else {
 569+ self.load( function() {
 570+ play();
 571+ } );
 572+ }
 573+
 574+ return self;
 575+ },
 576+ getVersion: function() {
 577+ var js = "flowplayer.js 3.0.0-rc5";
 578+ if ( api ) {
 579+ var ver = api.fp_getVersion();
 580+ ver.push( js );
 581+ return ver;
 582+ }
 583+ return js;
 584+ },
 585+ _api: function() {
 586+ if ( !api ) {
 587+ throw "Flowplayer " + self.id() + " not loaded. Try moving your call to player's onLoad event";
 588+ }
 589+ return api;
 590+ },
 591+ _dump: function() {
 592+ console.log( listeners );
 593+ }
 594+ } );
 595+
 596+ // event handlers
 597+ each( ( "Click*,Load*,Unload*,Keypress*,Volume*,Mute*,Unmute*,PlaylistReplace,Fullscreen*,FullscreenExit,Error" ).split( "," ),
 598+ function() {
 599+ var name = "on" + this;
 600+
 601+ // before event
 602+ if ( name.indexOf( "*" ) != - 1 ) {
 603+ name = name.substring( 0, name.length - 1 );
 604+ var name2 = "onBefore" + name.substring( 2 );
 605+ self[name2] = function( fn ) {
 606+ bind( listeners, name2, fn );
 607+ return self;
 608+ };
 609+ }
 610+
 611+ // normal event
 612+ self[name] = function( fn ) {
 613+ bind( listeners, name, fn );
 614+ return self;
 615+ };
 616+ }
 617+ );
 618+
 619+ // core API methods
 620+ each( ( "pause,resume,mute,unmute,stop,toggle,seek,getStatus,getVolume,setVolume,getTime,isPaused,isPlaying,startBuffering,stopBuffering,isFullscreen,reset" ).split( "," ),
 621+ function() {
 622+ var name = this;
 623+
 624+ self[name] = function( arg ) {
 625+ if ( !api ) { return self; }
 626+ try {
 627+ var ret = ( arg === undefined ) ? api["fp_" + name]() : api["fp_" + name]( arg );
 628+ return ret == 'undefined' ? self : ret;
 629+ } catch ( e ) {
 630+ js_log( 'flowplayer could not access fp_ ' + name );
 631+ }
 632+ };
 633+ }
 634+ );
 635+
 636+// }}}
 637+// {{{ public method: _fireEvent
 638+ self._fireEvent = function( evt, arg0, arg1, arg2 ) {
 639+ if ( conf.debug ) {
 640+ log( arguments );
 641+ }
 642+
 643+ // internal onLoad
 644+ if ( evt == 'onLoad' && !api ) {
 645+ api = api || el( apiId );
 646+ swfHeight = api.clientHeight;
 647+
 648+ each( playlist, function() {
 649+ this._fireEvent( "onLoad" );
 650+ } );
 651+
 652+ each( plugins, function( name, p ) {
 653+ p._fireEvent( "onUpdate" );
 654+ } );
 655+
 656+ commonClip._fireEvent( "onLoad" );
 657+ }
 658+
 659+ if ( evt == 'onContextMenu' ) {
 660+ each( conf.contextMenu[arg0], function( key, fn ) {
 661+ fn.call( self );
 662+ } );
 663+ return;
 664+ }
 665+
 666+ if ( evt == 'onPluginEvent' ) {
 667+ var name = arg0.name || arg0;
 668+ var p = plugins[name];
 669+ if ( p ) {
 670+ if ( arg0.name ) {
 671+ p._fireEvent( "onUpdate", arg0 );
 672+ }
 673+ p._fireEvent( arg1 );
 674+ }
 675+ return;
 676+ }
 677+
 678+ // onPlaylistReplace
 679+ if ( evt == 'onPlaylistReplace' ) {
 680+ playlist = [];
 681+ var index = 0;
 682+ each( arg0, function() {
 683+ playlist.push( new Clip( this, index++ ) );
 684+ } );
 685+ }
 686+
 687+ var ret = true;
 688+
 689+ // clip event
 690+ if ( arg0 === 0 || ( arg0 && arg0 >= 0 ) ) {
 691+ activeIndex = arg0;
 692+ var clip = playlist[arg0];
 693+
 694+ if ( clip ) {
 695+ ret = clip._fireEvent( evt, arg1, arg2 );
 696+ }
 697+
 698+ if ( !clip || ret !== false ) {
 699+ // clip argument is given for common clip, because it behaves as the target
 700+ ret = commonClip._fireEvent( evt, arg1, arg2, clip );
 701+ }
 702+ }
 703+
 704+ // player event
 705+ var i = 0;
 706+ each( listeners[evt], function() {
 707+ ret = this.call( self, arg0 );
 708+
 709+ // remove cached entry
 710+ if ( this.cached ) {
 711+ listeners[evt].splice( i, 1 );
 712+ }
 713+
 714+ // break loop
 715+ if ( ret === false ) { return false; }
 716+ i++;
 717+
 718+ } );
 719+
 720+ return ret;
 721+ };
 722+
 723+// }}}
 724+// {{{ init
 725+ function init() {
 726+ if ( $f( wrapper ) ) {
 727+ return null;
 728+ }
 729+
 730+ wrapperHeight = parseInt( wrapper.style.height ) || wrapper.clientHeight;
 731+
 732+ // register this player into global array of instances
 733+ players.push( self );
 734+
 735+
 736+ // flashembed parameters
 737+ if ( typeof params == 'string' ) {
 738+ params = { src: params };
 739+ }
 740+
 741+ // playerId
 742+ playerId = wrapper.id || "fp" + makeId();
 743+ apiId = params.id || playerId + "_api";
 744+ params.id = apiId;
 745+ conf.playerId = playerId;
 746+
 747+
 748+ // plain url is given as config
 749+ if ( typeof conf == 'string' ) {
 750+ conf = { clip: { url:conf } };
 751+ }
 752+
 753+ // common clip is always there
 754+ conf.clip = conf.clip || { };
 755+ commonClip = new Clip( conf.clip, - 1, self );
 756+
 757+
 758+ // wrapper href as playlist
 759+ if ( wrapper.getAttribute( "href" ) ) {
 760+ conf.playlist = [ { url:wrapper.getAttribute( "href", 2 ) }];
 761+ }
 762+
 763+ // playlist
 764+ conf.playlist = conf.playlist || [conf.clip];
 765+
 766+ var index = 0;
 767+ each( conf.playlist, function() {
 768+
 769+ var clip = this;
 770+
 771+ // clip is an array, we don't allow that
 772+ if ( typeof clip == 'object' && clip.length ) {
 773+ clip = "" + clip;
 774+ }
 775+
 776+ if ( !clip.url && typeof clip == 'string' ) {
 777+ clip = { url: clip };
 778+ }
 779+
 780+ // populate common clip properties to each clip
 781+ extend( clip, conf.clip, true );
 782+
 783+ // modify configuration playlist
 784+ conf.playlist[index] = clip;
 785+
 786+ // populate playlist array
 787+ clip = new Clip( clip, index, self );
 788+ playlist.push( clip );
 789+ index++;
 790+ } );
 791+
 792+
 793+ // event listeners
 794+ each( conf, function( key, val ) {
 795+ if ( typeof val == 'function' ) {
 796+ bind( listeners, key, val );
 797+ delete conf[key];
 798+ }
 799+ } );
 800+
 801+
 802+ // plugins
 803+ each( conf.plugins, function( name, val ) {
 804+ if ( val ) {
 805+ plugins[name] = new Plugin( name, val, self );
 806+ }
 807+ } );
 808+
 809+
 810+ // setup controlbar plugin if not explicitly defined
 811+ if ( !conf.plugins || conf.plugins.controls === undefined ) {
 812+ plugins.controls = new Plugin( "controls", null, self );
 813+ }
 814+
 815+ // Flowplayer uses black background by default
 816+ params.bgcolor = params.bgcolor || "#000000";
 817+
 818+
 819+ // setup default settings for express install
 820+ params.version = params.version || [9, 0];
 821+ params.expressInstall = 'http://www.flowplayer.org/swf/expressinstall.swf';
 822+
 823+
 824+ // click function
 825+ function doClick( e ) {
 826+ if ( self._fireEvent( "onBeforeClick" ) !== false ) {
 827+ self.load();
 828+ }
 829+ return stopEvent( e );
 830+ }
 831+
 832+ // defer loading upon click
 833+ html = wrapper.innerHTML;
 834+ if ( html.replace( /\s/g, '' ) !== '' ) {
 835+
 836+ if ( wrapper.addEventListener ) {
 837+ wrapper.addEventListener( "click", doClick, false );
 838+
 839+ } else if ( wrapper.attachEvent ) {
 840+ wrapper.attachEvent( "onclick", doClick );
 841+ }
 842+
 843+ // player is loaded upon page load
 844+ } else {
 845+
 846+ // prevent default action from wrapper (safari problem) loaded
 847+ if ( wrapper.addEventListener ) {
 848+ wrapper.addEventListener( "click", stopEvent, false );
 849+ }
 850+
 851+ // load player
 852+ self.load();
 853+ }
 854+
 855+ }
 856+
 857+ // possibly defer initialization until DOM get's loaded
 858+ if ( typeof wrapper == 'string' ) {
 859+ flashembed.domReady( function() {
 860+ var node = el( wrapper );
 861+
 862+ if ( !node ) {
 863+ throw "Flowplayer cannot access element: " + wrapper;
 864+ } else {
 865+ wrapper = node;
 866+ init();
 867+ }
 868+ } );
 869+
 870+ // we have a DOM element so page is already loaded
 871+ } else {
 872+ init();
 873+ }
 874+// }}}
 875+}
 876+
 877+// {{{ flowplayer() & statics
 878+// container for player instances
 879+var players = [];
 880+
 881+// this object is returned when multiple player's are requested
 882+function Iterator( arr ) {
 883+ this.length = arr.length;
 884+
 885+ this.each = function( fn ) {
 886+ each( arr, fn );
 887+ };
 888+
 889+ this.size = function() {
 890+ return arr.length;
 891+ };
 892+}
 893+
 894+// these two variables are the only global variables
 895+window.flowplayer = window.$f = function() {
 896+ var instance = null;
 897+ var arg = arguments[0];
 898+
 899+ // $f()
 900+ if ( !arguments.length ) {
 901+ each( players, function() {
 902+ if ( this.isLoaded() ) {
 903+ instance = this;
 904+ return false;
 905+ }
 906+ } );
 907+
 908+ return instance || players[0];
 909+ }
 910+
 911+ if ( arguments.length == 1 ) {
 912+ // $f(index);
 913+ if ( typeof arg == 'number' ) {
 914+ return players[arg];
 915+
 916+ // $f(wrapper || 'containerId' || '*');
 917+ } else {
 918+ // $f("*");
 919+ if ( arg == '*' ) {
 920+ return new Iterator( players );
 921+ }
 922+
 923+ // $f(wrapper || 'containerId');
 924+ each( players, function() {
 925+ if ( this.id() == arg.id || this.id() == arg || this.getParent() == arg ) {
 926+ instance = this;
 927+ return false;
 928+ }
 929+ } );
 930+
 931+ return instance;
 932+ }
 933+ }
 934+
 935+ // instance builder
 936+ if ( arguments.length > 1 ) {
 937+ var swf = arguments[1];
 938+ var conf = ( arguments.length == 3 ) ? arguments[2] : { };
 939+
 940+ if ( typeof arg == 'string' ) {
 941+ // select arg by classname
 942+ if ( arg.indexOf( "." ) != - 1 ) {
 943+ var instances = [];
 944+
 945+ each( select( arg ), function() {
 946+ instances.push( new Player( this, clone ( swf ), clone ( conf ) ) );
 947+ } );
 948+
 949+ return new Iterator( instances );
 950+
 951+ // select node by id
 952+ } else {
 953+ var node = el( arg );
 954+ return new Player( node !== null ? node : arg, swf, conf );
 955+ }
 956+
 957+
 958+ // arg is a DOM element
 959+ } else if ( arg ) {
 960+ return new Player( arg, swf, conf );
 961+ }
 962+ }
 963+
 964+ return null;
 965+};
 966+
 967+extend( window.$f, {
 968+ // called by Flash External Interface
 969+ fireEvent: function( id, evt, a0, a1, a2 ) {
 970+ var p = $f( id );
 971+ return p ? p._fireEvent( evt, a0, a1, a2 ) : null;
 972+ },
 973+
 974+ // create plugins by modifying Player's prototype
 975+ addPlugin: function( name, fn ) {
 976+ Player.prototype[name] = fn;
 977+ return $f;
 978+ },
 979+
 980+ // utility methods for plugin developers
 981+ each: each,
 982+
 983+ extend: extend
 984+} );
 985+
 986+// }}}
 987+// {{{ jQuery support
 988+
 989+if ( typeof jQuery == 'function' ) {
 990+ jQuery.prototype.flowplayer = function( params, conf ) {
 991+
 992+ // select instances
 993+ if ( !arguments.length || typeof arguments[0] == 'number' ) {
 994+ var arr = [];
 995+ this.each( function() {
 996+ var p = $f( this );
 997+ if ( p ) {
 998+ arr.push( p );
 999+ }
 1000+ } );
 1001+ return arguments.length ? arr[arguments[0]] : new Iterator( arr );
 1002+ }
 1003+
 1004+ // create flowplayer instances
 1005+ return this.each( function() {
 1006+ $f( this, clone ( params ), conf ? clone ( conf ) : { } );
 1007+ } );
 1008+
 1009+ };
 1010+
 1011+}
 1012+
 1013+// }}}
 1014+
 1015+
 1016+} )();
 1017+/**
 1018+ * flashembed 0.34. Adobe Flash embedding script
 1019+ *
 1020+ * http://flowplayer.org/tools/flash-embed.html
 1021+ *
 1022+ * Copyright (c) 2008 Tero Piirainen (support@flowplayer.org)
 1023+ *
 1024+ * Released under the MIT License:
 1025+ * http://www.opensource.org/licenses/mit-license.php
 1026+ *
 1027+ * >> Basically you can do anything you want but leave this header as is <<
 1028+ *
 1029+ * first version 0.01 - 03/11/2008
 1030+ * version 0.34 - Tue Nov 11 2008 09:09:52 GMT-0000 (GMT+00:00)
 1031+ */
 1032+( function() {
 1033+
 1034+// {{{ utility functions
 1035+
 1036+var jQ = typeof jQuery == 'function';
 1037+
 1038+
 1039+// from "Pro JavaScript techniques" by John Resig
 1040+function isDomReady() {
 1041+
 1042+ if ( domReady.done ) { return false; }
 1043+
 1044+ var d = document;
 1045+ if ( d && d.getElementsByTagName && d.getElementById && d.body ) {
 1046+ clearInterval( domReady.timer );
 1047+ domReady.timer = null;
 1048+
 1049+ for ( var i = 0; i < domReady.ready.length; i++ ) {
 1050+ domReady.ready[i].call();
 1051+ }
 1052+
 1053+ domReady.ready = null;
 1054+ domReady.done = true;
 1055+ }
 1056+}
 1057+
 1058+// if jQuery is present, use it's more effective domReady method
 1059+var domReady = jQ ? jQuery : function( f ) {
 1060+
 1061+ if ( domReady.done ) {
 1062+ return f();
 1063+ }
 1064+
 1065+ if ( domReady.timer ) {
 1066+ domReady.ready.push( f );
 1067+
 1068+ } else {
 1069+ domReady.ready = [f];
 1070+ domReady.timer = setInterval( isDomReady, 13 );
 1071+ }
 1072+};
 1073+
 1074+
 1075+// override extend params function
 1076+function extend( to, from ) {
 1077+ if ( from ) {
 1078+ for ( key in from ) {
 1079+ if ( from.hasOwnProperty( key ) ) {
 1080+ to[key] = from[key];
 1081+ }
 1082+ }
 1083+ }
 1084+
 1085+ return to;
 1086+}
 1087+
 1088+
 1089+function concatVars( vars ) {
 1090+ var out = "";
 1091+
 1092+ for ( var key in vars ) {
 1093+ if ( vars[key] ) {
 1094+ out += [key] + '=' + asString( vars[key] ) + '&';
 1095+ }
 1096+ }
 1097+ return out.substring( 0, out.length - 1 );
 1098+}
 1099+
 1100+
 1101+
 1102+// JSON.asString() function
 1103+function asString( obj ) {
 1104+
 1105+ switch ( typeOf( obj ) ) {
 1106+ case 'string':
 1107+ obj = obj.replace( new RegExp( '(["\\\\])', 'g' ), '\\$1' );
 1108+
 1109+ // flash does not handle %- characters well. transforms "50%" to "50pct" (a dirty hack, I admit)
 1110+ obj = obj.replace( /^\s?(\d+)%/, "$1pct" );
 1111+ return '"' + obj + '"';
 1112+
 1113+ case 'array':
 1114+ return '[' + map( obj, function( el ) {
 1115+ return asString( el );
 1116+ } ).join( ',' ) + ']';
 1117+
 1118+ case 'function':
 1119+ return '"function()"';
 1120+
 1121+ case 'object':
 1122+ var str = [];
 1123+ for ( var prop in obj ) {
 1124+ if ( obj.hasOwnProperty( prop ) ) {
 1125+ str.push( '"' + prop + '":' + asString( obj[prop] ) );
 1126+ }
 1127+ }
 1128+ return '{' + str.join( ',' ) + '}';
 1129+ }
 1130+
 1131+ // replace ' --> " and remove spaces
 1132+ return String( obj ).replace( /\s/g, " ").replace( /\'/g, "\"" );
 1133+}
 1134+
 1135+
 1136+// private functions
 1137+function typeOf(obj) {
 1138+ if (obj === null || obj === undefined) { return false; }
 1139+ var type = typeof obj;
 1140+ return (type == 'object' && obj.push) ? 'array' : type;
 1141+}
 1142+
 1143+
 1144+// version 9 bugfix: (http://blog.deconcept.com/2006/07/28/swfobject-143-released/)
 1145+if (window.attachEvent) {
 1146+ window.attachEvent("onbeforeunload", function() {
 1147+ __flash_unloadHandler = function() {};
 1148+ __flash_savedUnloadHandler = function() {};
 1149+ });
 1150+}
 1151+
 1152+function map(arr, func) {
 1153+ var newArr = [];
 1154+ for (var i in arr) {
 1155+ if (arr.hasOwnProperty(i)) {
 1156+ newArr[i] = func(arr[i]);
 1157+ }
 1158+ }
 1159+ return newArr;
 1160+}
 1161+
 1162+function getEmbedCode(p, c) {
 1163+ var html = ' < embed type = "application/x-shockwave-flash" ';
 1164+
 1165+ if (p.id) { extend(p, {name:p.id}); }
 1166+
 1167+ for (var key in p) {
 1168+ if (p[key] !== null) {
 1169+ html += key + '="' + p[key] + '"\n\t';
 1170+ }
 1171+ }
 1172+
 1173+ if (c) {
 1174+ html += 'flashvars=\'' + concatVars( c ) + '\'';
 1175+ }
 1176+
 1177+ // thanks Tom Price (07/17/2008)
 1178+ html += '/>';
 1179+
 1180+ return html;
 1181+}
 1182+
 1183+function getObjectCode( p, c, embeddable ) {
 1184+
 1185+ var html = '<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" ';
 1186+ html += 'width="' + p.width + '" height="' + p.height + '"';
 1187+
 1188+ // force id for IE. otherwise embedded Flash object cannot be returned
 1189+ if ( !p.id && document.all ) {
 1190+ p.id = "_" + ( "" + Math.random() ).substring( 5 );
 1191+ }
 1192+
 1193+ if ( p.id ) {
 1194+ html += ' id="' + p.id + '"';
 1195+ }
 1196+
 1197+ html += '>';
 1198+
 1199+ // sometimes ie fails to load flash if it's on cache
 1200+ if ( document.all ) {
 1201+ p.src += ( ( p.src.indexOf( "?" ) != - 1 ? "&" : "?" ) + Math.random() );
 1202+ }
 1203+
 1204+ html += '\n\t<param name="movie" value="' + p.src + '" />';
 1205+
 1206+ var e = extend( { }, p );
 1207+ e.id = e.width = e.height = e.src = null;
 1208+
 1209+ for ( var k in e ) {
 1210+ if ( e[k] !== null ) {
 1211+ html += '\n\t<param name="' + k + '" value="' + e[k] + '" />';
 1212+ }
 1213+ }
 1214+
 1215+ if ( c ) {
 1216+ html += '\n\t<param name="flashvars" value=\'' + concatVars( c ) + '\' />';
 1217+ }
 1218+
 1219+ if ( embeddable ) {
 1220+ html += getEmbedCode( p, c );
 1221+ }
 1222+
 1223+ html += "</object>";
 1224+
 1225+ return html;
 1226+}
 1227+
 1228+function getFullHTML( p, c ) {
 1229+ return getObjectCode( p, c, true );
 1230+}
 1231+
 1232+function getHTML( p, c ) {
 1233+ var isNav = navigator.plugins && navigator.mimeTypes && navigator.mimeTypes.length;
 1234+ return ( isNav ) ? getEmbedCode( p, c ) : getObjectCode( p, c );
 1235+}
 1236+
 1237+// }}}
 1238+
 1239+
 1240+window.flashembed = function( root, userParams, flashvars ) {
 1241+
 1242+
 1243+// {{{ construction
 1244+
 1245+ // setup params
 1246+ var params = {
 1247+
 1248+ // very common params
 1249+ src: '#',
 1250+ width: '100%',
 1251+ height: '100%',
 1252+
 1253+ // flashembed specific options
 1254+ version:null,
 1255+ onFail:null,
 1256+ expressInstall:null,
 1257+ debug: false,
 1258+
 1259+ // flashembed defaults
 1260+ // bgcolor: 'transparent',
 1261+ allowfullscreen: true,
 1262+ allowscriptaccess: 'always',
 1263+ quality: 'high',
 1264+ type: 'application/x-shockwave-flash',
 1265+ pluginspage: 'http://www.adobe.com/go/getflashplayer'
 1266+ };
 1267+
 1268+
 1269+ if ( typeof userParams == 'string' ) {
 1270+ userParams = { src: userParams };
 1271+ }
 1272+
 1273+ extend( params, userParams );
 1274+
 1275+ var version = flashembed.getVersion();
 1276+ var required = params.version;
 1277+ var express = params.expressInstall;
 1278+ var debug = params.debug;
 1279+
 1280+
 1281+ if ( typeof root == 'string' ) {
 1282+ var el = document.getElementById( root );
 1283+ if ( el ) {
 1284+ root = el;
 1285+ } else {
 1286+ domReady( function() {
 1287+ flashembed( root, userParams, flashvars );
 1288+ } );
 1289+ return;
 1290+ }
 1291+ }
 1292+
 1293+ if ( !root ) { return; }
 1294+
 1295+
 1296+ // is supported
 1297+ if ( !required || flashembed.isSupported( required ) ) {
 1298+ params.onFail = params.version = params.expressInstall = params.debug = null;
 1299+
 1300+ // root.innerHTML may cause broplems: http://domscripting.com/blog/display/99
 1301+ // thanks to: Ryan Rud
 1302+ // var tmp = document.createElement("extradiv");
 1303+ // tmp.innerHTML = getHTML();
 1304+ // root.appendChild(tmp);
 1305+
 1306+ root.innerHTML = getHTML( params, flashvars );
 1307+
 1308+ // return our API
 1309+ return root.firstChild;
 1310+
 1311+ // custom fail event
 1312+ } else if ( params.onFail ) {
 1313+ var ret = params.onFail.call( params, flashembed.getVersion(), flashvars );
 1314+ if ( ret === true ) { root.innerHTML = ret; }
 1315+
 1316+
 1317+ // express install
 1318+ } else if ( required && express && flashembed.isSupported( [6, 65] ) ) {
 1319+
 1320+ extend( params, { src: express } );
 1321+
 1322+ flashvars = {
 1323+ MMredirectURL: location.href,
 1324+ MMplayerType: 'PlugIn',
 1325+ MMdoctitle: document.title
 1326+ };
 1327+
 1328+ root.innerHTML = getHTML( params, flashvars );
 1329+
 1330+ // not supported
 1331+ } else {
 1332+
 1333+ // minor bug fixed here 08.04.2008 (thanks JRodman)
 1334+
 1335+ if ( root.innerHTML.replace( /\s/g, '') !== '' ) {
 1336+ // custom content was supplied
 1337+
 1338+ } else {
 1339+ root.innerHTML =
 1340+ "<h2>Flash version " + required + " or greater is required</h2>" +
 1341+ "<h3>" +
 1342+ ( version[0] > 0 ? "Your version is " + version : "You have no flash plugin installed" ) +
 1343+ "</h3>" +
 1344+ "<p>Download latest version from <a href='" + params.pluginspage + "'>here</a></p>";
 1345+ }
 1346+ }
 1347+
 1348+ return root;
 1349+
 1350+// }}}
 1351+
 1352+
 1353+};
 1354+
 1355+
 1356+// {{{ static methods
 1357+
 1358+extend( window.flashembed, {
 1359+
 1360+ // returns arr[major, fix]
 1361+ getVersion: function() {
 1362+
 1363+ var version = [0, 0];
 1364+
 1365+ if ( navigator.plugins && typeof navigator.plugins["Shockwave Flash"] == "object" ) {
 1366+ var _d = navigator.plugins["Shockwave Flash"].description;
 1367+ if ( typeof _d != "undefined" ) {
 1368+ _d = _d.replace( /^.*\s+(\S+\s+\S+$ )/, "$1" );
 1369+ var _m = parseInt( _d.replace( /^(.*)\..*$/, "$1" ), 10 );
 1370+ var _r = / r / .test( _d ) ? parseInt( _d.replace( /^.*r(.*)$/ , "$1" ), 10 ) : 0;
 1371+ version = [_m, _r];
 1372+ }
 1373+
 1374+ } else if ( window.ActiveXObject ) {
 1375+
 1376+ try { // avoid fp 6 crashes
 1377+ var _a = new ActiveXObject( "ShockwaveFlash.ShockwaveFlash.7" );
 1378+
 1379+ } catch ( e ) {
 1380+ try {
 1381+ _a = new ActiveXObject( "ShockwaveFlash.ShockwaveFlash.6" );
 1382+ version = [6, 0];
 1383+ _a.AllowScriptAccess = "always"; // throws if fp < 6.47
 1384+
 1385+ } catch ( ee ) {
 1386+ if ( version[0] == 6 ) { return; }
 1387+ }
 1388+ try {
 1389+ _a = new ActiveXObject( "ShockwaveFlash.ShockwaveFlash" );
 1390+ } catch ( eee ) {
 1391+
 1392+ }
 1393+
 1394+ }
 1395+
 1396+ if ( typeof _a == "object" ) {
 1397+ _d = _a.GetVariable( "$version" ); // bugs in fp 6.21 / 6.23
 1398+ if ( typeof _d != "undefined" ) {
 1399+ _d = _d.replace( /^\S+\s+(.*)$/, "$1" ).split( "," );
 1400+ version = [parseInt( _d[0], 10 ), parseInt( _d[2], 10 )];
 1401+ }
 1402+ }
 1403+ }
 1404+
 1405+ return version;
 1406+ },
 1407+
 1408+ isSupported: function( version ) {
 1409+ var now = flashembed.getVersion();
 1410+ var ret = ( now[0] > version[0] ) || ( now[0] == version[0] && now[1] >= version[1] );
 1411+ return ret;
 1412+ },
 1413+
 1414+ domReady: domReady,
 1415+
 1416+ // returns a String representation from JSON object
 1417+ asString: asString,
 1418+
 1419+ getHTML: getHTML,
 1420+
 1421+ getFullHTML: getFullHTML
 1422+
 1423+} );
 1424+
 1425+// }}}
 1426+
 1427+
 1428+// setup jquery support
 1429+if ( jQ ) {
 1430+
 1431+ jQuery.prototype.flashembed = function( params, flashvars ) {
 1432+ return this.each( function() {
 1433+ flashembed( this, params, flashvars );
 1434+ } );
 1435+ };
 1436+
 1437+}
 1438+
 1439+} )();
 1440+
 1441+/************************************************
 1442+********* mv_embed extension to flowplayer.js ***
 1443+************************************************/
 1444+var flowplayerEmbed = {
 1445+ instanceOf:'flowplayerEmbed',
 1446+ monitorTimerId : 0,
 1447+ old_pid:0,
 1448+ didSeekJump:false,
 1449+ startedTimedPlayback:false,
 1450+ didDateStartTimeRestore:false,
 1451+ supports: {
 1452+ 'play_head' : true,
 1453+ 'pause' : true,
 1454+ 'stop' : true,
 1455+ 'time_display' : true,
 1456+ 'volume_control' : true
 1457+ },
 1458+ getEmbedHTML: function () {
 1459+ setTimeout( 'document.getElementById(\'' + this.id + '\').postEmbedJS()', 150 );
 1460+ return this.wrapEmebedContainer( this.getEmbedObj() );
 1461+ },
 1462+ getEmbedObj:function() {
 1463+ // give the embed element a unique pid (work around for flowplayer persistence)
 1464+ if ( this.old_pid != 0 ) {
 1465+ this.pid = this.pid + '_' + this.old_pid;
 1466+ }
 1467+ return '<a ' +
 1468+ 'href="' + this.getSrc() + '" ' +
 1469+ 'style="display:block;width:' + parseInt( this.width ) + 'px;height:' + parseInt( this.height ) + 'px" ' +
 1470+ 'id="' + this.pid + '">' +
 1471+ '</a>';
 1472+ },
 1473+ postEmbedJS: function()
 1474+ {
 1475+ var _this = this;
 1476+ js_log( 'embedFlow: uri:' + this.getSrc() + "\n" + mv_embed_path + 'libEmbedPlayer/binPlayers/flowplayer/flowplayer-3.0.1.swf' ) ;
 1477+ var flowConfig = {
 1478+ clip: {
 1479+ url: this.getSrc(),
 1480+ // when this is false playback does not start until play button is pressed
 1481+ autoPlay: true
 1482+ },
 1483+ plugins: {
 1484+ controls: {
 1485+ all: false,
 1486+ fullscreen: true,
 1487+ backgroundColor: 'transparent',
 1488+ backgroundGradient: 'none',
 1489+ autoHide:'always',
 1490+ top:'95%',
 1491+ right:'0px'
 1492+ }
 1493+ },
 1494+ screen: {
 1495+ opacity : '1.0'
 1496+ }
 1497+ };
 1498+
 1499+ // if in preview mode set grey and lower volume until "ready"
 1500+ if ( this.preview_mode ) {
 1501+ flowConfig.screen.opacity = 0.2;
 1502+ }
 1503+
 1504+ $f( this.pid, mv_embed_path + 'binPlayers/flowplayer/flowplayer-3.0.1.swf', flowConfig );
 1505+ // get the this.fla value:
 1506+ this.getFLA();
 1507+ // set up bindings (for when interacting with the swf causes action:
 1508+ this.fla.onPause( function() {
 1509+ _this.parent_pause(); // update the interface
 1510+ } )
 1511+ this.fla.onResume( function() {
 1512+ _this.parent_play(); // update the interface
 1513+ } );
 1514+
 1515+ // start monitor:
 1516+ this.monitor();
 1517+ this.old_pid++;
 1518+ },
 1519+ /* js hooks/controls */
 1520+ play: function() {
 1521+ this.getFLA();
 1522+ // update play/pause button etc
 1523+ this.parent_play();
 1524+ if ( this.fla ) {
 1525+ this.fla.play();
 1526+
 1527+ // on a resume make sure volume and opacity are correct
 1528+ this.restorePlayer();
 1529+ setTimeout( '$j(\'#' + this.id + '\').get(0).monitor()', 250 );
 1530+ }
 1531+ },
 1532+ // @@todo support mute
 1533+ toggleMute: function() {
 1534+ this.parent_toggleMute();
 1535+ this.getFLA();
 1536+ if ( this.fla ) {
 1537+ if ( this.muted ) {
 1538+
 1539+ } else {
 1540+
 1541+ }
 1542+ }
 1543+ },
 1544+ // @@ Suport UpDateVolumen
 1545+ updateVolumen:function( perc ) {
 1546+ this.getFLA();
 1547+ if ( this.fla )this.fla.setVolume( perc * 100 );
 1548+
 1549+ },
 1550+ // @@ Get Volumen
 1551+ getVolumen:function() {
 1552+ this.getFLA();
 1553+ if ( this.fla )
 1554+ return this.fla.getVolume() / 100;
 1555+ },
 1556+ fullscreen:function() {
 1557+ if ( this.fla ) {
 1558+ this.fla.fullscreen();
 1559+ } else {
 1560+ js_log( 'must be playing before you can go fullscreen' );
 1561+ }
 1562+ },
 1563+ pause : function()
 1564+ {
 1565+ this.getFLA();
 1566+ if ( !this.thumbnail_disp ) {
 1567+ this.parent_pause();
 1568+ if ( this.fla ) {
 1569+ js_log( "Flash:Pause: " + this.fla.isPaused() );
 1570+ if ( this.fla['pause'] ) {
 1571+ if ( ! this.fla.isPaused() ) {
 1572+ js_log( 'calling plugin pause' );
 1573+ this.fla.pause();
 1574+
 1575+ // restore volume and opacity
 1576+ this.restorePlayer();
 1577+ }
 1578+ }
 1579+ }
 1580+ }
 1581+ },
 1582+ monitor : function()
 1583+ {
 1584+ var _this = this;
 1585+ // date time
 1586+ if ( !this.dateStartTime ) {
 1587+ var d = new Date();
 1588+ this.dateStartTime = d.getTime();
 1589+
 1590+ } else {
 1591+ var d = new Date();
 1592+ if ( !this.didDateStartTimeRestore && this.preview_mode )
 1593+ this.fla.setVolume( 0 );
 1594+
 1595+ if ( ( d.getTime() - this.dateStartTime ) > 6000 && !this.didDateStartTimeRestore ) {
 1596+ this.restorePlayer();
 1597+ }
 1598+ }
 1599+
 1600+ var flash_state = this.fla.getStatus();
 1601+ // update the duration from the clip if its zero or not set:
 1602+ if ( !this.duration || this.duration == 0 ) {
 1603+ if ( this.fla.getClip() ) {
 1604+ this.duration = this.fla.getClip().fullDuration;
 1605+ js_log( 'set duration via clip value: ' + this.getDuration() );
 1606+ }
 1607+ }
 1608+ // update the duration ntp values:
 1609+ this.getDuration();
 1610+
 1611+ if ( typeof flash_state == 'undefined' ) {
 1612+ var flash_state = {
 1613+ "time" : this.fla.getTime()
 1614+ };
 1615+ // we are not getting buffered data restore volume and opacity
 1616+ this.restorePlayer();
 1617+ } else {
 1618+ // simplification of buffer state ... should move to support returning time rages like:
 1619+ // http://www.whatwg.org/specs/web-apps/current-work/#normalized-timeranges-object
 1620+ this.bufferedPercent = flash_state.bufferEnd / this.getDuration();
 1621+ }
 1622+ // set the current Time (based on timeFormat)
 1623+ if ( this.supportsURLTimeEncoding() ) {
 1624+ this.currentTime = flash_state.time;
 1625+ // js_log('set buffer: ' + flash_state.bufferEnd + ' at time: ' + flash_state.time +' of total dur: ' + this.getDuration());
 1626+ } else {
 1627+ this.currentTime = flash_state.time + this.start_offset;
 1628+ // stop buffering if greater than the duration:
 1629+ if ( flash_state.bufferEnd > this.getDuration() + 5 ) {
 1630+ // js_log('should stop buffering (does not seem to work)' + flash_state.bufferEnd + ' > dur: ' + this.getDuration() );
 1631+ this.fla.stopBuffering();
 1632+ }
 1633+ }
 1634+
 1635+ if ( this.currentTime > npt2seconds( this.start_ntp ) && !this.startedTimedPlayback ) {
 1636+ var fail = false;
 1637+ try
 1638+ {
 1639+ this.restorePlayer();
 1640+ }
 1641+ catch ( err )
 1642+ {
 1643+ js_log( 'failed to set values' );
 1644+ fail = true;
 1645+ }
 1646+ if ( !fail )
 1647+ this.startedTimedPlayback = true;
 1648+ }
 1649+
 1650+ /* to support local seeks */
 1651+ if ( this.currentTime > 1 && this.seek_time_sec != 0 && !this.supportsURLTimeEncoding() )
 1652+ {
 1653+ js_log( 'flashEmbed: _local_ Seeking to ' + this.seek_time_sec );
 1654+ this.fla.seek( this.seek_time_sec );
 1655+ this.seek_time_sec = 0;
 1656+ }
 1657+
 1658+ // checks to see if we reached the end of playback:
 1659+ if ( this.duration && this.startedTimedPlayback &&
 1660+ ( this.currentTime > ( npt2seconds( this.end_ntp ) + 2 )
 1661+ ||
 1662+ ( this.currentTime > ( npt2seconds( this.end_ntp ) - 1 )
 1663+ && this.prevTime == this.currentTime ) )
 1664+ ) {
 1665+ js_log( 'prbally reached end of stream: ' + seconds2npt( this.currentTime ) );
 1666+ this.onClipDone();
 1667+ }
 1668+
 1669+ // update the status and check timmer via universal parent monitor
 1670+ this.parent_monitor();
 1671+
 1672+
 1673+ this.prevTime = this.currentTime;
 1674+ // js_log('cur perc loaded: ' + this.fla.getPercentLoaded() +' cur time : ' + (this.currentTime - npt2seconds(this.start_ntp)) +' / ' +(npt2seconds(this.end_ntp)-npt2seconds(this.start_ntp)));
 1675+ },
 1676+ restorePlayer:function() {
 1677+ if ( !this.fla )
 1678+ this.getFLA();
 1679+ if ( this.fla ) {
 1680+ js_log( 'f:do restorePlayer' );
 1681+ this.fla.setVolume( 90 );
 1682+ $f().getPlugin( 'screen' ).css( { 'opacity':'1.0' } );
 1683+ // set the fallback date restore flag to true:
 1684+ this.didDateStartTimeRestore = true;
 1685+ }
 1686+ },
 1687+ // get the embed fla object
 1688+ getFLA : function () {
 1689+ this.fla = $f( this.pid );
 1690+ },
 1691+ stop : function() {
 1692+ js_log( 'f:flashEmbed:stop' );
 1693+ this.startedTimedPlayback = false;
 1694+ if ( this.monitorTimerId != 0 )
 1695+ {
 1696+ clearInterval( this.monitorTimerId );
 1697+ this.monitorTimerId = 0;
 1698+ }
 1699+ if ( this.fla )
 1700+ this.fla.unload();
 1701+ this.parent_stop();
 1702+ },
 1703+ onStop: function() {
 1704+ js_log( 'f:onStop' );
 1705+ // stop updates:
 1706+ if ( this.monitorTimerId != 0 )
 1707+ {
 1708+ clearInterval( this.monitorTimerId );
 1709+ this.monitorTimerId = 0;
 1710+ }
 1711+ },
 1712+ onClipDone: function() {
 1713+ js_log( 'f:flash:onClipDone' );
 1714+ if ( ! this.startedTimedPlayback ) {
 1715+ js_log( 'clip done before timed playback started .. not good. (ignoring) ' );
 1716+ // keep monitoring:
 1717+ this.monitor();
 1718+ } else {
 1719+ js_log( 'clip done and ' + this.startedTimedPlayback );
 1720+ // stop the clip if its not stopped already:
 1721+ this.stop();
 1722+ this.setStatus( "Clip Done..." );
 1723+ // run the onClip done action:
 1724+ this.parent_onClipDone();
 1725+ }
 1726+ }
 1727+};
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/flowplayerEmbed.js
___________________________________________________________________
Added: svn:mergeinfo
11728 Merged /branches/REL1_15/phase3/js2/mwEmbed/libEmbedVideo/flashEmbed.js:r51646
Added: svn:eol-style
21729 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/htmlEmbed.js
@@ -0,0 +1,195 @@
 2+/*
 3+ * used to embed HTML as a movie clip
 4+ * for use with mv_playlist SMIL additions
 5+ * (we make assumptions about this.pc (parent clip) being available)
 6+ */
 7+var pcHtmlEmbedDefaults = {
 8+ 'dur':4 // default duration of 4 seconds
 9+}
 10+
 11+var htmlEmbed = {
 12+ supports: {
 13+ 'play_head':true,
 14+ 'pause':true,
 15+ 'fullscreen':false,
 16+ 'time_display':true,
 17+ 'volume_control':true,
 18+
 19+ 'overlays':true,
 20+ 'playlist_swap_loader':true // if the object supports playlist functions
 21+ },
 22+ ready_to_play:true,
 23+ pauseTime:0,
 24+ currentTime:0,
 25+ start_offset:0,
 26+ monitorTimerId:false,
 27+ play:function() {
 28+ // call the parent
 29+ this.parent_play();
 30+
 31+ js_log( 'f:play: htmlEmbedWrapper' );
 32+ var ct = new Date();
 33+ this.clockStartTime = ct.getTime();
 34+
 35+ // Start up monitor:
 36+ this.monitor();
 37+ },
 38+ stop:function() {
 39+ this.currentTime = 0;
 40+ this.pause();
 41+ // window.clearInterval( this.monitorTimerId );
 42+ },
 43+ pause:function() {
 44+ js_log( 'f:pause: htmlEmbedWrapper' );
 45+ var ct = new Date();
 46+ this.pauseTime = this.currentTime;
 47+ js_log( 'pause time: ' + this.pauseTime );
 48+
 49+ window.clearInterval( this.monitorTimerId );
 50+ },
 51+ doSeek:function( perc ){
 52+ this.pauseTime = perc * this.getDuration();
 53+ this.play();
 54+ },
 55+ setCurrentTime:function( perc, callback ){
 56+ this.pauseTime = perc * this.getDuration();
 57+ if( callback )
 58+ callback();
 59+ },
 60+ // Monitor just needs to keep track of time
 61+ monitor:function() {
 62+ //js_log('html:monitor: '+ this.currentTime);
 63+ var ct = new Date();
 64+ this.currentTime = ( ( ct.getTime() - this.clockStartTime ) / 1000 ) + this.pauseTime;
 65+ var ct = new Date();
 66+ // js_log('mvPlayList:monitor trueTime: '+ this.currentTime);
 67+
 68+ // Once currentTime is updated call parent_monitor
 69+ this.parent_monitor();
 70+ },
 71+ // set up minimal media_element emulation:
 72+ media_element: {
 73+ autoSelectSource:function() {
 74+ return true;
 75+ },
 76+ selectedPlayer: {
 77+ library : "html"
 78+ },
 79+ selected_source: {
 80+ URLTimeEncoding:false
 81+ },
 82+ checkForTextSource:function() {
 83+ return false;
 84+ }
 85+ },
 86+ inheritEmbedPlayer:function() {
 87+ return true;
 88+ },
 89+ renderTimelineThumbnail:function( options ) {
 90+ js_log( "HTMLembed req w, height: " + options.width + ' ' + options.height );
 91+ // generate a scaled down version _that_ we can clone if nessisary
 92+ // add a not vissiable container to the body:
 93+ var do_refresh = ( typeof options['refresh'] != 'undefined' ) ? true:false;
 94+
 95+ var thumb_render_id = this.id + '_thumb_render_' + options.height;
 96+ if ( $j( '#' + thumb_render_id ).length == 0 || do_refresh ) {
 97+ // set the font scale down percentage: (kind of arbitrary)
 98+ var scale_perc = options.width / this.pc.pp.width;
 99+ js_log( 'scale_perc:' + options.width + ' / ' + $j( this ).width() + ' = ' + scale_perc );
 100+ // min scale font percent of 70 (overflow is hidden)
 101+ var font_perc = ( Math.round( scale_perc * 100 ) < 80 ) ? 80 : Math.round( scale_perc * 100 );
 102+ var thumb_class = ( typeof options['thumb_class'] != 'undefined' ) ? options['thumb_class'] : '';
 103+ $j( 'body' ).append( '<div id="' + thumb_render_id + '" style="display:none">' +
 104+ '<div class="' + thumb_class + '" ' +
 105+ 'style="width:' + options.width + 'px;height:' + options.height + 'px;" >' +
 106+ this.getThumbnailHTML( {
 107+ 'width': options.width,
 108+ 'height': options.height
 109+ } ) +
 110+ '</div>' +
 111+ '</div>'
 112+ );
 113+ // scale down the fonts:
 114+ $j( '#' + thumb_render_id + ' *' ).filter( 'span,div,p,h,h1,h2,h3,h4,h5,h6' ).css( 'font-size', font_perc + '%' )
 115+
 116+ // replace out links:
 117+ $j( '#' + thumb_render_id + ' a' ).each( function() {
 118+ $j( this ).replaceWith( "<span>" + $j( this ).html() + "</span>" );
 119+ } );
 120+
 121+ // scale images that have width or height:
 122+ $j( '#' + thumb_render_id + ' img' ).filter( '[width]' ).each( function() {
 123+ $j( this ).attr( {
 124+ 'width': Math.round( $j( this ).attr( 'width' ) * scale_perc ),
 125+ 'height': Math.round( $j( this ).attr( 'height' ) * scale_perc )
 126+ }
 127+ );
 128+ } );
 129+ }
 130+ return $j( '#' + thumb_render_id ).html();
 131+ },
 132+ // nothing to update in static html display: (return a static representation)
 133+ // @@todo render out a mini text "preview"
 134+ updateThumbTime:function( float_time ) {
 135+ return ;
 136+ },
 137+ getEmbedHTML:function() {
 138+ js_log( 'f:html:getEmbedHTML: ' + this.id );
 139+ // set up the css for our parent div:
 140+ $j( this ).css( {
 141+ 'width':this.pc.pp.width,
 142+ 'height':this.pc.pp.height,
 143+ 'overflow':"hidden"
 144+ } );
 145+ // @@todo support more smil animation layout stuff:
 146+
 147+ // wrap output in videoPlayer_ div:
 148+ $j( this ).html( '<div id="videoPlayer_' + this.id + '">' + this.getThumbnailHTML() + '</div>' );
 149+ },
 150+ getThumbnailHTML:function( opt ) {
 151+ var out = '';
 152+ if ( !opt )
 153+ opt = { };
 154+ var height = ( opt.height ) ? opt.height:this.pc.pp.height;
 155+ var width = ( opt.width ) ? opt.width: this.pc.pp.width;
 156+ js_log( '1req ' + opt.height + ' but got: ' + height );
 157+ if ( this.pc.type == 'image/jpeg' || this.pc.type == 'image/png' ) {
 158+ js_log( 'should put src: ' + this.pc.src );
 159+ out = '<img style="width:' + width + 'px;height:' + height + 'px" src="' + this.pc.src + '">';
 160+ } else {
 161+ out = this.pc.wholeText;
 162+ }
 163+ // js_log('f:getThumbnailHTML: got thumb: '+out);
 164+ return out;
 165+ },
 166+ doThumbnailHTML:function() {
 167+ js_log( 'htmlEmbed:doThumbnailHTML()' );
 168+ this.getEmbedHTML();
 169+ },
 170+ /* since its just html display get the "embed" right away */
 171+ getHTML:function() {
 172+ js_log( 'htmlEmbed::getHTML() ' + this.id );
 173+ this.getEmbedHTML();
 174+ },
 175+ getDuration:function() {
 176+ if( !this.duration ){
 177+ if( this.pc.dur ){
 178+ this.duration = this.pc.dur;
 179+ }else if( pcHtmlEmbedDefaults.dur ){
 180+ this.duration =pcHtmlEmbedDefaults.dur ;
 181+ }
 182+ }
 183+ return this.parent_getDuration();
 184+ },
 185+ updateVideoTime:function( start_ntp, end_ntp ) {
 186+ // since we don't really have timeline for html elements just take the delta and set it as the duration
 187+ this.pc.dur = npt2seconds( end_ntp ) - npt2seconds( start_ntp );
 188+ },
 189+ // gives a chance to make any nesseary external requests
 190+ // @@todo we can "start loading images" if we want
 191+ on_dom_swap:function() {
 192+ this.loading_external_data = false
 193+ this.ready_to_play = true;
 194+ return ;
 195+ }
 196+};
\ No newline at end of file
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/htmlEmbed.js
___________________________________________________________________
Added: svn:eol-style
1197 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/vlcEmbed.js
@@ -0,0 +1,297 @@
 2+/*
 3+* vlc embed based on: http://people.videolan.org/~damienf/plugin-0.8.6.html
 4+* javascript api: http://www.videolan.org/doc/play-howto/en/ch04.html
 5+* assume version > 0.8.5.1
 6+*/
 7+var vlcEmbed = {
 8+ instanceOf : 'vlcEmbed',
 9+ supports : {
 10+ 'play_head':true,
 11+ 'pause':true,
 12+ 'stop':true,
 13+ 'fullscreen':true,
 14+ 'time_display':true,
 15+ 'volume_control':true,
 16+
 17+ 'playlist_driver':true, // if the object supports playlist functions
 18+ 'overlay':false
 19+ },
 20+ // init vars:
 21+ monitorTimerId : 0,
 22+ prevState : 0,
 23+ pejs_count:0, // post embed js count
 24+
 25+ getEmbedHTML: function() {
 26+ // give VLC 150ms to initialize before we start playback
 27+ // @@todo should be able to do this as an ready event
 28+ this.pejs_count = 0;
 29+ setTimeout( 'document.getElementById(\'' + this.id + '\').postEmbedJS()', 150 );
 30+ return this.getEmbedObj();
 31+ },
 32+ getEmbedObj:function() {
 33+ var embed_code = '<object classid="clsid:9BE31822-FDAD-461B-AD51-BE1D1C159921" ' +
 34+ 'codebase="http://downloads.videolan.org/pub/videolan/vlc/latest/win32/axvlc.cab#Version=0,8,6,0" ' +
 35+ 'id="' + this.pid + '" events="True" height="' + this.height + '" width="' + this.width + '"' +
 36+ '>' +
 37+ '<param name="MRL" value="">' +
 38+ '<param name="ShowDisplay" value="True">' +
 39+ '<param name="AutoLoop" value="False">' +
 40+ '<param name="AutoPlay" value="False">' +
 41+ '<param name="Volume" value="50">' +
 42+ '<param name="StartTime" value="0">' +
 43+ '<embed pluginspage="http://www.videolan.org" type="application/x-vlc-plugin" ' +
 44+ 'progid="VideoLAN.VLCPlugin.2" name="' + this.pid + '" ' +
 45+ 'height="' + this.height + '" width="' + this.width + '" ' +
 46+ // set the style too 'just to be sure'
 47+ 'style="width:' + this.width + 'px;height:' + this.height + 'px;" ' +
 48+ '>' +
 49+ '</object>';
 50+ js_log( 'embed with: ' + embed_code );
 51+ return embed_code;
 52+ },
 53+
 54+ /*
 55+ * some java script to start vlc playback after the embed:
 56+ */
 57+ postEmbedJS: function() {
 58+ // load a pointer to the vlc into the object (this.vlc)
 59+ this.getVLC();
 60+ if ( this.vlc.log ) {
 61+ // manipulate the dom object to make sure vlc has the correct size:
 62+ this.vlc.style.width = this.width;
 63+ this.vlc.style.height = this.height;
 64+ this.vlc.playlist.items.clear();
 65+ var src = mw.absoluteUrl( this.getSrc() ) ;
 66+ // @@todo if client supports seeking no need to send seek_offset to URI
 67+ js_log( 'vlc play::' + src );
 68+ var itemId = this.vlc.playlist.add( src );
 69+ if ( itemId != -1 ) {
 70+ // play
 71+ this.vlc.playlist.playItem( itemId );
 72+ } else {
 73+ js_log( "error:cannot play at the moment !" );
 74+ }
 75+ // if controls enabled start up javascript interface and monitor:
 76+ if ( this.controls ) {
 77+ // activate the slider: scriptaculus based)
 78+ // this.activateSlider();
 79+ // start doing status updates every 1/10th of a second
 80+ }
 81+ setTimeout( '$j(\'#' + this.id + '\').get(0).monitor()', 100 );
 82+ } else {
 83+ js_log( 'postEmbedJS:vlc not ready' );
 84+ this.pejs_count++;
 85+ if ( this.pejs_count < 10 ) {
 86+ setTimeout( 'document.getElementById(\'' + this.id + '\').postEmbedJS()', 100 );
 87+ } else {
 88+ js_log( 'vlc never ready' );
 89+ }
 90+ }
 91+ },
 92+ // disable local seeking (while we don't know what we have avaliable)
 93+ doSeek : function( perc ) {
 94+ this.getVLC();
 95+ if ( this.supportsURLTimeEncoding() ) {
 96+ this.parent_doSeek( perc );
 97+ } else if ( this.vlc ) {
 98+ this.seeking = true;
 99+ js_log( "do vlc http seek to: " + perc )
 100+ if ( ( this.vlc.input.state == 3 ) && ( this.vlc.input.position != perc ) )
 101+ {
 102+ this.vlc.input.position = perc;
 103+ this.setStatus( 'seeking...' );
 104+ }
 105+ } else {
 106+ this.doPlayThenSeek( perc );
 107+ }
 108+ this.parent_monitor();
 109+ },
 110+ doPlayThenSeek:function( perc ) {
 111+ js_log( 'doPlayThenSeekHack' );
 112+ var _this = this;
 113+ this.play();
 114+ var rfsCount = 0;
 115+ var readyForSeek = function() {
 116+ _this.getVLC();
 117+ var newState = _this.vlc.input.state;
 118+ // if playing we are ready to do the
 119+ if ( newState == 3 ) {
 120+ _this.doSeek( perc );
 121+ } else {
 122+ // try to get player for 10 seconds:
 123+ if ( rfsCount < 200 ) {
 124+ setTimeout( readyForSeek, 50 );
 125+ rfsCount++;
 126+ } else {
 127+ js_log( 'error:doPlayThenSeek failed' );
 128+ }
 129+ }
 130+ }
 131+ readyForSeek();
 132+ },
 133+ playMovieAt: function ( order ) {
 134+ // @@todo add clips to playlist after (order) and then play
 135+ this.play();
 136+ },
 137+ /*
 138+ * updates the status time
 139+ */
 140+ monitor: function() {
 141+ this.getVLC();
 142+ if ( !this.vlc )
 143+ return ;
 144+ if ( this.vlc.log ) {
 145+ // js_log( 'state:' + this.vlc.input.state);
 146+ // js_log('time: ' + this.vlc.input.time);
 147+ // js_log('pos: ' + this.vlc.input.position);
 148+ if ( this.vlc.log.messages.count > 0 ) {
 149+ // there is one or more messages in the log
 150+ var iter = this.vlc.log.messages.iterator();
 151+ while ( iter.hasNext ) {
 152+ var msg = iter.next();
 153+ var msgtype = msg.type.toString();
 154+ if ( ( msg.severity == 1 ) && ( msgtype == "input" ) )
 155+ {
 156+ js_log( msg.message );
 157+ }
 158+ }
 159+ // clear the log once finished to avoid clogging
 160+ this.vlc.log.messages.clear();
 161+ }
 162+ var newState = this.vlc.input.state;
 163+ if ( this.prevState != newState ) {
 164+ if ( newState == 0 )
 165+ {
 166+ // current media has stopped
 167+ this.onStop();
 168+ }
 169+ else if ( newState == 1 )
 170+ {
 171+ // current media is opening/connecting
 172+ this.onOpen();
 173+ }
 174+ else if ( newState == 2 )
 175+ {
 176+ // current media is buffering data
 177+ this.onBuffer();
 178+ }
 179+ else if ( newState == 3 )
 180+ {
 181+ // current media is now playing
 182+ this.onPlay();
 183+ }
 184+ else if ( this.vlc.input.state == 4 )
 185+ {
 186+ // current media is now paused
 187+ this.onPause();
 188+ }
 189+ this.prevState = newState;
 190+ } else if ( newState == 3 ) {
 191+ // current media is playing
 192+ this.onPlaying();
 193+ }
 194+ }
 195+ // update the status and check timmer via universal parent monitor
 196+ this.parent_monitor();
 197+ },
 198+ /* events */
 199+ onOpen: function() {
 200+ this.setStatus( "Opening..." );
 201+ },
 202+ onBuffer: function() {
 203+ this.setStatus( "Buffering..." );
 204+ },
 205+ onPlay: function() {
 206+ this.onPlaying();
 207+ },
 208+ liveFeedRoll: 0,
 209+ onPlaying: function() {
 210+ this.seeking = false;
 211+ // for now trust the duration from url over vlc input.length
 212+ if ( !this.getDuration() && this.vlc.input.length > 0 )
 213+ {
 214+ // js_log('setting duration to ' + this.vlc.input.length /1000);
 215+ this.duration = this.vlc.input.length / 1000;
 216+ }
 217+ this.currentTime = this.vlc.input.time / 1000;
 218+ },
 219+ onPause: function() {
 220+ this.parent_pause(); // update the inteface if paused via native control
 221+ },
 222+ onStop: function() {
 223+ js_log( 'vlc:onStop:' );
 224+ if ( !this.seeking )
 225+ this.onClipDone();
 226+ },
 227+ /* js hooks/controls */
 228+ play : function() {
 229+ js_log( 'f:vlcPlay' );
 230+ this.getVLC();
 231+ // call the parent
 232+ this.parent_play();
 233+ if ( this.vlc ) {
 234+ // plugin is already being present send play call:
 235+ // clear the message log and enable error logging
 236+ if ( this.vlc.log ) {
 237+ this.vlc.log.messages.clear();
 238+ }
 239+ if ( this.vlc.playlist )
 240+ this.vlc.playlist.play();
 241+
 242+ this.monitor();
 243+ this.paused = false;
 244+ }
 245+ },
 246+ stop : function() {
 247+ if ( this.vlc ) {
 248+ if ( typeof this.vlc != 'undefined' ) {
 249+ if ( typeof this.vlc.playlist != 'undefined' ) {
 250+ // dont' stop (issues all the plugin-stop actions)
 251+ // this.vlc.playlist.stop();
 252+ if ( this.monitorTimerId != 0 )
 253+ {
 254+ clearInterval( this.monitorTimerId );
 255+ this.monitorTimerId = 0;
 256+ }
 257+ }
 258+ }
 259+ }
 260+ // this.onStop();
 261+ // do parent stop
 262+ this.parent_stop();
 263+ },
 264+ pause : function() {
 265+ this.parent_pause(); // update the interface if paused via native control
 266+ if ( this.vlc ) {
 267+ this.vlc.playlist.togglePause();
 268+ }
 269+ },
 270+ toggleMute:function() {
 271+ this.parent_toggleMute();
 272+ this.getVLC();
 273+ if ( this.vlc )
 274+ this.vlc.audio.toggleMute();
 275+ },
 276+ // @@ Support UpDateVolumen
 277+ updateVolumen:function( perc ) {
 278+ this.getVLC();
 279+ if ( this.vlc )
 280+ this.vlc.audio.volume = perc * 100;
 281+ },
 282+ // @@ Get Volumen
 283+ getVolumen:function() {
 284+ this.getVLC();
 285+ if ( this.vlc )
 286+ return this.vlc.audio.volume / 100;
 287+ },
 288+ fullscreen : function() {
 289+ if ( this.vlc ) {
 290+ if ( this.vlc.video )
 291+ this.vlc.video.toggleFullscreen();
 292+ }
 293+ },
 294+ // get the embed vlc object
 295+ getVLC : function() {
 296+ this.vlc = this.getPluginEmbed();
 297+ }
 298+};
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/vlcEmbed.js
___________________________________________________________________
Added: svn:eol-style
1299 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/nativeEmbed.js
@@ -0,0 +1,303 @@
 2+// native embed library:
 3+var nativeEmbed = {
 4+ instanceOf:'nativeEmbed',
 5+ canPlayThrough:false,
 6+ grab_try_count:0,
 7+ onlyLoadFlag:false,
 8+ onLoadedCallback : new Array(),
 9+ urlAppend:'',
 10+ prevCurrentTime: -1,
 11+ supports: {
 12+ 'play_head':true,
 13+ 'pause':true,
 14+ 'fullscreen':false,
 15+ 'time_display':true,
 16+ 'volume_control':true,
 17+
 18+ 'overlays':true,
 19+ 'playlist_swap_loader':true // if the object supports playlist functions
 20+ },
 21+ getEmbedHTML : function () {
 22+ var embed_code = this.getEmbedObj();
 23+ js_log( "embed code: " + embed_code )
 24+ setTimeout( '$j(\'#' + this.id + '\').get(0).postEmbedJS()', 150 );
 25+ return this.wrapEmebedContainer( embed_code );
 26+ },
 27+ getEmbedObj:function() {
 28+ // we want to let mv_embed handle the controls so notice the absence of control attribute
 29+ // controls=false results in controls being displayed:
 30+ // http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2008-August/016159.html
 31+ js_log( "native play url:" + this.getSrc() + ' start_offset: ' + this.start_ntp + ' end: ' + this.end_ntp );
 32+ var eb = '<video ' +
 33+ 'id="' + this.pid + '" ' +
 34+ 'style="width:' + this.width + 'px;height:' + this.height + 'px;" ' +
 35+ 'width="' + this.width + '" height="' + this.height + '" ' +
 36+ 'src="' + this.getSrc() + '" ';
 37+
 38+ /*if(!this.onlyLoadFlag)
 39+ eb+='autoplay="true" ';*/
 40+
 41+ // continue with the other attr:
 42+ eb += 'oncanplaythrough="$j(\'#' + this.id + '\').get(0).oncanplaythrough();return false;" ' +
 43+ 'onloadedmetadata="$j(\'#' + this.id + '\').get(0).onloadedmetadata();return false;" ' +
 44+ 'loadedmetadata="$j(\'#' + this.id + '\').get(0).onloadedmetadata();return false;" ' +
 45+ 'onprogress="$j(\'#' + this.id + '\').get(0).onprogress( event );return false;" ' +
 46+ 'onended="$j(\'#' + this.id + '\').get(0).onended();return false;" ' +
 47+ 'onseeking="$j(\'#' + this.id + '\').get(0).onseeking();" ' +
 48+ 'onseeked="$j(\'#' + this.id + '\').get(0).onseeked();" >' +
 49+ '</video>';
 50+ return eb;
 51+ },
 52+ // @@todo : loading progress
 53+ postEmbedJS:function() {
 54+ var _this = this;
 55+ js_log( "f:native:postEmbedJS:" );
 56+ this.getVID();
 57+ if ( typeof this.vid != 'undefined' ) {
 58+ // always load the media:
 59+ if ( this.onlyLoadFlag ) {
 60+ this.vid.load();
 61+ } else {
 62+ // issue play request
 63+ this.vid.play();
 64+ }
 65+ setTimeout( '$j(\'#' + this.id + '\').get(0).monitor()', 100 );
 66+ } else {
 67+ js_log( 'could not grab vid obj trying again:' + typeof this.vid );
 68+ this.grab_try_count++;
 69+ if ( this.grab_count == 20 ) {
 70+ js_log( ' could not get vid object after 20 tries re-run: getEmbedObj() ?' ) ;
 71+ } else {
 72+ setTimeout( function(){
 73+ _this.postEmbedJS();
 74+ }, 200 );
 75+ }
 76+ }
 77+ },
 78+ onseeking:function() {
 79+ js_log( "onseeking" );
 80+ this.seeking = true;
 81+ this.setStatus( gM( 'mwe-seeking' ) );
 82+ },
 83+ onseeked: function() {
 84+ js_log("onseeked");
 85+ this.seeking = false;
 86+ },
 87+ doSeek:function( perc ) {
 88+ js_log( 'native:seek:p: ' + perc + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec );
 89+ // @@todo check if the clip is loaded here (if so we can do a local seek)
 90+ if ( this.supportsURLTimeEncoding() ) {
 91+ // Make sure we could not do a local seek instead:
 92+ if ( perc < this.bufferedPercent && this.vid.duration && !this.didSeekJump ) {
 93+ js_log( "do local seek " + perc + ' is already buffered < ' + this.bufferedPercent );
 94+ this.doNativeSeek( perc );
 95+ } else {
 96+ // We support URLTimeEncoding call parent seek:
 97+ this.parent_doSeek( perc );
 98+ }
 99+ } else if ( this.vid && this.vid.duration ) {
 100+ // (could also check bufferedPercent > perc seek (and issue oggz_chop request or not)
 101+ this.doNativeSeek( perc );
 102+ } else {
 103+ // try to do a play then seek:
 104+ this.doPlayThenSeek( perc )
 105+ }
 106+ },
 107+ doNativeSeek:function( perc ) {
 108+ js_log( 'native::doNativeSeek::' + perc );
 109+ this.seek_time_sec = 0;
 110+ this.vid.currentTime = perc * this.duration;
 111+ this.monitor();
 112+ },
 113+ doPlayThenSeek:function( perc ) {
 114+ js_log( 'native::doPlayThenSeek::' );
 115+ var _this = this;
 116+ this.play();
 117+ var rfsCount = 0;
 118+ var readyForSeek = function() {
 119+ _this.getVID();
 120+ if ( _this.vid )
 121+ js_log( 'readyForSeek looking::' + _this.vid.duration );
 122+ // if we have duration then we are ready to do the seek
 123+ if ( _this.vid && _this.vid.duration ) {
 124+ _this.doNativeSeek( perc );
 125+ } else {
 126+ // Try to get player for 40 seconds:
 127+ // (it would be nice if the onmetadata type callbacks where fired consistently)
 128+ if ( rfsCount < 800 ) {
 129+ setTimeout( readyForSeek, 50 );
 130+ rfsCount++;
 131+ } else {
 132+ js_log( 'error:doPlayThenSeek failed' );
 133+ }
 134+ }
 135+ }
 136+ readyForSeek();
 137+ },
 138+ setCurrentTime: function( pos, callback ) {
 139+ var _this = this;
 140+ js_log( 'native:setCurrentTime::: ' + pos + ' : dur: ' + _this.getDuration() );
 141+ this.getVID();
 142+ if ( !this.vid ) {
 143+ this.load( function() {
 144+ _this.doSeekedCb( pos, callback );
 145+ } );
 146+ } else {
 147+ _this.doSeekedCb( pos, callback );
 148+ }
 149+ },
 150+ doSeekedCb : function( pos, cb ){
 151+ var _this = this;
 152+ this.getVID();
 153+ var once = function( event ) {
 154+ js_log("did seek cb");
 155+ cb();
 156+ _this.vid.removeEventListener( 'seeked', once, false );
 157+ };
 158+ // Assume we will get to add the Listener before the seek is done
 159+ _this.vid.currentTime = pos;
 160+ _this.vid.addEventListener( 'seeked', once, false );
 161+ },
 162+ monitor : function() {
 163+ this.getVID(); // make sure we have .vid obj
 164+ if ( !this.vid ) {
 165+ js_log( 'could not find video embed: ' + this.id + ' stop monitor' );
 166+ this.stopMonitor();
 167+ return false;
 168+ }
 169+ // don't update status if we are not the current clip
 170+ // (playlist leakage?) .. should move to playlist overwrite of monitor?
 171+ if ( this.pc ) {
 172+ if ( this.pc.pp.cur_clip.id != this.pc.id )
 173+ return true;
 174+ }
 175+
 176+ // Do a seek check (on seeked does not seem fire consistently)
 177+ if ( this.prevCurrentTime != -1 && this.prevCurrentTime != 0
 178+ && this.prevCurrentTime < this.currentTime && this.seeking )
 179+ this.seeking = false;
 180+
 181+ this.prevCurrentTime = this.currentTime;
 182+
 183+ // update currentTime
 184+ this.currentTime = this.vid.currentTime;
 185+
 186+ // js_log('currentTime:' + this.currentTime);
 187+ // js_log('this.currentTime: ' + this.currentTime );
 188+ // once currentTime is updated call parent_monitor
 189+ this.parent_monitor();
 190+ },
 191+
 192+ /**
 193+ * Get video src URI
 194+ */
 195+ getSrc:function() {
 196+ var src = this.parent_getSrc();
 197+ if ( this.urlAppend != '' )
 198+ return src + ( ( src.indexOf( '?' ) == -1 ) ? '?':'&' ) + this.urlAppend;
 199+ return src;
 200+ },
 201+ /*
 202+ * native callbacks for the video tag:
 203+ */
 204+ oncanplaythrough : function() {
 205+ js_log('f:oncanplaythrough');
 206+ this.getVID();
 207+ if ( ! this.paused )
 208+ this.vid.play();
 209+ },
 210+ onloadedmetadata: function() {
 211+ this.getVID();
 212+ js_log( 'f:onloadedmetadata metadata ready (update duration)' );
 213+ // update duration if not set (for now trust the getDuration more than this.vid.duration
 214+ if ( this.getDuration() == 0 && ! isNaN( this.vid.duration ) ) {
 215+ js_log( 'updaed duration via native video duration: ' + this.vid.duration )
 216+ this.duration = this.vid.duration;
 217+ }
 218+ //fire "onLoaded" flags if set
 219+ while( this.onLoadedCallback.length ){
 220+ func = this.onLoadedCallback.pop()
 221+ if( typeof func == 'function' )
 222+ func();
 223+ }
 224+ },
 225+ onprogress: function( e ) {
 226+ this.bufferedPercent = e.loaded / e.total;
 227+ // js_log("onprogress:" +e.loaded + ' / ' + (e.total) + ' = ' + this.bufferedPercent);
 228+ },
 229+ onended:function() {
 230+ var _this = this
 231+ this.getVID();
 232+ js_log( 'native:onended:' + this.vid.currentTime + ' real dur:' + this.getDuration() );
 233+ // if we just started (under 1 second played) & duration is much longer.. don't run onClipDone just yet . (bug in firefox native sending onended event early)
 234+ if ( this.vid.currentTime < 1 && this.getDuration() > 1 && this.grab_try_count < 5 ) {
 235+ js_log( 'native on ended called with time:' + this.vid.currentTime + ' of total real dur: ' + this.getDuration() + ' attempting to reload src...' );
 236+ var doRetry = function() {
 237+ _this.urlAppend = 'retry_src=' + _this.grab_try_count;
 238+ _this.doEmbedHTML();
 239+ _this.grab_try_count++;
 240+ }
 241+ setTimeout( doRetry, 100 );
 242+ } else {
 243+ js_log( 'native onClipDone done call' );
 244+ this.onClipDone();
 245+ }
 246+ },
 247+ pause : function() {
 248+ this.getVID();
 249+ this.parent_pause(); // update interface
 250+ if ( this.vid ) {
 251+ this.vid.pause();
 252+ }
 253+ // stop updates:
 254+ this.stopMonitor();
 255+ },
 256+ play:function() {
 257+ this.getVID();
 258+ this.parent_play(); // update interface
 259+ if ( this.vid ) {
 260+ this.vid.play();
 261+ // re-start the monitor:
 262+ this.monitor();
 263+ }
 264+ },
 265+ toggleMute:function() {
 266+ this.parent_toggleMute();
 267+ this.getVID();
 268+ if ( this.vid )
 269+ this.vid.muted = this.muted;
 270+ },
 271+ updateVolumen:function( perc ) {
 272+ this.getVID();
 273+ if ( this.vid )
 274+ this.vid.volume = perc;
 275+ },
 276+ getVolumen:function() {
 277+ this.getVID();
 278+ if ( this.vid )
 279+ return this.vid.volume;
 280+ },
 281+ getNativeDuration:function() {
 282+ if ( this.vid )
 283+ return this.vid.duration;
 284+ },
 285+ load:function( callback ) {
 286+ this.getVID();
 287+ if ( !this.vid ) {
 288+ // No vid loaded
 289+ js_log( 'native::load() ... doEmbed' );
 290+ this.onlyLoadFlag = true;
 291+ this.doEmbedHTML();
 292+ this.onLoadedCallback.push( callback );
 293+ } else {
 294+ // Should not happen offten
 295+ this.vid.load();
 296+ if( callback)
 297+ callback();
 298+ }
 299+ },
 300+ // get the embed vlc object
 301+ getVID : function () {
 302+ this.vid = $j( '#' + this.pid ).get( 0 );
 303+ }
 304+};
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/nativeEmbed.js
___________________________________________________________________
Added: svn:eol-style
1305 + native
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/kplayerEmbed.js
@@ -0,0 +1,140 @@
 2+var kplayerEmbed = {
 3+ instanceOf:'kplayerEmbed',
 4+ supports: {
 5+ 'play_head':true,
 6+ 'pause':true,
 7+ 'stop':true,
 8+ 'time_display':true,
 9+ 'volume_control':true,
 10+ 'overlay':false,
 11+ 'fullscreen':false
 12+ },
 13+ getEmbedHTML : function () {
 14+ var embed_code = this.getEmbedObj();
 15+ alert
 16+ var _this = this;
 17+ setTimeout(function(){
 18+ _this.postEmbedJS();
 19+ }, 50);
 20+ js_log( "return embed html" );
 21+ return this.wrapEmebedContainer( embed_code );
 22+ },
 23+ getEmbedObj:function() {
 24+ var player_path = mv_embed_path + 'libEmbedPlayer/binPlayers/kaltura-player';
 25+ return '<object width="' + this.width + '" height="' + this.height + '" '+
 26+ 'data="' + player_path + '/wrapper.swf" allowfullscreen="true" '+
 27+ 'allownetworking="all" allowscriptaccess="always" '+
 28+ 'type="application/x-shockwave-flash" '+
 29+ 'id="' + this.pid + '" name="' + this.pid + '">'+
 30+ '<param value="always" name="allowScriptAccess"/>'+
 31+ '<param value="all" name="allowNetworking"/>'+
 32+ '<param value="true" name="allowFullScreen"/>'+
 33+ '<param value="#000000" name="bgcolor"/>'+
 34+ '<param value="wrapper.swf" name="movie"/>'+
 35+ '<param value="' +
 36+ 'kdpUrl=' + player_path + '/kdp.swf' +
 37+ '&ks=dummy&partner_id=0&subp_id=0' +
 38+ '&uid=0&emptyF=onKdpEmpty&readyF=onKdpReady' +
 39+ '" ' +
 40+ 'name="flashVars"/>'+
 41+ '<param value="opaque" name="wmode"/>'+
 42+ '</object>';
 43+ },
 44+ postEmbedJS:function() {
 45+ var _this = this;
 46+ this.getKDP();
 47+ //alert( this.kdp );
 48+ if( this.kdp && this.kdp.insertMedia){
 49+ // Add KDP listeners
 50+
 51+ //this.kdp.addJsListener("doPlay","kdpDoOnPlay");
 52+ //this.kdp.addJsListener("doStop","kdpDoOnStop");
 53+ //myKdp.addJsListener("fastForward","kdpDoOnFF");
 54+
 55+ _this.bindKdpFunc( 'doPause', 'kdpPause' );
 56+ _this.bindKdpFunc( 'doPlay', 'play' );
 57+ _this.bindKdpFunc( 'playerPlayEnd', 'onClipDone' );
 58+
 59+ // KDP player likes an absolute url for the src:
 60+ var src = mw.absoluteUrl( _this.getSrc() );
 61+ js_log('play src: ' + src);
 62+ // Insert the src:
 63+ this.kdp.insertMedia("-1", src, 'true' );
 64+ this.kdp.dispatchKdpEvent('doPlay');
 65+
 66+ // Start the monitor
 67+ this.monitor();
 68+ }else{
 69+ js_log('insert media: not defiend' + typeof this.kdp.insertMedia );
 70+ setTimeout( function(){
 71+ _this.postEmbedJS();
 72+ }, 25);
 73+ }
 74+ },
 75+ /**
 76+ * bindKdpFunc
 77+ *
 78+ * @param {String} flash binding name
 79+ * @param {String} function callback name
 80+ */
 81+ bindKdpFunc:function( bName, fName ){
 82+ var cbid = fName + '_cb_' + this.id.replace(' ', '_');
 83+ eval( 'window[ \'' + cbid +'\' ] = function(){$j(\'#' + this.id + '\').get(0).'+ fName +'();}' );
 84+ this.kdp.addJsListener( bName , cbid);
 85+ },
 86+ kdpPause:function(){
 87+ this.parent_pause();
 88+ },
 89+ play:function() {
 90+ if( this.kdp && this.kdp.dispatchKdpEvent )
 91+ this.kdp.dispatchKdpEvent('doPlay');
 92+ this.parent_play();
 93+ },
 94+ pause:function() {
 95+ this.kdp.dispatchKdpEvent('doPause');
 96+ this.parent_pause();
 97+ },
 98+ doSeek:function( prec ){
 99+ var _this = this;
 100+ if( this.kdp ){
 101+ var seek_time = prec * this.getDuration();
 102+ this.kdp.dispatchKdpEvent('doSeek', seek_time);
 103+ // Kdp is missing seek done callback
 104+ setTimeout(function(){
 105+ _this.seeking= false;
 106+ },500);
 107+ }
 108+ this.monitor();
 109+ },
 110+ updateVolumen:function( perc ) {
 111+ if( this.kdp && this.kdp.dispatchKdpEvent )
 112+ this.kdp.dispatchKdpEvent('volumeChange', perc);
 113+ },
 114+ monitor:function() {
 115+ if( this.kdp && this.kdp.getMediaSeekTime ){
 116+ this.currentTime = this.kdp.getMediaSeekTime();
 117+ }
 118+ this.parent_monitor();
 119+ },
 120+ // get the embed fla object
 121+ getKDP: function () {
 122+ this.kdp = document.getElementById( this.pid );
 123+ }
 124+}
 125+
 126+function kdpDoOnPause( player ){
 127+ var cat = player
 128+ debugger;
 129+}
 130+
 131+function onKdpReady( playerId ) {
 132+ js_log( "IN THEORY PLAYER IS READY:" + playerId);
 133+ /*
 134+ window.myKdp=get(playerId);
 135+ get("Player_State").innerHTML="<br>&nbsp; READY (Id=" + playerId + ")";
 136+ get("nowPlaying").innerHTML=(myKdp.evaluate('{entryId}'));
 137+ getDuration();
 138+ attachKdpEvents();
 139+ addKdpListners();
 140+ */
 141+}
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/kplayerEmbed.js
___________________________________________________________________
Added: svn:eol-style
1142 + native
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer
___________________________________________________________________
Added: svn:mergeinfo
2143 Merged /branches/REL1_15/phase3/js2/mwEmbed/libEmbedVideo:r51646
3144 Merged /branches/sqlite/js2/mwEmbed/libEmbedVideo:r58211-58321
Index: branches/js2-work/phase3/js2/mwEmbed/libSequencer/mvPlayList.js
@@ -37,7 +37,7 @@
3838 var defaultMetaDataProvider = wgServer + wgScript + '?title=Special:MvExportStream&feed_format=roe&stream_name=';
3939 }
4040 /*
41 - * The playlist Object implements ~most~ of embedVideo but we don't inherit (other than to use the control builder)
 41+ * The playlist Object implements ~most~ of embedPlayer but we don't inherit (other than to use the control builder)
4242 * because pretty much every function has to be changed for the playlist context
4343 */
4444 var mvPlayList = function( element ) {
@@ -131,10 +131,10 @@
132132 // get and load the html:
133133 this.getHTML();
134134 },
135 - // run inheritEmbedObj on every clip (we have changed the playback method)
136 - inheritEmbedObj:function() {
 135+ // run inheritEmbedPlayer on every clip (we have changed the playback method)
 136+ inheritEmbedPlayer:function() {
137137 $j.each( this.tracks, function( i, track ) {
138 - track.inheritEmbedObj();
 138+ track.inheritEmbedPlayer();
139139 } );
140140 },
141141 doOptionsHTML:function() {
@@ -295,7 +295,7 @@
296296 // js_log("return dur: " + this.pl_duration);
297297 return this.pl_duration;
298298 },
299 - getTimeReq:function() {
 299+ getTimeRange:function() {
300300 // playlist does not really support time request atm ( in theory in the future we could embed playlists with temporal urls)
301301 return '0:0:0/' + seconds2npt( this.getDuration() );
302302 },
@@ -1298,7 +1298,7 @@
12991299 ve.setAttribute( i, vid_init[i] );
13001300 }
13011301 }
1302 - var videoInterface = new embedVideo( ve );
 1302+ var videoInterface = new embedPlayer( ve );
13031303 // inherit the videoInterface
13041304 for ( method in videoInterface ) {
13051305 if ( method != 'style' ) {
@@ -2268,9 +2268,9 @@
22692269 getClipCount:function() {
22702270 return this.clips.length;
22712271 },
2272 - inheritEmbedObj: function() {
 2272+ inheritEmbedPlayer: function() {
22732273 $j.each( this.clips, function( i, clip ) {
2274 - clip.embed.inheritEmbedObj();
 2274+ clip.embed.inheritEmbedPlayer();
22752275 } );
22762276 }
22772277 };
Index: branches/js2-work/phase3/js2/mwEmbed/libClipEdit/mvClipEdit.js
@@ -1,4 +1,4 @@
2 -/*
 2+k/*
33 mvClipEdit hanndles the edit interfaces for images and video
44 */
55 // set gMsg object:
@@ -582,7 +582,7 @@
583583 ebvid.stop();
584584 ebvid.updateVideoTime( start_time, end_time );
585585 js_log( 'update thumb: ' + start_time );
586 - ebvid.updateThumbTimeNTP( start_time );
 586+ ebvid.updateThumbTimeNPT( start_time );
587587 }
588588 },
589589

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r59439Fixes for remoteSearchDriver.js and related. Untested, probably doesn't work....tstarling03:10, 26 November 2009

Status & tagging log