Index: branches/js2-work/phase3/js2/remoteMwEmbed.js |
— | — | @@ -69,7 +69,7 @@ |
70 | 70 | } |
71 | 71 | } |
72 | 72 | 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' ]; |
74 | 74 | // Quick sniff use java if IE and native if firefox |
75 | 75 | // ( other browsers will run detect and get on-demand ) |
76 | 76 | if (navigator.userAgent.indexOf("MSIE") != -1) |
— | — | @@ -79,7 +79,7 @@ |
80 | 80 | jsSetVideo.push( 'nativeEmbed' ); |
81 | 81 | |
82 | 82 | mwr_load_mv_embed( jsSetVideo, function() { |
83 | | - mvJsLoader.embedVideoCheck( function() { |
| 83 | + mvJsLoader.embedPlayerCheck( function() { |
84 | 84 | // Do utility rewrite of OggHandler content: |
85 | 85 | rewrite_for_OggHandler( vidIdList ); |
86 | 86 | } ); |
Index: branches/js2-work/phase3/js2/mwEmbed/php/languages/mwEmbed.i18n.php |
— | — | @@ -342,7 +342,7 @@ |
343 | 343 | 'mwe-credit-title' => 'Title: $1', |
344 | 344 | |
345 | 345 | /* |
346 | | - * js file: /libEmbedVideo/embedVideo.js |
| 346 | + * js file: /libEmbedPlayer/embedPlayer.js |
347 | 347 | */ |
348 | 348 | 'mwe-loading_plugin' => 'loading plugin ...', |
349 | 349 | 'mwe-select_playback' => 'Set playback preference', |
Index: branches/js2-work/phase3/js2/mwEmbed/skins/ctrlBuilder.js |
— | — | @@ -3,12 +3,12 @@ |
4 | 4 | _global['dismissNativeWarn'] = false; |
5 | 5 | |
6 | 6 | /** |
7 | | -* Msg text is inherited from embedVideo |
| 7 | +* Msg text is inherited from embedPlayer |
8 | 8 | */ |
9 | 9 | |
10 | 10 | /** |
11 | 11 | * ctrlBuilder object |
12 | | -* @param the embedVideo element we are targeting |
| 12 | +* @param the embedPlayer element we are targeting |
13 | 13 | */ |
14 | 14 | var ctrlBuilder = function( embedObj, options ) { |
15 | 15 | return this.init( embedObj, options ); |
— | — | @@ -198,7 +198,7 @@ |
199 | 199 | $j( id + ' .play-btn-large' ).fadeOut( 'fast' ); |
200 | 200 | // If playlist always start at 0 |
201 | 201 | embedObj.start_time_sec = ( embedObj.instanceOf == 'mvPlayList' ) ? 0: |
202 | | - npt2seconds( embedObj.getTimeReq().split( '/' )[0] ); |
| 202 | + npt2seconds( embedObj.getTimeRange().split( '/' )[0] ); |
203 | 203 | }, |
204 | 204 | slide: function( event, ui ) { |
205 | 205 | var perc = ui.value / 1000; |
— | — | @@ -494,7 +494,7 @@ |
495 | 495 | 'time_display': { |
496 | 496 | 'w':90, |
497 | 497 | '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>'; |
499 | 499 | } |
500 | 500 | }, |
501 | 501 | /* |
Index: branches/js2-work/phase3/js2/mwEmbed/mv_embed.js |
— | — | @@ -132,15 +132,15 @@ |
133 | 133 | |
134 | 134 | "mvClipEdit" : "libClipEdit/mvClipEdit.js", |
135 | 135 | |
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", |
145 | 145 | |
146 | 146 | "mvPlayList" : "libSequencer/mvPlayList.js", |
147 | 147 | "mvSequencer" : "libSequencer/mvSequencer.js", |
— | — | @@ -1167,9 +1167,9 @@ |
1168 | 1168 | } |
1169 | 1169 | } ); |
1170 | 1170 | }, |
1171 | | - embedVideoCheck:function( callback ) { |
| 1171 | + embedPlayerCheck:function( callback ) { |
1172 | 1172 | var _this = this; |
1173 | | - js_log( 'embedVideoCheck:' ); |
| 1173 | + js_log( 'embedPlayerCheck:' ); |
1174 | 1174 | // Make sure we have jQuery |
1175 | 1175 | _this.jQueryCheck( function() { |
1176 | 1176 | // set class videonojs to loading |
— | — | @@ -1178,7 +1178,7 @@ |
1179 | 1179 | var depReq = [ |
1180 | 1180 | [ |
1181 | 1181 | '$j.ui', |
1182 | | - 'embedVideo', |
| 1182 | + 'embedPlayer', |
1183 | 1183 | 'ctrlBuilder', |
1184 | 1184 | '$j.cookie' |
1185 | 1185 | ], |
— | — | @@ -1283,11 +1283,12 @@ |
1284 | 1284 | } |
1285 | 1285 | } |
1286 | 1286 | // 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: |
1290 | 1291 | mvJsLoader.runQueuedFunctions(); |
1291 | | - } ); |
| 1292 | + }); |
1292 | 1293 | } ); |
1293 | 1294 | } else { |
1294 | 1295 | mvJsLoader.runQueuedFunctions(); |
— | — | @@ -1314,7 +1315,7 @@ |
1315 | 1316 | function rewrite_by_id( vid_id, ready_callback ) { |
1316 | 1317 | js_log( 'f:rewrite_by_id: ' + vid_id ); |
1317 | 1318 | // Force a re-check of the DOM for playlist or video elements: |
1318 | | - mvJsLoader.embedVideoCheck( function() { |
| 1319 | + mvJsLoader.eembedPlayerheck( function() { |
1319 | 1320 | mv_video_embed( ready_callback, vid_id ); |
1320 | 1321 | } ); |
1321 | 1322 | } |
— | — | @@ -1456,7 +1457,7 @@ |
1457 | 1458 | loadExternalCss( mv_embed_path + 'skins/' + mw.conf['skin_name'] + '/mv_sequence.css' ); |
1458 | 1459 | // Make sure we have the required mv_embed libs (they are not loaded when no video |
1459 | 1460 | // element is on the page) |
1460 | | - mvJsLoader.embedVideoCheck( function() { |
| 1461 | + mvJsLoader.eembedPlayerheck( function() { |
1461 | 1462 | // Load the playlist object and then the jQuery UI stuff: |
1462 | 1463 | mvJsLoader.doLoadDepMode( [ |
1463 | 1464 | [ |
Index: branches/js2-work/phase3/js2/mwEmbed/libTimedText/mvTextInterface.js |
— | — | @@ -54,7 +54,7 @@ |
55 | 55 | _this.getParseTimedText_rowReady(); |
56 | 56 | } |
57 | 57 | } else { |
58 | | - if ( this.pe.media_element.checkForTextSource() ) { |
| 58 | + if ( this.pe.media_element.textSourceExists() ) { |
59 | 59 | _this.getParseTimedText_rowReady(); |
60 | 60 | } else { |
61 | 61 | js_log( 'no roe data or timed text sources' ); |
Index: branches/js2-work/phase3/js2/mwEmbed/libAddMedia/remoteSearchDriver.js |
— | — | @@ -1005,7 +1005,7 @@ |
1006 | 1006 | break; |
1007 | 1007 | } |
1008 | 1008 | } |
1009 | | - } |
| 1009 | + }, |
1010 | 1010 | |
1011 | 1011 | /** |
1012 | 1012 | * checkForCopyURLPermission: |
— | — | @@ -1695,15 +1695,15 @@ |
1696 | 1696 | // normally this meta should be provided in the search result |
1697 | 1697 | // (but archive.org has another query for more media meta) |
1698 | 1698 | resource.pSobj.addResourceInfoCallback( resource, function() { |
1699 | | - // Make sure we have the embedVideo libs: |
| 1699 | + // Make sure we have the embedPlayer libs: |
1700 | 1700 | var runFlag = false; |
1701 | | - mvJsLoader.embedVideoCheck( function() { |
| 1701 | + mvJsLoader.embedPlayerCheck( function() { |
1702 | 1702 | // Strange concurrency issue with callbacks |
1703 | 1703 | // @@todo try and figure out why this callback is fired twice |
1704 | 1704 | if ( !runFlag ) { |
1705 | 1705 | runFlag = true; |
1706 | 1706 | } else { |
1707 | | - js_log( 'Error: embedVideoCheck run twice' ); |
| 1707 | + js_log( 'Error: embedPlayerCheck run twice' ); |
1708 | 1708 | return false; |
1709 | 1709 | } |
1710 | 1710 | var embedHtml = resource.pSobj.getEmbedHTML( resource, |
— | — | @@ -2341,9 +2341,7 @@ |
2342 | 2342 | resource.mime.indexOf( 'video' ) != -1 || |
2343 | 2343 | resource.mime.indexOf( '/ogg' ) != -1 ) |
2344 | 2344 | { |
2345 | | - mvJsLoader.embedVideoCheck( function() { |
2346 | | - mv_video_embed(); |
2347 | | - } ); |
| 2345 | + mvJsLoader.embedPlayerCheck(); |
2348 | 2346 | } |
2349 | 2347 | } |
2350 | 2348 | |
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 |
1 | 67 | + 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 = '<script type="text/javascript" ' + |
| 2040 | + 'src="' + mv_embed_path + 'mv_embed.js"></script>' + |
| 2041 | + '<video '; |
| 2042 | + if ( this.roe ) { |
| 2043 | + embed_code_html += 'roe="' + escape( this.roe ) + '" '; |
| 2044 | + } else { |
| 2045 | + embed_code_html += 'src="' + this.src + '" ' + |
| 2046 | + 'poster="' + escape( embed_thumb_url ) + '" '; |
| 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="' + escape( this.wikiTitleKey ) + '"'; |
| 2054 | + } |
| 2055 | + |
| 2056 | + // close the video tag |
| 2057 | + embed_code_html += '></video>'; |
| 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 |
1 | 3040 | Merged /branches/REL1_15/phase3/js2/mwEmbed/libEmbedVideo/embedVideo.js:r51646 |
2 | 3041 | Merged /branches/sqlite/js2/mwEmbed/libEmbedVideo/embedVideo.js:r58211-58321 |
Added: svn:eol-style |
3 | 3042 | + 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 |
1 | 19 | + 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 |
1 | 676 | + 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 |
2 | 677 | + 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 |
1 | 17 | + 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 |
2 | 18 | + 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 |
3 | 19 | + 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 |
4 | 20 | + 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 |
5 | 21 | + 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 |
1 | 54 | + 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 |
2 | 55 | + 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 |
1 | 1522 | + 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 |
2 | 1523 | + 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 |
3 | 1524 | + 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 |
1 | 31 | + 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 |
1 | 74 | + 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 |
1 | 51 | + 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 |
1 | 118 | + 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 |
1 | 54 | + 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 |
1 | 94 | + 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 |
1 | 77 | + 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 |
1 | 72 | + 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 |
1 | 225 | + 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 |
1 | 64 | + 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 |
1 | 342 | + 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 |
1 | 75 | + 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 |
1 | 144 | + 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 |
1 | 58 | + 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 |
1 | 280 | + 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 |
1 | 89 | + 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 |
1 | 138 | + 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 |
1 | 120 | + 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 |
1 | 138 | + 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 |
1 | 83 | + 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 |
1 | 138 | + 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 |
1 | 124 | + 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 |
1 | 132 | + 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 |
1 | 124 | + 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 |
1 | 111 | + 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 |
1 | 108 | + 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 |
1 | 5 | + 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 |
1 | 339 | + 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 |
2 | 340 | + 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 |
1 | 19 | + 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 |
1 | 203 | + 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 |
1 | 3 | + 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 |
2 | 4 | + 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 |
3 | 5 | + application/octet-stream |
Added: svn:executable |
4 | 6 | + * |
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 |
1 | 13 | + 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 |
2 | 14 | + application/octet-stream |
Added: svn:executable |
3 | 15 | + * |
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/binPlayers |
___________________________________________________________________ |
Added: svn:mergeinfo |
4 | 16 | 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 |
1 | 179 | + 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 |
1 | 1728 | Merged /branches/REL1_15/phase3/js2/mwEmbed/libEmbedVideo/flashEmbed.js:r51646 |
Added: svn:eol-style |
2 | 1729 | + 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 |
1 | 197 | + 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 |
1 | 299 | + 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 |
1 | 305 | + 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> 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 |
1 | 142 | + native |
Property changes on: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer |
___________________________________________________________________ |
Added: svn:mergeinfo |
2 | 143 | Merged /branches/REL1_15/phase3/js2/mwEmbed/libEmbedVideo:r51646 |
3 | 144 | Merged /branches/sqlite/js2/mwEmbed/libEmbedVideo:r58211-58321 |
Index: branches/js2-work/phase3/js2/mwEmbed/libSequencer/mvPlayList.js |
— | — | @@ -37,7 +37,7 @@ |
38 | 38 | var defaultMetaDataProvider = wgServer + wgScript + '?title=Special:MvExportStream&feed_format=roe&stream_name='; |
39 | 39 | } |
40 | 40 | /* |
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) |
42 | 42 | * because pretty much every function has to be changed for the playlist context |
43 | 43 | */ |
44 | 44 | var mvPlayList = function( element ) { |
— | — | @@ -131,10 +131,10 @@ |
132 | 132 | // get and load the html: |
133 | 133 | this.getHTML(); |
134 | 134 | }, |
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() { |
137 | 137 | $j.each( this.tracks, function( i, track ) { |
138 | | - track.inheritEmbedObj(); |
| 138 | + track.inheritEmbedPlayer(); |
139 | 139 | } ); |
140 | 140 | }, |
141 | 141 | doOptionsHTML:function() { |
— | — | @@ -295,7 +295,7 @@ |
296 | 296 | // js_log("return dur: " + this.pl_duration); |
297 | 297 | return this.pl_duration; |
298 | 298 | }, |
299 | | - getTimeReq:function() { |
| 299 | + getTimeRange:function() { |
300 | 300 | // playlist does not really support time request atm ( in theory in the future we could embed playlists with temporal urls) |
301 | 301 | return '0:0:0/' + seconds2npt( this.getDuration() ); |
302 | 302 | }, |
— | — | @@ -1298,7 +1298,7 @@ |
1299 | 1299 | ve.setAttribute( i, vid_init[i] ); |
1300 | 1300 | } |
1301 | 1301 | } |
1302 | | - var videoInterface = new embedVideo( ve ); |
| 1302 | + var videoInterface = new embedPlayer( ve ); |
1303 | 1303 | // inherit the videoInterface |
1304 | 1304 | for ( method in videoInterface ) { |
1305 | 1305 | if ( method != 'style' ) { |
— | — | @@ -2268,9 +2268,9 @@ |
2269 | 2269 | getClipCount:function() { |
2270 | 2270 | return this.clips.length; |
2271 | 2271 | }, |
2272 | | - inheritEmbedObj: function() { |
| 2272 | + inheritEmbedPlayer: function() { |
2273 | 2273 | $j.each( this.clips, function( i, clip ) { |
2274 | | - clip.embed.inheritEmbedObj(); |
| 2274 | + clip.embed.inheritEmbedPlayer(); |
2275 | 2275 | } ); |
2276 | 2276 | } |
2277 | 2277 | }; |
Index: branches/js2-work/phase3/js2/mwEmbed/libClipEdit/mvClipEdit.js |
— | — | @@ -1,4 +1,4 @@ |
2 | | -/* |
| 2 | +k/* |
3 | 3 | mvClipEdit hanndles the edit interfaces for images and video |
4 | 4 | */ |
5 | 5 | // set gMsg object: |
— | — | @@ -582,7 +582,7 @@ |
583 | 583 | ebvid.stop(); |
584 | 584 | ebvid.updateVideoTime( start_time, end_time ); |
585 | 585 | js_log( 'update thumb: ' + start_time ); |
586 | | - ebvid.updateThumbTimeNTP( start_time ); |
| 586 | + ebvid.updateThumbTimeNPT( start_time ); |
587 | 587 | } |
588 | 588 | }, |
589 | 589 | |