Index: branches/js2-work/phase3/js2/js2stopgap.js |
— | — | @@ -9510,4 +9510,4 @@ |
9511 | 9511 | } |
9512 | 9512 | |
9513 | 9513 | // Define a dummy mw.load() function |
9514 | | -mw.load = function ( callback ) { callback() } |
| 9514 | +mw.load = function ( loadRequest, callback ) { callback() } |
Index: branches/js2-work/phase3/js2/mwEmbed/php/languages/mwEmbed.i18n.php |
— | — | @@ -388,7 +388,7 @@ |
389 | 389 | '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 />', |
390 | 390 | '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>', |
391 | 391 | 'mwe-do_not_warn_again' => 'Dismiss for now.', |
392 | | - 'mwe-playerselect' => 'Players', |
| 392 | + 'mwe-playerSelect' => 'Players', |
393 | 393 | 'mwe-read_before_embed' => '<a href="http://mediawiki.org/wiki/Security_Notes_on_Remote_Embedding" target="_new">Read this</a> before embedding.', |
394 | 394 | 'mwe-embed_site_or_blog' => 'Embed on a page', |
395 | 395 | 'mwe-related_videos' => 'Related videos', |
Index: branches/js2-work/phase3/js2/mwEmbed/php/jsAutoloadLocalClasses.php |
— | — | @@ -28,6 +28,7 @@ |
29 | 29 | global $wgJSAutoloadLocalClasses, $wgMwEmbedDirectory; |
30 | 30 | if ( !isset( $jvar[1] ) ) |
31 | 31 | return false; |
| 32 | + |
32 | 33 | $jClassSet = FormatJson::decode( '{' . $jvar[1] . '}', true ); |
33 | 34 | foreach ( $jClassSet as $jClass => $jPath ) { |
34 | 35 | // Strip $ from jClass (as they are stripped on URL request parameter input) |
Index: branches/js2-work/phase3/js2/mwEmbed/skins/ctrlBuilder.js |
— | — | @@ -220,9 +220,8 @@ |
221 | 221 | if ( embedObj.userSlide ) { |
222 | 222 | embedObj.userSlide = false; |
223 | 223 | embedObj.seeking = true; |
224 | | - // stop the monitor timer (if we can) |
225 | | - if ( embedObj.stopMonitor ) |
226 | | - embedObj.stopMonitor(); |
| 224 | + // Stop the monitor timer (if we can) |
| 225 | + embedObj.stopMonitor(); |
227 | 226 | |
228 | 227 | var perc = ui.value / 1000; |
229 | 228 | // set seek time (in case we have to do a url seek) |
— | — | @@ -247,7 +246,7 @@ |
248 | 247 | // videoOptions ... @@todo should be merged with something more like kskin.js: |
249 | 248 | $opt.find( '.vo_selection' ).click( function() { |
250 | 249 | embedObj.displayHTML(); |
251 | | - embedObj.showPlayerselect( $target.find( '.videoOptionsComplete' ) ); |
| 250 | + embedObj.showPlayerSelect( $target.find( '.videoOptionsComplete' ) ); |
252 | 251 | $opt.hide(); |
253 | 252 | return false; |
254 | 253 | } ); |
Index: branches/js2-work/phase3/js2/mwEmbed/skins/kskin/kskin.js |
— | — | @@ -22,7 +22,7 @@ |
23 | 23 | |
24 | 24 | // Menu items for the kskin: |
25 | 25 | menu_items:[ |
26 | | - 'playerselect', |
| 26 | + 'playerSelect', |
27 | 27 | 'download', |
28 | 28 | 'share', |
29 | 29 | 'credits', |
Index: branches/js2-work/phase3/js2/mwEmbed/mwEmbed.js |
— | — | @@ -85,22 +85,22 @@ |
86 | 86 | |
87 | 87 | // What tags will be re-written to video player by default |
88 | 88 | // set to empty string or null to avoid automatic rewrites |
89 | | - 'rewriteTags' : 'video,audio,playlist', |
| 89 | + 'rewritePlayerTags' : 'video,audio,playlist', |
90 | 90 | |
91 | 91 | /** |
92 | 92 | * If jQuery / mwEmbed should always be loaded. |
93 | 93 | * |
94 | 94 | * mwEmbedSetup ignores this flag and is run if: |
95 | 95 | * If your js calls mw.addOnloadHook ( callback_function ) |
96 | | - * If your page includes any tags set in config.rewriteTags |
| 96 | + * If your page includes any tags set in config.rewritePlayerTags |
97 | 97 | * |
98 | | - * This flag increases page performace on pages that do not use mwEmbed |
| 98 | + * This flag increases page performance on pages that do not use mwEmbed |
99 | 99 | * and don't already load jQuery |
100 | 100 | * |
101 | 101 | * For examle when including the mwEmbed.js in your blog template |
102 | 102 | * mwEmbed will only load extra js on blog posts that include the video tag. |
103 | 103 | * |
104 | | - * NOTE: Future articture will probably do away with this flag and refactor it into |
| 104 | + * NOTE: Future architecture will probably do away with this flag and refactor it into |
105 | 105 | * a smaller "remotePageMwEmbed.js" script similar to remoteMwEmbed.js in the js2 folder |
106 | 106 | */ |
107 | 107 | 'alwaysSetupMwEmbed' : false, |
— | — | @@ -112,7 +112,10 @@ |
113 | 113 | 'k_attribution' : true, |
114 | 114 | |
115 | 115 | // The path of mvEmbed in mediaWiki folder |
116 | | - 'mediaWikiPath' : 'js2/mwEmbed/' |
| 116 | + 'mediaWikiPath' : 'js2/mwEmbed/', |
| 117 | + |
| 118 | + //If we are in debug mode ( results in fresh debugg javascript includes ) |
| 119 | + 'debug' : false |
117 | 120 | } |
118 | 121 | |
119 | 122 | |
— | — | @@ -915,6 +918,7 @@ |
916 | 919 | // Make sure the class is not already defined: |
917 | 920 | if ( $.isset( className ) ){ |
918 | 921 | js_log( 'Class ( ' + className + ' ) already defined ' ); |
| 922 | + callback(); |
919 | 923 | return ; |
920 | 924 | } |
921 | 925 | |
— | — | @@ -959,7 +963,7 @@ |
960 | 964 | * class name file path pairs. |
961 | 965 | * |
962 | 966 | * classSet must be strict JSON to allow the |
963 | | - * scriptLoader to parse the file paths. |
| 967 | + * php scriptLoader to parse the file paths. |
964 | 968 | */ |
965 | 969 | addClassFilePaths: function( classSet ){ |
966 | 970 | for( var i in classSet ){ |
— | — | @@ -1074,12 +1078,13 @@ |
1075 | 1079 | // Flag to ensure setup is only run once: |
1076 | 1080 | var mwSetupFlag = false; |
1077 | 1081 | |
1078 | | - $.setupMwEmbed = function ( ) { |
1079 | | - |
| 1082 | + $.setupMwEmbed = function ( ) { |
1080 | 1083 | // Only run the setup once: |
1081 | 1084 | if( mwSetupFlag ) |
1082 | 1085 | return ; |
1083 | 1086 | mwSetupFlag = true; |
| 1087 | + |
| 1088 | + js_log( 'mw:setupMwEmbed' ); |
1084 | 1089 | |
1085 | 1090 | // Make sure jQuery is loaded: |
1086 | 1091 | $.load( 'window.jQuery', function(){ |
— | — | @@ -1105,9 +1110,12 @@ |
1106 | 1111 | mwDojQueryBindings(); |
1107 | 1112 | |
1108 | 1113 | // Check for tag-rewrites ( sometimes checked twice but ensures fresh dom check ) |
1109 | | - if( $.documentHasRewriteTags() ){ |
| 1114 | + if( $.documentHasPlayerTags() ){ |
1110 | 1115 | // Load the embedPlayer module ( then run queued hooks ) |
1111 | | - ms.load( 'embedPlayer', function ( ) { |
| 1116 | + mw.load( 'player', function ( ) { |
| 1117 | + // Rewrite the rewritePlayerTags with the |
| 1118 | + $j( $.getConfig( 'rewritePlayerTags' ) ).embedPlayer() |
| 1119 | + // Run mw hooks: |
1112 | 1120 | mw.runLoadHooks(); |
1113 | 1121 | } ); |
1114 | 1122 | }else{ |
— | — | @@ -1116,8 +1124,10 @@ |
1117 | 1125 | } |
1118 | 1126 | } ); |
1119 | 1127 | } |
| 1128 | + |
1120 | 1129 | //Flag to register the domReady has been called |
1121 | 1130 | var mwDomReadyFlag = false; |
| 1131 | + |
1122 | 1132 | /** |
1123 | 1133 | * This will get called when the DOM is ready |
1124 | 1134 | * Will check configuration and issue a mw.setupMwEmbed call if needed |
— | — | @@ -1136,7 +1146,7 @@ |
1137 | 1147 | } |
1138 | 1148 | |
1139 | 1149 | // Check for rewrite tags: |
1140 | | - if ( $.documentHasRewriteTags() ) { |
| 1150 | + if ( $.documentHasPlayerTags() ) { |
1141 | 1151 | $.setupMwEmbed(); |
1142 | 1152 | return ; |
1143 | 1153 | } |
— | — | @@ -1165,29 +1175,37 @@ |
1166 | 1176 | } |
1167 | 1177 | |
1168 | 1178 | /** |
1169 | | - * Check the current DOM for any tags in "rewriteTags" |
| 1179 | + * Check the current DOM for any tags in "rewritePlayerTags" |
1170 | 1180 | */ |
1171 | | - $.documentHasRewriteTags = function(){ |
1172 | | - var tags = $.getRewriteTags(); |
1173 | | - return ( tags && tags.length ); |
| 1181 | + $.documentHasPlayerTags = function(){ |
| 1182 | + var tagElm = $.getPlayerTagElements( true ); |
| 1183 | + if( tagElm && tagElm.length ) |
| 1184 | + return true; |
| 1185 | + return false; |
1174 | 1186 | } |
1175 | | - $.getRewriteTags = function(){ |
1176 | | - var tagString = $.getConfig( 'rewriteTags' ); |
| 1187 | + /** |
| 1188 | + * Gets page elements that match the rewritePlayerTags config |
| 1189 | + * |
| 1190 | + * @param {Boolean} getOne Flag to retive only one tag ( faster for simple has tag checks ) |
| 1191 | + */ |
| 1192 | + $.getPlayerTagElements = function( getOne ){ |
| 1193 | + var tagString = $.getConfig( 'rewritePlayerTags' ); |
1177 | 1194 | if( ! tagString || tagString == '' ) |
1178 | 1195 | return false; |
1179 | 1196 | |
1180 | 1197 | // Tags should be separated by "," |
1181 | 1198 | var tags = tagString.split(','); |
1182 | | - |
| 1199 | + var tagsInDOM = [ ]; |
1183 | 1200 | // Check for tags: |
1184 | 1201 | for( var i in tags ){ |
1185 | | - var tagsInDOM = document.getElementsByTagName( tags[ i ] ); |
1186 | | - // If tags found return true |
1187 | | - if( tagsInDOM.length > 0 ){ |
1188 | | - return true; |
| 1202 | + var tagElements = document.getElementsByTagName( tags[ i ] ); |
| 1203 | + for(var j = 0; j < tagElements.length; j++ ){ |
| 1204 | + tagsInDOM.push( tagElements[ j ] ); |
| 1205 | + if( getOne ) |
| 1206 | + return tagsInDOM; |
1189 | 1207 | } |
1190 | | - } |
1191 | | - return false; |
| 1208 | + } |
| 1209 | + return tagsInDOM; |
1192 | 1210 | } |
1193 | 1211 | |
1194 | 1212 | /** |
— | — | @@ -1199,16 +1217,22 @@ |
1200 | 1218 | * @param {Function} callback Function to call once script is loaded |
1201 | 1219 | */ |
1202 | 1220 | $.getScript = function( url, callback ){ |
| 1221 | + // Add on the request paramaters to the url: |
| 1222 | + url += ( url.indexOf( '?' ) === -1 )? '?' : '&'; |
1203 | 1223 | |
| 1224 | + // Get url Param also updates the "debug" var |
| 1225 | + url += $.getUrlParam(); |
| 1226 | + |
1204 | 1227 | js_log( 'mw.getScript: ' + url ); |
1205 | 1228 | |
1206 | | - // If jQuery is available just use getScript |
1207 | | - if( $.isset( 'window.jQuery' ) ) { |
| 1229 | + // If jQuery is available and debug is off get the scirpt j |
| 1230 | + if( $.isset( 'window.jQuery' ) && $.getConfig( 'debug' ) === false ) { |
1208 | 1231 | $j.getScript( url, callback ); |
1209 | 1232 | return ; |
1210 | 1233 | } |
1211 | 1234 | |
1212 | | - // No jQuery load and bind manually: ( copied from jQuery ajax function ) |
| 1235 | + // No jQuery or we want a script instead of XHR eval for debugging |
| 1236 | + // Load and bind manually: ( copied from jQuery ajax function ) |
1213 | 1237 | var head = document.getElementsByTagName("head")[0]; |
1214 | 1238 | var script = document.createElement("script"); |
1215 | 1239 | script.setAttribute( 'src', url ); |
— | — | @@ -1257,7 +1281,7 @@ |
1258 | 1282 | // Check for scriptLoader include of mwEmbed: |
1259 | 1283 | if ( src.indexOf( 'mwScriptLoader.php' ) !== -1 ) { |
1260 | 1284 | // Script loader is in the root of MediaWiki, Include the default mwEmbed extension path: |
1261 | | - mwpath = src.substr( 0, src.indexOf( 'mwScriptLoader.php' ) ) + $.conf.mediaWikiPath; |
| 1285 | + mwpath = src.substr( 0, src.indexOf( 'mwScriptLoader.php' ) ) + $.getConfig( 'mediaWikiPath' ); |
1262 | 1286 | } |
1263 | 1287 | |
1264 | 1288 | // Script-loader has jsScriptLoader name when local: |
— | — | @@ -1309,7 +1333,7 @@ |
1310 | 1334 | var mwUrlParam = null; |
1311 | 1335 | |
1312 | 1336 | /** |
1313 | | - * Get URL Paramaters per paramaters in the host script include |
| 1337 | + * Get URL Parameters per parameters in the host script include |
1314 | 1338 | */ |
1315 | 1339 | $.getUrlParam = function() { |
1316 | 1340 | if ( mwUrlParam ) |
— | — | @@ -1323,7 +1347,7 @@ |
1324 | 1348 | |
1325 | 1349 | // If we're in debug mode, get a fresh unique request key and pass on "debug" param |
1326 | 1350 | if ( mw.parseUri( mwEmbedSrc ).queryKey['debug'] == 'true' ) { |
1327 | | - |
| 1351 | + $.setConfig( 'debug', true ); |
1328 | 1352 | var d = new Date(); |
1329 | 1353 | req_param += 'urid=' + d.getTime() + '&debug=true'; |
1330 | 1354 | |
— | — | @@ -1335,7 +1359,7 @@ |
1336 | 1360 | req_param += 'urid=' + mw.version; |
1337 | 1361 | } |
1338 | 1362 | |
1339 | | - // Add the language param: |
| 1363 | + // Add the language param if present: |
1340 | 1364 | var langKey = mw.parseUri( mwEmbedSrc ).queryKey['uselang']; |
1341 | 1365 | if ( langKey ) |
1342 | 1366 | req_param += '&uselang=' + langKey; |
— | — | @@ -1545,17 +1569,16 @@ |
1546 | 1570 | } ); |
1547 | 1571 | |
1548 | 1572 | /** |
1549 | | -* libEmbedPlayer Depenency Module Loader: |
| 1573 | +* libEmbedPlayer Dependency Module Loader: |
1550 | 1574 | * |
1551 | 1575 | * NOTE: this code block could eventually be put in: |
1552 | 1576 | * "libEmbedPlayer/loader.js" |
1553 | 1577 | * |
1554 | | -* That it could be dynamically inserted into mwEmbed requests |
1555 | | -* at poit of release or at runtime via the script-loader. |
| 1578 | +* Then it could be dynamically inserted into mwEmbed requests |
| 1579 | +* at point of release or at runtime via the script-loader. |
1556 | 1580 | * |
1557 | | -* A per module loader enables a dynamic set of modules with only minimal |
| 1581 | +* Per module loader enables a dynamic set of modules with only minimal |
1558 | 1582 | * loader code per module in the core mwEmbed included js |
1559 | | -* |
1560 | 1583 | */ |
1561 | 1584 | // Add class file paths: |
1562 | 1585 | mw.addClassFilePaths( { |
— | — | @@ -1567,16 +1590,15 @@ |
1568 | 1591 | "javaEmbed" : "libEmbedPlayer/javaEmbed.js", |
1569 | 1592 | "nativeEmbed" : "libEmbedPlayer/nativeEmbed.js", |
1570 | 1593 | "quicktimeEmbed" : "libEmbedPlayer/quicktimeEmbed.js", |
1571 | | - "vlcEmbed" : "libEmbedPlayer/vlcEmbed.js", |
| 1594 | + "vlcEmbed" : "libEmbedPlayer/vlcEmbed.js" |
1572 | 1595 | |
1573 | 1596 | } ); |
1574 | | - |
1575 | 1597 | // Add the module loader function: |
1576 | | -mw.addModuleLoader( 'player', function(){ |
| 1598 | +mw.addModuleLoader( 'player', function( callback ){ |
1577 | 1599 | var _this = this; |
1578 | 1600 | js_log( 'loadModule: player :' ); |
1579 | 1601 | |
1580 | | - // Set module specifc class videonojs to loading: |
| 1602 | + // Set module specific class videonojs to loading: |
1581 | 1603 | $j( '.videonojs' ).html( gM( 'mwe-loading_txt' ) ); |
1582 | 1604 | |
1583 | 1605 | // Set up the embed video player class request: (include the skin js as well) |
— | — | @@ -1594,43 +1616,47 @@ |
1595 | 1617 | |
1596 | 1618 | // Get any other skins that we need to load |
1597 | 1619 | // That way skin js can be part of the single script-loader request: |
1598 | | - |
1599 | | - var sn = e[j][k].getAttribute('class'); |
1600 | | - if( sn && sn != ''){ |
1601 | | - for(var n=0;n< $mw.valid_skins.length;n++){ |
1602 | | - if( sn.indexOf($mw.valid_skins[n]) !== -1){ |
1603 | | - $mw.skin_list.push( $mw.valid_skins[n] ); |
1604 | | - } |
| 1620 | + var playerElements = mw.getPlayerTagElements(); |
| 1621 | + $j.each( playerElements, function(na, playerElem ){ |
| 1622 | + var cName = $j( playerElem ).attr( 'class' ); |
| 1623 | + for( var n=0; n < mw.valid_skins.length ; n++ ){ |
| 1624 | + if( cName.indexOf( mw.valid_skins[ n ] ) !== -1){ |
| 1625 | + mw.skin_list.push( mw.valid_skins[n] ); |
1605 | 1626 | } |
1606 | | - } |
1607 | | - // Add any requested skins (supports multiple skins per single page) |
| 1627 | + } |
| 1628 | + } ); |
| 1629 | + |
| 1630 | + // Add any page specific requested skins js ( supports multiple skins per single page ) |
1608 | 1631 | if ( mw.skin_list ) { |
1609 | 1632 | for ( var i in mw.skin_list ) { |
1610 | | - depReq[0].push( mw.skin_list[i] + 'Config' ); |
| 1633 | + dependencyRequest[0].push( mw.skin_list[i] + 'Config' ); |
1611 | 1634 | } |
1612 | 1635 | } |
1613 | 1636 | |
1614 | 1637 | // Add PNG fix if needed: |
1615 | 1638 | if ( $j.browser.msie || $j.browser.version < 7 ) |
1616 | | - depReq[0].push( '$j.fn.pngFix' ); |
| 1639 | + dependencyRequest[0].push( '$j.fn.pngFix' ); |
1617 | 1640 | |
1618 | 1641 | // Load the video libs: |
1619 | | - _this.doLoadDepMode( depReq, function() { |
| 1642 | + mw.load( dependencyRequest, function() { |
| 1643 | + |
| 1644 | + // Detect what players are supported: |
1620 | 1645 | embedTypes.init(); |
1621 | | - callback(); |
| 1646 | + |
| 1647 | + // Remove no video html elements: |
1622 | 1648 | $j( '.videonojs' ).remove(); |
| 1649 | + |
| 1650 | + //Run the callback |
| 1651 | + callback(); |
1623 | 1652 | } ); |
1624 | 1653 | |
1625 | | -} ); |
| 1654 | +} ); // done with embedPlayer loader.js |
1626 | 1655 | |
1627 | 1656 | |
1628 | 1657 | |
1629 | 1658 | |
1630 | 1659 | |
1631 | 1660 | |
1632 | | - |
1633 | | - |
1634 | | - |
1635 | 1661 | // Add the core mvEmbed Messages ( will be localized by script server ) |
1636 | 1662 | mw.addMessages( { |
1637 | 1663 | "mwe-loading_txt" : "Loading ...", |
— | — | @@ -1675,17 +1701,6 @@ |
1676 | 1702 | |
1677 | 1703 | |
1678 | 1704 | |
1679 | | - |
1680 | | - |
1681 | | - |
1682 | | - |
1683 | | - |
1684 | | - |
1685 | | - |
1686 | | - |
1687 | | - |
1688 | | - |
1689 | | - |
1690 | 1705 | // Get the loading image |
1691 | 1706 | function mv_get_loading_img( style, class_attr ) { |
1692 | 1707 | var style_txt = ( style ) ? style:''; |
— | — | @@ -2292,6 +2307,9 @@ |
2293 | 2308 | $.addDialog( msg_txt, msg_txt + '<br>' + mv_get_loading_img() ); |
2294 | 2309 | } |
2295 | 2310 | |
| 2311 | + /** |
| 2312 | + * shortcut jquery binding to add a dialog window: |
| 2313 | + */ |
2296 | 2314 | $.addDialog = function ( title, msg_txt, btn ) { |
2297 | 2315 | $( '#mwe_tmp_loader' ).remove(); |
2298 | 2316 | // append the style free loader ontop: |
Index: branches/js2-work/phase3/js2/mwEmbed/example_usage/Firefogg_Make_Advanced.html |
— | — | @@ -2,8 +2,8 @@ |
3 | 3 | <html><head> |
4 | 4 | <meta http-equiv="content-type" content="text/html; charset=UTF-8"> |
5 | 5 | <title>Firefogg - Make Ogg Video in your Browser</title> |
6 | | - <script type="text/javascript" src="../jsScriptLoader.php?urid=r58125&class=mwEmbed,window.jQuery,mvBaseUploadInterface,mvFirefogg,mvAdvFirefogg,$j.ui,$j.ui.progressbar,$j.ui.dialog,$j.cookie,$j.ui.accordion,$j.ui.slider,$j.ui.datepicker,$j.ui.draggable"></script> |
7 | | - <!-- <script type="text/javascript" src="../mwEmbed.js"></script> --> |
| 6 | + <!-- <script type="text/javascript" src="../jsScriptLoader.php?urid=r58125&class=mwEmbed,window.jQuery,mvBaseUploadInterface,mvFirefogg,mvAdvFirefogg,$j.ui,$j.ui.progressbar,$j.ui.dialog,$j.cookie,$j.ui.accordion,$j.ui.slider,$j.ui.datepicker,$j.ui.draggable"></script> --> |
| 7 | + <script type="text/javascript" src="../mwEmbed.js?debug=true"></script> |
8 | 8 | <style type="text/css" media="all">body { |
9 | 9 | margin: 0; |
10 | 10 | padding: 0; |
— | — | @@ -66,10 +66,10 @@ |
67 | 67 | } |
68 | 68 | </style> |
69 | 69 | <script type="text/javascript"> |
70 | | -mwAddOnloadHook(function(){ |
| 70 | +mw.addOnloadHook(function(){ |
71 | 71 | $j('#firefogg_app').firefogg({ |
72 | | - 'encoder_interface' : true, |
73 | | - 'encode_local' : true |
| 72 | + 'encoder_interface' : true, |
| 73 | + 'encode_local' : true |
74 | 74 | },function(){ |
75 | 75 | $j('#loadFogg').hide(); |
76 | 76 | }); |
Index: branches/js2-work/phase3/js2/mwEmbed/libAddMedia/searchLibs/metavidSearch.js |
— | — | @@ -154,7 +154,7 @@ |
155 | 155 | if ( !source ) { |
156 | 156 | js_error( 'Error::could not find source: ' + resource.pSobj.provider.stream_import_key ); |
157 | 157 | } else { |
158 | | - resource['src'] = source.getURI(); |
| 158 | + resource['src'] = source.getSrc(); |
159 | 159 | js_log( "g src_key: " + resource.pSobj.provider.stream_import_key + ' src:' + resource['src'] ) ; |
160 | 160 | return true; |
161 | 161 | } |
— | — | @@ -190,9 +190,9 @@ |
191 | 191 | resource.other_versions = '*[' + resource['roe_url'] + ' XML of all Video Formats and Timed Text]' + "\n"; |
192 | 192 | for ( var i in sources ) { |
193 | 193 | var cur_source = sources[i]; |
194 | | - // resource.other_versions += '*['+cur_source.getURI() +' ' + cur_source.title +']' + "\n"; |
| 194 | + // resource.other_versions += '*['+cur_source.getSrc() +' ' + cur_source.title +']' + "\n"; |
195 | 195 | if ( cur_source.id == this.provider.target_source_id ) |
196 | | - resource['url'] = cur_source.getURI(); |
| 196 | + resource['url'] = cur_source.getSrc(); |
197 | 197 | } |
198 | 198 | // js_log('set url to: ' + resource['url']); |
199 | 199 | return resource; |
Index: branches/js2-work/phase3/js2/mwEmbed/libAddMedia/mvFirefogg.js |
— | — | @@ -724,8 +724,10 @@ |
725 | 725 | */ |
726 | 726 | getEncoderSettings: function() { |
727 | 727 | if ( this.current_encoder_settings == null ) { |
| 728 | + |
728 | 729 | // Clone the default settings |
729 | | - var settings = $j.extend( { }, this.default_encoder_settings) ; |
| 730 | + var settings = $j.extend( { }, this.default_encoder_settings) ; |
| 731 | + |
730 | 732 | // Grab the extension |
731 | 733 | var sf = this.fogg.sourceFilename; |
732 | 734 | if ( !sf ) { |
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/embedPlayer.js |
— | — | @@ -1,4 +1,4 @@ |
2 | | -/* |
| 2 | +/** |
3 | 3 | * embedPlayer is the base class for html5 video tag javascript abstraction library |
4 | 4 | * embedPlayer include a few subclasses: |
5 | 5 | * |
— | — | @@ -53,7 +53,7 @@ |
54 | 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 | 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 | 56 | "mwe-do_not_warn_again" : "Dismiss for now.", |
57 | | - "mwe-playerselect" : "Players", |
| 57 | + "mwe-playerSelect" : "Players", |
58 | 58 | "mwe-read_before_embed" : "<a href=\"http:\/\/mediawiki.org\/wiki\/Security_Notes_on_Remote_Embedding\" target=\"_new\">Read this<\/a> before embedding.", |
59 | 59 | "mwe-embed_site_or_blog" : "Embed on a page", |
60 | 60 | "mwe-related_videos" : "Related videos", |
— | — | @@ -343,7 +343,9 @@ |
344 | 344 | // Make sure we have the necessary playlist libs loaded: |
345 | 345 | mw.load( [ |
346 | 346 | 'mvPlayList', |
347 | | - '$j.ui', // Include dialog for pop-ing up things |
| 347 | + |
| 348 | + // Include dialog: |
| 349 | + '$j.ui', |
348 | 350 | '$j.ui.dialog' |
349 | 351 | ], function() { |
350 | 352 | // Create playlist player interface |
— | — | @@ -596,7 +598,7 @@ |
597 | 599 | * @param {Number} seek_time_sec Int: Used to adjust the URI for url based seeks) |
598 | 600 | * @return {String} the URI of the source. |
599 | 601 | */ |
600 | | - getURI : function( seek_time_sec ) { |
| 602 | + getSrc : function( seek_time_sec ) { |
601 | 603 | if ( !seek_time_sec || !this.URLTimeEncoding ) { |
602 | 604 | return this.src; |
603 | 605 | } |
— | — | @@ -762,7 +764,7 @@ |
763 | 765 | |
764 | 766 | if ( $j( video_element ).attr( 'durationHint' ) ) { |
765 | 767 | this.durationHint = $j( video_element ).attr( 'durationHint' ); |
766 | | - // convert duration hint if needed: |
| 768 | + // Convert duration hint if needed: |
767 | 769 | this.duration = npt2seconds( this.durationHint ); |
768 | 770 | } |
769 | 771 | |
— | — | @@ -839,15 +841,14 @@ |
840 | 842 | * |
841 | 843 | * @param {Number} index Index of source element to set as selected_source |
842 | 844 | */ |
843 | | - selectSource:function( index ) |
844 | | - { |
| 845 | + selectSource:function( index ) { |
845 | 846 | js_log( 'f:selectSource:' + index ); |
846 | 847 | var playable_sources = this.getPlayableSources(); |
847 | 848 | for ( var i = 0; i < playable_sources.length; i++ ) { |
848 | 849 | if ( i == index ) { |
849 | 850 | this.selected_source = playable_sources[i]; |
850 | 851 | // Update the user selected format: |
851 | | - embedTypes.players.userSelectFormat( playable_sources[i].mime_type ); |
| 852 | + embedTypes.players.setFormatPreference( playable_sources[i].mime_type ); |
852 | 853 | break; |
853 | 854 | } |
854 | 855 | } |
— | — | @@ -870,7 +871,7 @@ |
871 | 872 | return true; |
872 | 873 | } |
873 | 874 | // Set via user-preference |
874 | | - if ( embedTypes.players.preference['format_prefrence'] == mime_type ) { |
| 875 | + if ( embedTypes.players.preference['format_preference'] == mime_type ) { |
875 | 876 | js_log( 'set via preference: ' + playable_sources[source].mime_type ); |
876 | 877 | this.selected_source = playable_sources[source]; |
877 | 878 | return true; |
— | — | @@ -926,8 +927,7 @@ |
927 | 928 | * Returns the thumbnail URL for the media element. |
928 | 929 | * @returns {String} thumbnail URL |
929 | 930 | */ |
930 | | - getThumbnailURL:function() |
931 | | - { |
| 931 | + getThumbnailURL: function( ) { |
932 | 932 | return this.thumbnail; |
933 | 933 | }, |
934 | 934 | |
— | — | @@ -963,15 +963,14 @@ |
964 | 964 | * the element has a 'src' attribute. |
965 | 965 | * @param {Element} element <video>, <source> or <mediaSource> <text> element. |
966 | 966 | */ |
967 | | - tryAddSource:function( element ) |
968 | | - { |
| 967 | + tryAddSource: function( element ) { |
969 | 968 | js_log( 'f:tryAddSource:' + $j( element ).attr( "src" ) ); |
970 | 969 | if ( $j( element ).attr( "src" ) ) { |
971 | 970 | var new_src = $j( element ).attr( 'src' ); |
972 | 971 | // make sure an existing element with the same src does not already exist: |
973 | 972 | for ( var i = 0; i < this.sources.length; i++ ) { |
974 | 973 | if ( this.sources[i].src == new_src ) { |
975 | | - // js_log('checking existing: '+this.sources[i].getURI() + ' != '+ new_src); |
| 974 | + // js_log('checking existing: '+this.sources[i].getSrc() + ' != '+ new_src); |
976 | 975 | // can't add it all but try to update any additional attr: |
977 | 976 | this.sources[i].updateSource( element ); |
978 | 977 | } |
— | — | @@ -985,9 +984,8 @@ |
986 | 985 | if ( !source.startOffset && this.startOffset ) |
987 | 986 | source.startOffset = this.startOffset; |
988 | 987 | |
989 | | - |
990 | | - this.sources.push( source ); |
991 | 988 | js_log( 'pushed source to stack' + source + 'sl:' + this.sources.length ); |
| 989 | + this.sources.push( source ); |
992 | 990 | }, |
993 | 991 | |
994 | 992 | /** |
— | — | @@ -1097,6 +1095,9 @@ |
1098 | 1096 | // Percent of the clip buffered: |
1099 | 1097 | 'bufferedPercent' : 0, |
1100 | 1098 | |
| 1099 | + // Holds the timmer interval function |
| 1100 | + 'monitorTimerId' : null, |
| 1101 | + |
1101 | 1102 | /** |
1102 | 1103 | * embedPlayer constructor |
1103 | 1104 | * |
— | — | @@ -1176,18 +1177,23 @@ |
1177 | 1178 | |
1178 | 1179 | /** |
1179 | 1180 | * Set width or height from css style attribute, html element attribute, or by default value |
| 1181 | + * @param {Element} element Source element to grab size from |
| 1182 | + * @param {String} dimension "height" or "width" |
1180 | 1183 | */ |
1181 | | - setDimSize:function( element, dim ){ |
1182 | | - var dcss = parseInt( $j(element).css( dim ).replace( 'px' , '' ) ); |
1183 | | - var dattr = parseInt( $j(element).attr( dim ) ); |
1184 | | - this[ dim ] = ( dcss )? dcss : dattr; |
1185 | | - if( !this[ dim ] ){ |
| 1184 | + setDimSize:function( element, dimension ){ |
| 1185 | + var dcss = parseInt( $j(element).css( dimension ).replace( 'px' , '' ) ); |
| 1186 | + var dattr = parseInt( $j(element).attr( dimension ) ); |
| 1187 | + |
| 1188 | + this[ dimension ] = ( dcss )? dcss : dattr; |
| 1189 | + |
| 1190 | + // On load sometimes attr is temporarlly -1 |
| 1191 | + if( ! this[ dimension ] || this[ dimension ] == -1 ){ |
1186 | 1192 | //special height default for audio tag: |
1187 | | - if( element.tagName.toLowerCase() == 'audio' && dim == 'height' ) |
1188 | | - return this[ dim ] = 0; |
| 1193 | + if( element.tagName.toLowerCase() == 'audio' && dimension == 'height' ) |
| 1194 | + return this[ dimension ] = 0; |
1189 | 1195 | // Grab width/height from default value (for video) |
1190 | 1196 | var dwh = mw.getConfig( 'video_size' ).split( 'x' ); |
1191 | | - this[ dim ] = ( dim == 'width' )? dwh[0] : dwh[1]; |
| 1197 | + this[ dimension ] = ( dimension == 'width' )? dwh[0] : dwh[1]; |
1192 | 1198 | } |
1193 | 1199 | }, |
1194 | 1200 | |
— | — | @@ -1315,8 +1321,7 @@ |
1316 | 1322 | var _this = this; |
1317 | 1323 | |
1318 | 1324 | // Load the selected player |
1319 | | - this.selected_player.load( function() { |
1320 | | - |
| 1325 | + this.selected_player.load( function() { |
1321 | 1326 | // Get the selected Player embed interface |
1322 | 1327 | eval( 'var embedPlayer = ' + _this.selected_player.library + 'Embed;' ); |
1323 | 1328 | |
— | — | @@ -1325,13 +1330,13 @@ |
1326 | 1331 | _this['parent_' + method] = _this[method]; |
1327 | 1332 | _this[method] = embedPlayer[method]; |
1328 | 1333 | } |
1329 | | - |
| 1334 | + |
1330 | 1335 | _this.ready_to_play = true; |
1331 | 1336 | _this.getDuration(); |
1332 | | - _this.getHTML(); |
| 1337 | + _this.showPlayer(); |
1333 | 1338 | |
1334 | 1339 | // Run the callback if provided |
1335 | | - if ( callback ) |
| 1340 | + if ( typeof callback == 'function' ) |
1336 | 1341 | callback(); |
1337 | 1342 | } ); |
1338 | 1343 | }, |
— | — | @@ -1342,13 +1347,13 @@ |
1343 | 1348 | * @param {Object} player Player playback system to be selected |
1344 | 1349 | * player playback system include vlc, native, java etc. |
1345 | 1350 | */ |
1346 | | - selectPlayer:function( player ) { |
| 1351 | + selectPlayer: function( player ) { |
1347 | 1352 | var _this = this; |
1348 | 1353 | if ( this.selected_player.id != player.id ) { |
1349 | 1354 | this.selected_player = player; |
1350 | 1355 | this.inheritEmbedPlayer( function(){ |
1351 | 1356 | // Update the controls for the new selected player |
1352 | | - this.refreshControlsHTML(); |
| 1357 | + this.refreshControls(); |
1353 | 1358 | }); |
1354 | 1359 | } |
1355 | 1360 | }, |
— | — | @@ -1357,7 +1362,7 @@ |
1358 | 1363 | * Issue a warning to non-native playback systems |
1359 | 1364 | * that they could improve the playback experience with a different browser |
1360 | 1365 | */ |
1361 | | - doNativeWarningCheck:function() { |
| 1366 | + doNativeWarningCheck: function( ) { |
1362 | 1367 | if ( $j.cookie( 'dismissNativeWarn' ) && $j.cookie( 'dismissNativeWarn' ) === true ) { |
1363 | 1368 | return false; |
1364 | 1369 | } |
— | — | @@ -1443,7 +1448,7 @@ |
1444 | 1449 | return 'Error: function getEmbedHTML should be implemented by embed player interface '; |
1445 | 1450 | }, |
1446 | 1451 | |
1447 | | - /* |
| 1452 | + /** |
1448 | 1453 | * Seek function (should be implemented by embed player interface ) |
1449 | 1454 | */ |
1450 | 1455 | doSeek : function( percent ) { |
— | — | @@ -1455,13 +1460,14 @@ |
1456 | 1461 | this.stop(); |
1457 | 1462 | this.didSeekJump = true; |
1458 | 1463 | // Update the slider |
1459 | | - this.setSliderValue( percent ); |
| 1464 | + this.updatePlayHead( percent ); |
1460 | 1465 | } |
1461 | 1466 | // Do play request in 100ms ( give the dom time to swap out the embed player ) |
1462 | 1467 | setTimeout( function(){ |
1463 | 1468 | _this.play() |
1464 | 1469 | }, 100 ); |
1465 | 1470 | }, |
| 1471 | + |
1466 | 1472 | /** |
1467 | 1473 | * Seeks to the requested time and issues a callback when ready |
1468 | 1474 | * (should be overwritten by client that supports frame serving) |
— | — | @@ -1470,27 +1476,33 @@ |
1471 | 1477 | js_log( 'Error: base embed setCurrentTime can not frame serve (override via plugin)' ); |
1472 | 1478 | }, |
1473 | 1479 | |
1474 | | - doEmbedHTML:function() { |
1475 | | - js_log( 'f:doEmbedHTML' ); |
| 1480 | + /** |
| 1481 | + * Setup the embed player |
| 1482 | + * issues a loading request |
| 1483 | + */ |
| 1484 | + setupEmbedPlayer:function() { |
| 1485 | + js_log( 'f:setupEmbedPlayer' ); |
1476 | 1486 | js_log( 'thum disp:' + this.thumbnail_disp ); |
1477 | | - var _this = this; |
1478 | | - this.closeDisplayedHTML(); |
| 1487 | + var _this = this; |
1479 | 1488 | |
1480 | | - // Set "loading" here |
| 1489 | + // Set "loading" here: |
1481 | 1490 | $j( '#mv_embedded_player_' + _this.id ).html( '' + |
1482 | 1491 | '<div style="color:black;width:' + this.width + 'px;height:' + this.height + 'px;">' + |
1483 | 1492 | gM( 'mwe-loading_plugin' ) + |
1484 | 1493 | '</div>' |
1485 | 1494 | ); |
1486 | | - // Schedule embedding after player library is loaded: |
1487 | | - this.selected_player.load( function() { |
1488 | | - js_log( 'performing embed for ' + _this.id ); |
1489 | | - var embed_code = _this.getEmbedHTML(); |
1490 | | - // js_log('shopuld embed:' + embed_code); |
1491 | | - $j( '#mv_embedded_player_' + _this.id ).html( embed_code ); |
1492 | | - } ); |
| 1495 | + |
| 1496 | + // Make sure the player is |
| 1497 | + js_log( 'performing embed for ' + _this.id ); |
| 1498 | + var embed_code = _this.getEmbedHTML(); |
| 1499 | + // js_log('shopuld embed:' + embed_code); |
| 1500 | + $j( '#mv_embedded_player_' + _this.id ).html( embed_code ); |
1493 | 1501 | }, |
1494 | | - relatedTitleKeySearch:function() { |
| 1502 | + |
| 1503 | + /** |
| 1504 | + * Searches for related clipes from titleKey |
| 1505 | + */ |
| 1506 | + getRelatedFromTitleKey:function() { |
1495 | 1507 | var _this = this; |
1496 | 1508 | var reqObj = { |
1497 | 1509 | 'action' : 'query', |
— | — | @@ -1511,20 +1523,26 @@ |
1512 | 1524 | } |
1513 | 1525 | _this.getRelatedFromCat( req_categories ); |
1514 | 1526 | } else { |
1515 | | - _this.doThumbnailHTML(); |
| 1527 | + _this.showThumbnail(); |
1516 | 1528 | } |
1517 | 1529 | } ); |
1518 | 1530 | }, |
1519 | | - getRelatedFromCat:function( catAry ) { |
| 1531 | + |
| 1532 | + /** |
| 1533 | + * Get Related Clips from a category list |
| 1534 | + * |
| 1535 | + * @parma {Object} catlist List of categories |
| 1536 | + */ |
| 1537 | + getRelatedFromCat:function( catlist ) { |
1520 | 1538 | js_log( 'getRelatedFromCat' ); |
1521 | 1539 | var _this = this; |
1522 | | - for ( var i = 0 ; i <= catAry.length ; i++ ) { |
1523 | | - if ( !catAry[i] ) |
| 1540 | + for ( var i = 0 ; i <= catlist.length ; i++ ) { |
| 1541 | + if ( !catlist[i] ) |
1524 | 1542 | continue; |
1525 | 1543 | var reqObj = { |
1526 | 1544 | 'action' : 'query', |
1527 | 1545 | 'generator' : 'categorymembers' , |
1528 | | - 'gcmtitle' : catAry[i], |
| 1546 | + 'gcmtitle' : catlist[i], |
1529 | 1547 | 'prop' : 'imageinfo', |
1530 | 1548 | 'iiprop' : 'url', |
1531 | 1549 | 'iiurlwidth': '80' |
— | — | @@ -1563,12 +1581,16 @@ |
1564 | 1582 | } ); // end do_api_req |
1565 | 1583 | }; |
1566 | 1584 | }, |
| 1585 | + |
| 1586 | + /** |
| 1587 | + * On clip done action. Called once a clip is done playing |
| 1588 | + */ |
1567 | 1589 | onClipDone:function() { |
1568 | 1590 | js_log( 'base:onClipDone' ); |
1569 | 1591 | // stop the clip (load the thumbnail etc) |
1570 | 1592 | this.stop(); |
1571 | 1593 | this.seek_time_sec = 0; |
1572 | | - this.setSliderValue( 0 ); |
| 1594 | + this.updatePlayHead( 0 ); |
1573 | 1595 | var _this = this; |
1574 | 1596 | |
1575 | 1597 | if ( this.width < 300 ) { |
— | — | @@ -1599,12 +1621,17 @@ |
1600 | 1622 | '</div>' ); |
1601 | 1623 | $j( '#img_thumb_' + this.id ).fadeOut( "fast" ); |
1602 | 1624 | $j( '#dc_' + _this.id + ' .related_vids ul' ).html( gM( 'mwe-loading_txt' ) ); |
1603 | | - this.relatedTitleKeySearch(); |
| 1625 | + this.getRelatedFromTitleKey(); |
1604 | 1626 | } else { |
1605 | | - this.onClipDoneDisp(); |
| 1627 | + this.showNearbyClips(); |
1606 | 1628 | } |
1607 | 1629 | }, |
1608 | | - onClipDoneDisp:function() { |
| 1630 | + |
| 1631 | + /** |
| 1632 | + * Shows nearby clips based on "roe" xml |
| 1633 | + * Mostly metavid specific ( should be factored into a seperate module ) |
| 1634 | + */ |
| 1635 | + showNearbyClips: function() { |
1609 | 1636 | var _this = this; |
1610 | 1637 | // add the liks_info_div black back |
1611 | 1638 | $j( '#dc_' + this.id ).append( '<div id="liks_info_' + this.id + '" ' + |
— | — | @@ -1638,11 +1665,15 @@ |
1639 | 1666 | _this.getNextPrevLinks(); |
1640 | 1667 | } ); |
1641 | 1668 | } else { |
1642 | | - this.getNextPrevLinks(); |
| 1669 | + this.getNearbyClipLinks(); |
1643 | 1670 | } |
1644 | 1671 | }, |
1645 | | - // @@todo we should merge getNextPrevLinks with textInterface .. there is repeated code between them. |
1646 | | - getNextPrevLinks:function() { |
| 1672 | + |
| 1673 | + /** |
| 1674 | + * Gets nearby Clip links |
| 1675 | + * Mostly metavid specific ( should be factored into a seperate module ) |
| 1676 | + */ |
| 1677 | + getNearbyClipLinks:function() { |
1647 | 1678 | js_log( 'f:getNextPrevLinks' ); |
1648 | 1679 | var anno_track_url = null; |
1649 | 1680 | var _this = this; |
— | — | @@ -1658,7 +1689,7 @@ |
1659 | 1690 | if ( !anno_track_url ) { |
1660 | 1691 | js_log( 'no annotative track url found' ); |
1661 | 1692 | // $j('#liks_info_'+this.id).html('no metadata found for related links'); |
1662 | | - _this.doThumbnailHTML(); |
| 1693 | + _this.showThumbnail(); |
1663 | 1694 | return ; |
1664 | 1695 | } |
1665 | 1696 | |
— | — | @@ -1717,7 +1748,12 @@ |
1718 | 1749 | } |
1719 | 1750 | // query current request time +|- 60s to get prev next speech links. |
1720 | 1751 | }, |
1721 | | - showNextPrevLinks:function() { |
| 1752 | + |
| 1753 | + /** |
| 1754 | + * Display the nearby clip links |
| 1755 | + * Mostly metavid specific ( should be factored into a seperate module ) |
| 1756 | + */ |
| 1757 | + showNearbyClipLinks:function() { |
1722 | 1758 | // js_log('f:showNextPrevLinks'); |
1723 | 1759 | // int requested links: |
1724 | 1760 | var link = { |
— | — | @@ -1776,8 +1812,7 @@ |
1777 | 1813 | if ( regTimeCheck.test( this.media_element.linkback ) ) { |
1778 | 1814 | html += ' href="' + this.media_element.linkback.replace( regTimeCheck, time_req ) + '" '; |
1779 | 1815 | } else { |
1780 | | - html += ' href="#" onClick="$j(\'#' + this.id + '\').get(0).playByTimeReq(\'' + |
1781 | | - time_req + '\'); return false; "'; |
| 1816 | + html += ' href="#" class="playtimerequest" '; |
1782 | 1817 | } |
1783 | 1818 | html += ' title="' + title_msg + '">' + |
1784 | 1819 | gM( 'mwe-' + link_type + '_clip_msg' ) + |
— | — | @@ -1786,38 +1821,59 @@ |
1787 | 1822 | } |
1788 | 1823 | } |
1789 | 1824 | // js_og("should set html:"+ html); |
1790 | | - $j( '#liks_info_' + this.id ).html( html ); |
| 1825 | + $j( '#liks_info_' + this.id ) |
| 1826 | + .html( html ) |
| 1827 | + //Do bindings: |
| 1828 | + .children( '.playtimerequest' ) |
| 1829 | + .click( function(){ |
| 1830 | + _this.stop(); |
| 1831 | + _this.updateVideoTimeReq( time_req ); |
| 1832 | + _this.play(); |
| 1833 | + } ); |
| 1834 | + |
1791 | 1835 | }, |
1792 | | - playByTimeReq: function( time_req ) { |
1793 | | - js_log( 'f:playByTimeReq: ' + time_req ); |
1794 | | - this.stop(); |
1795 | | - this.updateVideoTimeReq( time_req ); |
1796 | | - this.play(); |
1797 | | - }, |
1798 | | - doThumbnailHTML:function() { |
| 1836 | + |
| 1837 | + /** |
| 1838 | + * Shows the video Thumbnail, updates pause state |
| 1839 | + */ |
| 1840 | + showThumbnail: function() { |
1799 | 1841 | var _this = this; |
1800 | | - js_log( 'f:doThumbnailHTML' + this.thumbnail_disp ); |
| 1842 | + js_log( 'f:showThumbnail' + this.thumbnail_disp ); |
1801 | 1843 | this.closeDisplayedHTML(); |
1802 | 1844 | $j( '#mv_embedded_player_' + this.id ).html( this.getThumbnailHTML() ); |
1803 | 1845 | this.paused = true; |
1804 | 1846 | this.thumbnail_disp = true; |
1805 | | - // make sure the ctrlBuilder remain active: |
| 1847 | + // Make sure the ctrlBuilder bindings are up-to-date |
1806 | 1848 | this.ctrlBuilder.addControlHooks(); |
1807 | 1849 | }, |
1808 | | - refreshControlsHTML:function() { |
| 1850 | + |
| 1851 | + /** |
| 1852 | + * Refresh the player Controls |
| 1853 | + * Usefull for updating for when new playback system is selected |
| 1854 | + */ |
| 1855 | + refreshControls:function() { |
1809 | 1856 | if ( $j( '#' + this.id + ' .control-bar' ).length == 0 ) { |
1810 | | - js_log( 'refreshControlsHTML::control-bar not present, no refresh' ); |
| 1857 | + js_log( 'refreshControls::control-bar not present, no refresh' ); |
1811 | 1858 | return ; |
1812 | 1859 | } |
1813 | 1860 | // Do update controls: |
1814 | | - $j( '#' + this.id + ' .control-bar' ).html( this.getControlsHTML() ); |
| 1861 | + $j( '#' + this.id + ' .control-bar' ).html( this.getControls() ); |
1815 | 1862 | this.ctrlBuilder.addControlHooks(); |
1816 | 1863 | |
1817 | 1864 | }, |
1818 | | - getControlsHTML:function() { |
| 1865 | + |
| 1866 | + /** |
| 1867 | + * Maps the getControls request to the ctrl Builder |
| 1868 | + * requires this.ctrlBuilder to be setup |
| 1869 | + */ |
| 1870 | + getControls: function() { |
1819 | 1871 | return this.ctrlBuilder.getControls( this ); |
1820 | 1872 | }, |
1821 | | - getHTML : function () { |
| 1873 | + |
| 1874 | + /** |
| 1875 | + * |
| 1876 | + */ |
| 1877 | + showPlayer : function () { |
1822 | 1878 | // set-up the local ctrlBuilder instance: |
1823 | 1879 | this.ctrlBuilder = new ctrlBuilder( this ); |
1824 | 1880 | |
— | — | @@ -1828,12 +1884,11 @@ |
1829 | 1885 | html_code += '<div style="width:' + parseInt( this.width ) + 'px;height:' + parseInt( this.height ) + 'px;" id="mv_embedded_player_' + this.id + '">' + |
1830 | 1886 | this.getThumbnailHTML() + |
1831 | 1887 | '</div>'; |
1832 | | - |
1833 | | - // js_log("mvEmbed:controls "+ typeof this.controls); |
| 1888 | + |
1834 | 1889 | if ( this.controls ) { |
1835 | | - js_log( "f:getHTML:AddControls" ); |
| 1890 | + js_log( "f:showPlayer:AddControls" ); |
1836 | 1891 | html_code += '<div class="ui-state-default ui-widget-header ui-helper-clearfix control-bar" >'; |
1837 | | - html_code += this.getControlsHTML(); |
| 1892 | + html_code += this.getControls(); |
1838 | 1893 | html_code += '</div>'; |
1839 | 1894 | // block out some space by encapsulating the top level div |
1840 | 1895 | $j( this ).wrap( '<div style="width:' + parseInt( this.width ) + 'px;height:' |
— | — | @@ -1850,7 +1905,7 @@ |
1851 | 1906 | |
1852 | 1907 | |
1853 | 1908 | if ( this.autoplay ) { |
1854 | | - js_log( 'getHTML::activating autoplay' ); |
| 1909 | + js_log( 'showPlayer::activating autoplay' ); |
1855 | 1910 | this.play(); |
1856 | 1911 | } |
1857 | 1912 | }, |
— | — | @@ -1889,7 +1944,7 @@ |
1890 | 1945 | this.setStatus( start_npt + '/' + end_npt ); |
1891 | 1946 | |
1892 | 1947 | // reset slider |
1893 | | - this.setSliderValue( 0 ); |
| 1948 | + this.updatePlayHead( 0 ); |
1894 | 1949 | |
1895 | 1950 | // reset seek_offset: |
1896 | 1951 | if ( this.media_element.selected_source.URLTimeEncoding ) |
— | — | @@ -2204,14 +2259,19 @@ |
2205 | 2260 | * Close the custom HTML displayed using displayHTML and restores the |
2206 | 2261 | * regular mwEmbed display. |
2207 | 2262 | */ |
2208 | | - closeDisplayedHTML:function() { |
| 2263 | + closeDisplayedHTML: function() { |
2209 | 2264 | var sel_id = ( this.pc != null ) ? this.pc.pp.id:this.id; |
2210 | 2265 | $j( '#blackbg_' + sel_id ).fadeOut( "slow", function() { |
2211 | 2266 | $j( '#blackbg_' + sel_id ).remove(); |
2212 | 2267 | } ); |
2213 | 2268 | return false; // onclick action return false |
2214 | 2269 | }, |
2215 | | - showPlayerselect:function( $target ) { |
| 2270 | + |
| 2271 | + /** |
| 2272 | + * Shows the Player Select interface |
| 2273 | + * @param {Object} $target jQuery target to output to |
| 2274 | + */ |
| 2275 | + showPlayerSelect: function( $target ) { |
2216 | 2276 | // Get id (in case where we have a parent container) |
2217 | 2277 | var this_id = ( this.pc != null ) ? this.pc.pp.id:this.id; |
2218 | 2278 | var _this = this; |
— | — | @@ -2263,7 +2323,7 @@ |
2264 | 2324 | $j( '#' + this_id ).get( 0 ).closeDisplayedHTML(); |
2265 | 2325 | $j( '#' + _this.id ).get( 0 ).media_element.selectSource( source_id ); |
2266 | 2326 | |
2267 | | - embedTypes.players.userSelectPlayer( default_player_id, |
| 2327 | + embedTypes.players.setPlayerPreference( default_player_id, |
2268 | 2328 | _this.media_element.sources[ source_id ].getMIMEType() ); |
2269 | 2329 | |
2270 | 2330 | // Issue a stop |
— | — | @@ -2274,6 +2334,11 @@ |
2275 | 2335 | } ); |
2276 | 2336 | } ); |
2277 | 2337 | }, |
| 2338 | + |
| 2339 | + /** |
| 2340 | + * Shows the download interface |
| 2341 | + * @param {Object} $target jQuery target to output to |
| 2342 | + */ |
2278 | 2343 | showDownload:function( $target ) { |
2279 | 2344 | var _this = this; |
2280 | 2345 | // Load the roe if available (to populate out download options: |
— | — | @@ -2282,9 +2347,9 @@ |
2283 | 2348 | var dl_list = ''; |
2284 | 2349 | var dl_txt_list = ''; |
2285 | 2350 | $j.each( _this.media_element.getSources(), function( index, source ) { |
2286 | | - var dl_line = '<li>' + '<a style="color:white" href="' + source.getURI() + '"> ' |
| 2351 | + var dl_line = '<li>' + '<a style="color:white" href="' + source.getSrc() + '"> ' |
2287 | 2352 | + source.getTitle() + '</a> ' + '</li>' + "\n"; |
2288 | | - if ( source.getURI().indexOf( '?t=' ) !== -1 ) { |
| 2353 | + if ( source.getSrc().indexOf( '?t=' ) !== -1 ) { |
2289 | 2354 | out += dl_line; |
2290 | 2355 | } else if ( this.getMIMEType() == "text/cmml" || this.getMIMEType() == "text/x-srt" ) { |
2291 | 2356 | dl_txt_list += dl_line; |
— | — | @@ -2312,10 +2377,19 @@ |
2313 | 2378 | $target.html( getShowVideoDownload() ); |
2314 | 2379 | } |
2315 | 2380 | }, |
2316 | | - /* |
2317 | | - * Base embed controls |
2318 | | - * The Play Action: |
| 2381 | + |
| 2382 | + /** |
| 2383 | + * Base Embed Controls |
2319 | 2384 | */ |
| 2385 | + |
| 2386 | + /** |
| 2387 | + * The Play Action |
| 2388 | + * |
| 2389 | + * Handles play requests, updates relevet states: |
| 2390 | + * seeking =false |
| 2391 | + * paused = false |
| 2392 | + * Updates pause button |
| 2393 | + */ |
2320 | 2394 | play : function() { |
2321 | 2395 | var eid = ( this.pc != null ) ? this.pc.pp.id:this.id; |
2322 | 2396 | |
— | — | @@ -2326,7 +2400,7 @@ |
2327 | 2401 | // this.innerHTML = this.getPluginMissingHTML(); |
2328 | 2402 | $j( '#' + this.id ).html( this.getPluginMissingHTML() ); |
2329 | 2403 | } else { |
2330 | | - this.doEmbedHTML(); |
| 2404 | + this.setupEmbedPlayer(); |
2331 | 2405 | this.paused = false; |
2332 | 2406 | this.thumbnail_disp = false; |
2333 | 2407 | } |
— | — | @@ -2342,18 +2416,23 @@ |
2343 | 2417 | } ).attr( 'title', gM( 'mwe-pause_clip' ) ); |
2344 | 2418 | |
2345 | 2419 | }, |
| 2420 | + |
| 2421 | + /** |
| 2422 | + * Maps the html5 load request. |
| 2423 | + * There is no genneral way to "load" clips so underling plugin-player libs should overide. |
| 2424 | + */ |
2346 | 2425 | load:function() { |
2347 | 2426 | // should be done by child (no base way to pre-buffer video) |
2348 | 2427 | js_log( 'baseEmbed:load call' ); |
2349 | | - }, |
2350 | | - getSrc:function() { |
2351 | | - return this.media_element.selected_source.getURI( this.seek_time_sec ); |
2352 | | - }, |
2353 | | - /* |
2354 | | - * Base embed pause |
2355 | | - * there is no general way to pause the video |
2356 | | - * must be overwritten by embed object to support this functionality. |
2357 | | - */ |
| 2428 | + }, |
| 2429 | + |
| 2430 | + /** |
| 2431 | + * Base embed pause |
| 2432 | + * Updaets the play/pause button state. |
| 2433 | + * |
| 2434 | + * There is no general way to pause the video |
| 2435 | + * must be overwritten by embed object to support this functionality. |
| 2436 | + */ |
2358 | 2437 | pause: function() { |
2359 | 2438 | var _this = this; |
2360 | 2439 | var eid = ( this.pc != null ) ? this.pc.pp.id:this.id; |
— | — | @@ -2367,9 +2446,16 @@ |
2368 | 2447 | _this.play(); |
2369 | 2448 | } ).attr( 'title', gM( 'mwe-play_clip' ) ); |
2370 | 2449 | }, |
| 2450 | + |
2371 | 2451 | /** |
2372 | | - * Base embed stop (can be overwritten by the plugin) |
2373 | | - */ |
| 2452 | + * Base embed stop |
| 2453 | + * |
| 2454 | + * Updates the player to the stop state |
| 2455 | + * shows Thumbnail |
| 2456 | + * resets Buffer |
| 2457 | + * resets Playhead slider |
| 2458 | + * resets Status |
| 2459 | + */ |
2374 | 2460 | stop: function() { |
2375 | 2461 | var _this = this; |
2376 | 2462 | js_log( 'mvEmbed:stop:' + this.id ); |
— | — | @@ -2392,9 +2478,9 @@ |
2393 | 2479 | js_log( 'already in stopped state' ); |
2394 | 2480 | } else { |
2395 | 2481 | // rewrite the html to thumbnail disp |
2396 | | - this.doThumbnailHTML(); |
| 2482 | + this.showThumbnail(); |
2397 | 2483 | this.bufferedPercent = 0; // reset buffer state |
2398 | | - this.setSliderValue( 0 ); |
| 2484 | + this.updatePlayHead( 0 ); |
2399 | 2485 | this.setStatus( this.getTimeRange() ); |
2400 | 2486 | } |
2401 | 2487 | |
— | — | @@ -2409,6 +2495,13 @@ |
2410 | 2496 | this.update_interval = null; |
2411 | 2497 | } |
2412 | 2498 | }, |
| 2499 | + |
| 2500 | + /** |
| 2501 | + * Base Embed mute |
| 2502 | + * |
| 2503 | + * Handles interface updates for toggling mute. |
| 2504 | + * Plug-in / player interface must handle updateing the actual media player |
| 2505 | + */ |
2413 | 2506 | toggleMute:function() { |
2414 | 2507 | var eid = ( this.pc != null ) ? this.pc.pp.id:this.id; |
2415 | 2508 | if ( this.muted ) { |
— | — | @@ -2422,15 +2515,37 @@ |
2423 | 2516 | } |
2424 | 2517 | js_log( 'f:toggleMute::' + this.muted ); |
2425 | 2518 | }, |
| 2519 | + |
| 2520 | + /** |
| 2521 | + * Abstract Update volumen Method must be overided by plug-in / player interface |
| 2522 | + */ |
2426 | 2523 | updateVolumen:function( perc ) { |
2427 | 2524 | js_log( 'update volume not supported with current playback type' ); |
| 2525 | + return ; |
2428 | 2526 | }, |
| 2527 | + |
| 2528 | + /** |
| 2529 | + * Abstract fullscreen Method must be overided by plug-in / player interface |
| 2530 | + */ |
2429 | 2531 | fullscreen:function() { |
2430 | 2532 | js_log( 'fullscreen not supported with current playback type' ); |
| 2533 | + return ; |
2431 | 2534 | }, |
| 2535 | + |
2432 | 2536 | /** |
2433 | | - * returns bool true if playing or paused, false if stooped |
| 2537 | + * Abstract method to be run post embeding the player |
| 2538 | + * Generally should be overwiten by the plug-in / player |
2434 | 2539 | */ |
| 2540 | + postEmbedJS:function() { |
| 2541 | + return ; |
| 2542 | + }, |
| 2543 | + |
| 2544 | + /** |
| 2545 | + * Checks the player state based on thumbnail display & paused state |
| 2546 | + * @return {Boolean} |
| 2547 | + * true if playing |
| 2548 | + * false if not playing |
| 2549 | + */ |
2435 | 2550 | isPlaying : function() { |
2436 | 2551 | if ( this.thumbnail_disp ) { |
2437 | 2552 | // in stoped state |
— | — | @@ -2442,20 +2557,29 @@ |
2443 | 2558 | return true; |
2444 | 2559 | } |
2445 | 2560 | }, |
| 2561 | + |
| 2562 | + /** |
| 2563 | + * Getter for paused state |
| 2564 | + * @return {Boolean} |
| 2565 | + * true if playing |
| 2566 | + * false if not playing |
| 2567 | + */ |
2446 | 2568 | isPaused : function() { |
2447 | 2569 | return this.isPlaying() && this.paused; |
2448 | 2570 | }, |
| 2571 | + |
| 2572 | + /** |
| 2573 | + * Getter for Stoped state |
| 2574 | + * @return {Boolean} |
| 2575 | + * true if playing |
| 2576 | + * false if not playing |
| 2577 | + */ |
2449 | 2578 | isStoped : function() { |
2450 | 2579 | return this.thumbnail_disp; |
2451 | 2580 | }, |
2452 | | - playlistSupport:function() { |
2453 | | - // by default not supported (implemented in js) |
2454 | | - return false; |
2455 | | - }, |
2456 | | - postEmbedJS:function() { |
2457 | | - return ''; |
2458 | | - }, |
2459 | | - /* |
| 2581 | + |
| 2582 | + |
| 2583 | + /** |
2460 | 2584 | * Monitor playback and update interface components. |
2461 | 2585 | * underling plugin objects are responsible for updating currentTime |
2462 | 2586 | */ |
— | — | @@ -2466,11 +2590,11 @@ |
2467 | 2591 | if ( !this.userSlide && !this.seeking ) { |
2468 | 2592 | if ( this.start_offset ) { |
2469 | 2593 | // If start offset include that calculation |
2470 | | - this.setSliderValue( ( this.currentTime - this.start_offset ) / this.duration ); |
| 2594 | + this.updatePlayHead( ( this.currentTime - this.start_offset ) / this.duration ); |
2471 | 2595 | var et = ( this.ctrlBuilder.long_time_disp ) ? '/' + seconds2npt( parseFloat( this.start_offset ) + parseFloat( this.duration ) ) : ''; |
2472 | 2596 | this.setStatus( seconds2npt( this.currentTime ) + et ); |
2473 | 2597 | } else { |
2474 | | - this.setSliderValue( this.currentTime / this.duration ); |
| 2598 | + this.updatePlayHead( this.currentTime / this.duration ); |
2475 | 2599 | var et = ( this.ctrlBuilder.long_time_disp ) ? '/' + seconds2npt( this.duration ):''; |
2476 | 2600 | this.setStatus( seconds2npt( this.currentTime ) + et ); |
2477 | 2601 | } |
— | — | @@ -2478,7 +2602,7 @@ |
2479 | 2603 | // Check if we are "done" |
2480 | 2604 | var end_presentation_time = parseFloat( this.startOffset) + parseFloat( this.duration ) ; |
2481 | 2605 | if ( this.currentTime > end_presentation_time ) { |
2482 | | - js_log( "should run clip done ct:: " + this.currentTime + ' > ' + end_presentation_time ); |
| 2606 | + js_log( "should run clip done :: " + this.currentTime + ' > ' + end_presentation_time ); |
2483 | 2607 | this.onClipDone(); |
2484 | 2608 | } |
2485 | 2609 | } else { |
— | — | @@ -2497,8 +2621,10 @@ |
2498 | 2622 | this.setStatus( this.getTimeRange() ); |
2499 | 2623 | } |
2500 | 2624 | } |
| 2625 | + |
2501 | 2626 | // Update buffer information |
2502 | 2627 | this.updateBufferStatus(); |
| 2628 | + |
2503 | 2629 | // Update monitorTimerId to call child monitor |
2504 | 2630 | if ( ! this.monitorTimerId ) { |
2505 | 2631 | // Make sure an instance of this.id exists: |
— | — | @@ -2511,13 +2637,20 @@ |
2512 | 2638 | } |
2513 | 2639 | } |
2514 | 2640 | }, |
| 2641 | + |
| 2642 | + /** |
| 2643 | + * Stop the playback monitor |
| 2644 | + */ |
2515 | 2645 | stopMonitor:function() { |
2516 | | - if ( this.monitorTimerId != 0 ) |
2517 | | - { |
| 2646 | + if ( this.monitorTimerId != 0 ){ |
2518 | 2647 | clearInterval( this.monitorTimerId ); |
2519 | 2648 | this.monitorTimerId = 0; |
2520 | 2649 | } |
2521 | 2650 | }, |
| 2651 | + |
| 2652 | + /** |
| 2653 | + * Update the buffer status based on the local bufferedPercent var |
| 2654 | + */ |
2522 | 2655 | updateBufferStatus: function() { |
2523 | 2656 | |
2524 | 2657 | // Build the buffer target based for playlist vs clip |
— | — | @@ -2536,27 +2669,13 @@ |
2537 | 2670 | $j( buffer_select ).css( "width", '0px' ); |
2538 | 2671 | } |
2539 | 2672 | }, |
2540 | | - relativeCurrentTime: function() { |
2541 | | - if ( !this.start_offset ) |
2542 | | - this.start_offset = 0; |
2543 | | - var rt = this.currentTime - this.start_offset; |
2544 | | - if ( rt < 0 ) // should not happen but does. |
2545 | | - return 0; |
2546 | | - return rt; |
2547 | | - }, |
2548 | | - getPluginEmbed : function() { |
2549 | | - if ( window.document[this.pid] ) { |
2550 | | - return window.document[this.pid]; |
2551 | | - } |
2552 | | - if ( $j.browser.msie ) { |
2553 | | - return document.getElementById( this.pid ); |
2554 | | - } else { |
2555 | | - if ( document.embeds && document.embeds[this.pid] ) |
2556 | | - return document.embeds[this.pid]; |
2557 | | - } |
2558 | | - return null; |
2559 | | - }, |
2560 | | - setSliderValue: function( perc, hide_progress ) { |
| 2673 | + |
| 2674 | + /** |
| 2675 | + * Update the player playhead |
| 2676 | + * |
| 2677 | + * @param {Float} perc Value between 0 and 1 for position of playhead |
| 2678 | + */ |
| 2679 | + updatePlayHead: function( perc ) { |
2561 | 2680 | var eid = ( this.pc ) ? this.pc.pp.id:this.id; |
2562 | 2681 | if ( this.controls && $j( '#' + eid + ' .play_head' ).length != 0 ) { |
2563 | 2682 | var val = parseInt( perc * 1000 ); |
— | — | @@ -2565,11 +2684,17 @@ |
2566 | 2685 | // 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) ); |
2567 | 2686 | // js_log('op:' + offset_perc + ' *('+perc+' * ' + $j('#slider_'+id).width() + ')'); |
2568 | 2687 | }, |
| 2688 | + |
| 2689 | + /** |
| 2690 | + * Highligh a section of video on the playhead |
| 2691 | + * ~ probably could be moved to a seperate module ~ |
| 2692 | + * |
| 2693 | + * @param {Object} options Provides "start" time & "end" time to highlight |
| 2694 | + */ |
2569 | 2695 | highlightPlaySection:function( options ) { |
2570 | 2696 | js_log( 'highlightPlaySection' ); |
2571 | 2697 | var eid = ( this.pc ) ? this.pc.pp.id:this.id; |
2572 | 2698 | var dur = this.getDuration(); |
2573 | | - var hide_progress = true; |
2574 | 2699 | // set the left percet and update the slider: |
2575 | 2700 | rel_start_sec = npt2seconds( options['start'] ); |
2576 | 2701 | // remove the start_offset if relevent: |
— | — | @@ -2581,7 +2706,7 @@ |
2582 | 2707 | left_perc = 0; |
2583 | 2708 | options['start'] = seconds2npt( this.start_offset ); |
2584 | 2709 | rel_start_sec = 0; |
2585 | | - this.setSliderValue( 0 , hide_progress ); |
| 2710 | + this.updatePlayHead( 0 ); |
2586 | 2711 | } else { |
2587 | 2712 | left_perc = parseInt( ( rel_start_sec / dur ) * 100 ) ; |
2588 | 2713 | slider_perc = ( left_perc / 100 ); |
— | — | @@ -2589,7 +2714,7 @@ |
2590 | 2715 | |
2591 | 2716 | js_log( "slider perc:" + slider_perc ); |
2592 | 2717 | if ( ! this.isPlaying() ) { |
2593 | | - this.setSliderValue( slider_perc , hide_progress ); |
| 2718 | + this.updatePlayHead( slider_perc ); |
2594 | 2719 | } |
2595 | 2720 | |
2596 | 2721 | width_perc = parseInt( ( ( npt2seconds( options['end'] ) - npt2seconds( options['start'] ) ) / dur ) * 100 ) ; |
— | — | @@ -2609,26 +2734,48 @@ |
2610 | 2735 | js_log( 'DO update: ' + this.jump_time ); |
2611 | 2736 | this.updateThumbTime( rel_start_sec ); |
2612 | 2737 | }, |
| 2738 | + |
| 2739 | + /** |
| 2740 | + * Hides the playhead highlight |
| 2741 | + */ |
2613 | 2742 | hideHighlight:function() { |
2614 | 2743 | var eid = ( this.pc ) ? this.pc.pp.id:this.id; |
2615 | 2744 | $j( '#mv_seeker_' + eid + ' .mv_highlight' ).hide(); |
2616 | 2745 | this.setStatus( this.getTimeReq() ); |
2617 | 2746 | thigetTimeRangerValue( 0 ); |
2618 | 2747 | }, |
| 2748 | + |
| 2749 | + /** |
| 2750 | + * Updates the player status that displays short text msgs and the play clock |
| 2751 | + */ |
2619 | 2752 | setStatus:function( value ) { |
2620 | 2753 | var eid = ( this.pc ) ? this.pc.pp.id:this.id; |
2621 | 2754 | // update status: |
2622 | 2755 | $j( '#' + eid + ' .time-disp' ).html( value ); |
2623 | 2756 | }, |
| 2757 | + |
| 2758 | + |
| 2759 | + |
2624 | 2760 | /** |
2625 | 2761 | * Helper Functions for selected source |
2626 | 2762 | */ |
2627 | | - /* |
2628 | | - * returns the selected source url for players to play |
| 2763 | + |
| 2764 | + /** |
| 2765 | + * Gets the current selected media source |
| 2766 | + * |
| 2767 | + * @return src url |
2629 | 2768 | */ |
2630 | | - getURI : function( seek_time_sec ) { |
2631 | | - return this.media_element.selected_source.getURI( this.seek_time_sec ); |
| 2769 | + getSrc: function() { |
| 2770 | + return this.media_element.selected_source.getSrc( this.seek_time_sec ); |
2632 | 2771 | }, |
| 2772 | + |
| 2773 | + /** |
| 2774 | + * If the selected src supports URL time encoding |
| 2775 | + * |
| 2776 | + * @return {Boolean} |
| 2777 | + * ture if the src supports url time requests |
| 2778 | + * false if the src does not support url time requests |
| 2779 | + */ |
2633 | 2780 | supportsURLTimeEncoding: function() { |
2634 | 2781 | // do head request if on the same domain |
2635 | 2782 | return this.media_element.selected_source.URLTimeEncoding; |
— | — | @@ -2639,9 +2786,10 @@ |
2640 | 2787 | |
2641 | 2788 | /** |
2642 | 2789 | * mediaPlayer represents a media player plugin. |
| 2790 | + |
2643 | 2791 | * @param {String} id id used for the plugin. |
2644 | 2792 | * @param {Array<String>} supported_types n array of supported MIME types. |
2645 | | - * @param {String} library external script containing the plugin interface code. (mv_<library>Embed.js) |
| 2793 | + * @param {String} library external script containing the plugin interface code. |
2646 | 2794 | * @constructor |
2647 | 2795 | */ |
2648 | 2796 | function mediaPlayer( id, supported_types, library ) |
— | — | @@ -2653,62 +2801,88 @@ |
2654 | 2802 | this.loading_callbacks = new Array(); |
2655 | 2803 | return this; |
2656 | 2804 | } |
2657 | | -mediaPlayer.prototype = |
2658 | | -{ |
| 2805 | +mediaPlayer.prototype = { |
| 2806 | + // Id of the mediaPlayer |
2659 | 2807 | id:null, |
| 2808 | + |
| 2809 | + // Mime types supported by this player |
2660 | 2810 | supported_types:null, |
| 2811 | + |
| 2812 | + // Player library ie: native, vlc, java etc. |
2661 | 2813 | library:null, |
| 2814 | + |
| 2815 | + // Flag stores the mediaPlayer load state |
2662 | 2816 | loaded:false, |
2663 | | - loading_callbacks:null, |
2664 | | - supportsMIMEType: function( type ) |
2665 | | - { |
2666 | | - for ( var i = 0; i < this.supported_types.length; i++ ) |
| 2817 | + |
| 2818 | + /** |
| 2819 | + * Checks support for a given MIME type |
| 2820 | + * |
| 2821 | + * @param {String} type Mime type to check against supported_types |
| 2822 | + * @return {Boolean} |
| 2823 | + * true if mime type is supported |
| 2824 | + * false if mime type is unsupported |
| 2825 | + */ |
| 2826 | + supportsMIMEType: function( type ) { |
| 2827 | + for ( var i = 0; i < this.supported_types.length; i++ ){ |
2667 | 2828 | if ( this.supported_types[i] == type ) |
2668 | 2829 | return true; |
| 2830 | + } |
2669 | 2831 | return false; |
2670 | 2832 | }, |
2671 | | - getName: function() |
2672 | | - { |
| 2833 | + |
| 2834 | + /** |
| 2835 | + * Get the "name" of the player from a predictable msg key |
| 2836 | + */ |
| 2837 | + getName: function() { |
2673 | 2838 | return gM( 'mwe-ogg-player-' + this.id ); |
2674 | 2839 | }, |
| 2840 | + |
| 2841 | + /** |
| 2842 | + * Loads the player library and then calls the callback. |
| 2843 | + * |
| 2844 | + * @param {Function} callback Function to be called once player library is loaded. |
| 2845 | + */ |
2675 | 2846 | load: function( callback ) { |
2676 | | - debugger; |
2677 | 2847 | mw.load( [ |
2678 | 2848 | this.library + 'Embed' |
2679 | | - ], function() { |
2680 | | - var cat = nativeEmbed; |
| 2849 | + ], function() { |
2681 | 2850 | callback(); |
2682 | 2851 | } ); |
2683 | 2852 | } |
2684 | 2853 | } |
2685 | | -/* players and supported mime types |
2686 | | -@@note ideally we query the plugin to get what mime types it supports in practice not always reliable/avaliable |
| 2854 | + |
| 2855 | +/** |
| 2856 | +* players and supported mime types |
| 2857 | +* In an ideal world we would query the plugin to get what mime |
| 2858 | +* types it supports in practice not always reliable/avaliable |
2687 | 2859 | */ |
| 2860 | + |
| 2861 | +//Flash based players: |
2688 | 2862 | //var flowPlayer = new mediaPlayer( 'flowplayer', ['video/x-flv', 'video/h264'], 'flowplayer' ); |
2689 | 2863 | var kplayer = new mediaPlayer('kplayer', ['video/x-flv', 'video/h264'], 'kplayer'); |
2690 | | - |
2691 | 2864 | var omtkPlayer = new mediaPlayer( 'omtkplayer', ['audio/ogg'], 'omtk' ); |
2692 | 2865 | |
| 2866 | +//Java based player |
2693 | 2867 | var cortadoPlayer = new mediaPlayer( 'cortado', ['video/ogg', 'audio/ogg'], 'java' ); |
| 2868 | + |
| 2869 | +//Native html5 player |
2694 | 2870 | var videoElementPlayer = new mediaPlayer( 'videoElement', ['video/ogg', 'audio/ogg'], 'native' ); |
2695 | 2871 | |
| 2872 | +//VLC player |
2696 | 2873 | var vlcMineList = ['video/ogg', 'audio/ogg', 'video/x-flv', 'video/mp4', 'video/h264']; |
2697 | 2874 | var vlcPlayer = new mediaPlayer( 'vlc-player', vlcMineList, 'vlc' ); |
2698 | 2875 | |
2699 | | -// add generic |
| 2876 | +//Generic plugin |
2700 | 2877 | var oggPluginPlayer = new mediaPlayer( 'oggPlugin', ['video/ogg'], 'generic' ); |
2701 | 2878 | |
2702 | | -// depricate quicktime in favor of safari native |
2703 | | -// var quicktimeMozillaPlayer = new mediaPlayer('quicktime-mozilla',['video/ogg'],'quicktime'); |
2704 | | -// var quicktimeActiveXPlayer = new mediaPlayer('quicktime-activex',['video/ogg'],'quicktime'); |
2705 | | - |
| 2879 | +//HTML player for timed display of html contnet ( used in sequencer ) |
2706 | 2880 | var htmlPlayer = new mediaPlayer( 'html', ['text/html', 'image/jpeg', 'image/png', 'image/svg'], 'html' ); |
2707 | 2881 | |
| 2882 | + |
2708 | 2883 | /** |
2709 | | - * mediaPlayers is a collection of mediaPlayer objects supported by the client. |
2710 | | - * It could be merged with embedTypes, since there is one embedTypes per script |
2711 | | - * and one mediaPlayers per embedTypes. |
2712 | | - */ |
| 2884 | + * mediaPlayers is a collection of mediaPlayer objects supported by the client. |
| 2885 | + * @constructor |
| 2886 | + */ |
2713 | 2887 | function mediaPlayers() |
2714 | 2888 | { |
2715 | 2889 | this.init(); |
— | — | @@ -2716,9 +2890,19 @@ |
2717 | 2891 | |
2718 | 2892 | mediaPlayers.prototype = |
2719 | 2893 | { |
| 2894 | + // The list of players supported |
2720 | 2895 | players : null, |
| 2896 | + |
| 2897 | + // Store per mime-type prefrences for players |
2721 | 2898 | preference : null, |
| 2899 | + |
| 2900 | + // Stores the default set of players for a given mime type |
2722 | 2901 | default_players : { }, |
| 2902 | + |
| 2903 | + /** |
| 2904 | + * Initializartion function defiens the default order for players for |
| 2905 | + * a given mime type |
| 2906 | + */ |
2723 | 2907 | init : function() { |
2724 | 2908 | this.players = new Array(); |
2725 | 2909 | this.loadPreferences(); |
— | — | @@ -2738,30 +2922,31 @@ |
2739 | 2923 | this.default_players['image/svg'] = ['html']; |
2740 | 2924 | |
2741 | 2925 | }, |
2742 | | - addPlayer : function( player, mime_type ) { |
| 2926 | + |
| 2927 | + /** |
| 2928 | + * Adds a Player to the player list |
| 2929 | + * |
| 2930 | + * @param {Object} player Player object to be added |
| 2931 | + */ |
| 2932 | + addPlayer: function( player ) { |
2743 | 2933 | for ( var i = 0; i < this.players.length; i++ ) { |
2744 | 2934 | if ( this.players[i].id == player.id ) { |
2745 | | - if ( mime_type != null ) { |
2746 | | - // make sure the mime_type is not already there: |
2747 | | - var add_mime = true; |
2748 | | - for ( var j = 0; j < this.players[i].supported_types.length; j++ ) { |
2749 | | - if ( this.players[i].supported_types[j] == mime_type ) |
2750 | | - add_mime = false; |
2751 | | - } |
2752 | | - if ( add_mime ) |
2753 | | - this.players[i].supported_types.push( mime_type ); |
2754 | | - } |
| 2935 | + // Player already found |
2755 | 2936 | return ; |
2756 | 2937 | } |
2757 | 2938 | } |
2758 | | - // Player not found: |
2759 | | - if ( mime_type != null ) |
2760 | | - player.supported_types.push( mime_type ); |
2761 | | - |
2762 | | - js_log( 'Adding ' + player.id + ' with mime_type ' + mime_type ); |
| 2939 | + // Add the player: |
2763 | 2940 | this.players.push( player ); |
2764 | 2941 | }, |
2765 | | - getMIMETypePlayers : function( mime_type ) { |
| 2942 | + |
| 2943 | + /** |
| 2944 | + * get players that support a given mime_type |
| 2945 | + * |
| 2946 | + * @param {String} mime_type Mime type of player set |
| 2947 | + * @return {Array} |
| 2948 | + * Array of players that support a the requested mime type |
| 2949 | + */ |
| 2950 | + getMIMETypePlayers: function( mime_type ) { |
2766 | 2951 | var mime_players = new Array(); |
2767 | 2952 | var _this = this; |
2768 | 2953 | var inx = 0; |
— | — | @@ -2778,6 +2963,15 @@ |
2779 | 2964 | } |
2780 | 2965 | return mime_players; |
2781 | 2966 | }, |
| 2967 | + |
| 2968 | + /** |
| 2969 | + * Default player for a given mime type |
| 2970 | + * |
| 2971 | + * @param {String} mime_type Mime type of the requested player |
| 2972 | + * @return |
| 2973 | + * Player for mime type |
| 2974 | + * null if no player found |
| 2975 | + */ |
2782 | 2976 | defaultPlayer : function( mime_type ) { |
2783 | 2977 | js_log( "get defaultPlayer for " + mime_type ); |
2784 | 2978 | var mime_players = this.getMIMETypePlayers( mime_type ); |
— | — | @@ -2795,11 +2989,24 @@ |
2796 | 2990 | js_log( 'No default player found for ' + mime_type ); |
2797 | 2991 | return null; |
2798 | 2992 | }, |
2799 | | - userSelectFormat : function ( mime_format ) { |
2800 | | - this.preference['format_prefrence'] = mime_format; |
| 2993 | + |
| 2994 | + /** |
| 2995 | + * Sets the format preference. |
| 2996 | + * |
| 2997 | + * @param {String} mime_format Prefered format |
| 2998 | + */ |
| 2999 | + setFormatPreference : function ( mime_format ) { |
| 3000 | + this.preference['format_preference'] = mime_format; |
2801 | 3001 | this.savePreferences(); |
2802 | 3002 | }, |
2803 | | - userSelectPlayer : function( player_id, mime_type ) { |
| 3003 | + |
| 3004 | + /** |
| 3005 | + * Sets the player preference |
| 3006 | + * |
| 3007 | + * @param {String} player_id Prefered player id |
| 3008 | + * @param {String} mime_type Mime type for the associated player stream |
| 3009 | + */ |
| 3010 | + setPlayerPreference : function( player_id, mime_type ) { |
2804 | 3011 | var selected_player = null; |
2805 | 3012 | for ( var i = 0; i < this.players.length; i++ ) { |
2806 | 3013 | if ( this.players[i].id == player_id ) { |
— | — | @@ -2821,8 +3028,11 @@ |
2822 | 3029 | } |
2823 | 3030 | } |
2824 | 3031 | }, |
2825 | | - loadPreferences : function() |
2826 | | - { |
| 3032 | + |
| 3033 | + /** |
| 3034 | + * Loads the user preference settings from a cookie |
| 3035 | + */ |
| 3036 | + loadPreferences : function ( ) { |
2827 | 3037 | this.preference = new Object(); |
2828 | 3038 | // see if we have a cookie set to a clientSupported type: |
2829 | 3039 | var cookieVal = $j.cookie( 'ogg_player_exp' ); |
— | — | @@ -2836,6 +3046,10 @@ |
2837 | 3047 | } |
2838 | 3048 | } |
2839 | 3049 | }, |
| 3050 | + |
| 3051 | + /** |
| 3052 | + * Saves the user preference settings to a cookie |
| 3053 | + */ |
2840 | 3054 | savePreferences : function() { |
2841 | 3055 | var cookieVal = ''; |
2842 | 3056 | for ( var i in this.preference ) |
— | — | @@ -2847,21 +3061,34 @@ |
2848 | 3062 | } |
2849 | 3063 | }; |
2850 | 3064 | |
2851 | | -/* |
| 3065 | +/** |
2852 | 3066 | * embedTypes object handles setting and getting of supported embed types: |
2853 | 3067 | * closely mirrors OggHandler so that its easier to share efforts in this area: |
2854 | 3068 | * http://svn.wikimedia.org/viewvc/mediawiki/trunk/extensions/OggHandler/OggPlayer.js |
2855 | 3069 | */ |
2856 | 3070 | var embedTypes = { |
2857 | | - // List of players |
| 3071 | + |
| 3072 | + // List of players supported |
2858 | 3073 | players: null, |
| 3074 | + |
| 3075 | + // Detect flag for completion |
2859 | 3076 | detect_done:false, |
| 3077 | + |
| 3078 | + /** |
| 3079 | + * Runs the detect method and update the detect_done flag |
| 3080 | + * @constructor |
| 3081 | + */ |
2860 | 3082 | init: function() { |
2861 | 3083 | // detect supported types |
2862 | 3084 | this.detect(); |
2863 | 3085 | this.detect_done = true; |
2864 | 3086 | }, |
2865 | | - clientSupports: { 'thumbnail' : true }, |
| 3087 | + |
| 3088 | + /** |
| 3089 | + * If the browsers supports a given mimetype |
| 3090 | + * |
| 3091 | + * @param {String} mimetype Mime type for browser plug-in check |
| 3092 | + */ |
2866 | 3093 | supportedMimeType: function( mimetype ) { |
2867 | 3094 | for ( var i = navigator.plugins.length; i-- > 0; ) { |
2868 | 3095 | var plugin = navigator.plugins[i]; |
— | — | @@ -2870,8 +3097,11 @@ |
2871 | 3098 | } |
2872 | 3099 | return false; |
2873 | 3100 | }, |
2874 | | - |
2875 | | - detect: function() { |
| 3101 | + |
| 3102 | + /** |
| 3103 | + * Detects what plug-ins the client supports |
| 3104 | + */ |
| 3105 | + detect: function() { |
2876 | 3106 | js_log( "running detect" ); |
2877 | 3107 | this.players = new mediaPlayers(); |
2878 | 3108 | // every browser supports html rendering: |
— | — | @@ -2962,7 +3192,7 @@ |
2963 | 3193 | pluginName = ''; |
2964 | 3194 | } |
2965 | 3195 | if ( pluginName.toLowerCase() == 'vlc multimedia plugin' || pluginName.toLowerCase() == 'vlc multimedia plug-in' ) { |
2966 | | - this.players.addPlayer( vlcPlayer, type ); |
| 3196 | + this.players.addPlayer( vlcPlayer ); |
2967 | 3197 | continue; |
2968 | 3198 | } |
2969 | 3199 | |
— | — | @@ -2973,7 +3203,7 @@ |
2974 | 3204 | |
2975 | 3205 | if ( type == 'application/ogg' ) { |
2976 | 3206 | if ( pluginName.toLowerCase() == 'vlc multimedia plugin' ) { |
2977 | | - this.players.addPlayer( vlcMozillaPlayer, type ); |
| 3207 | + this.players.addPlayer( vlcMozillaPlayer ); |
2978 | 3208 | // else if ( pluginName.indexOf( 'QuickTime' ) > -1 ) |
2979 | 3209 | // this.players.addPlayer(quicktimeMozillaPlayer); |
2980 | 3210 | } else { |
— | — | @@ -2982,7 +3212,7 @@ |
2983 | 3213 | continue; |
2984 | 3214 | } else if ( uniqueMimesOnly ) { |
2985 | 3215 | if ( type == 'application/x-vlc-player' ) { |
2986 | | - this.players.addPlayer( vlcMozillaPlayer, type ); |
| 3216 | + this.players.addPlayer( vlcMozillaPlayer ); |
2987 | 3217 | continue; |
2988 | 3218 | } else if ( type == 'video/quicktime' ) { |
2989 | 3219 | // this.players.addPlayer(quicktimeMozillaPlayer); |
— | — | @@ -2990,10 +3220,6 @@ |
2991 | 3221 | } |
2992 | 3222 | } |
2993 | 3223 | |
2994 | | - /*if ( type == 'video/quicktime' ) { |
2995 | | - this.players.addPlayer(vlcMozillaPlayer, type); |
2996 | | - continue; |
2997 | | - }*/ |
2998 | 3224 | if ( type == 'application/x-shockwave-flash' ) { |
2999 | 3225 | |
3000 | 3226 | this.players.addPlayer( kplayer ); |
— | — | @@ -3011,12 +3237,14 @@ |
3012 | 3238 | continue; |
3013 | 3239 | } |
3014 | 3240 | } |
3015 | | - } |
3016 | | - // @@The xiph quicktime component does not work well with annodex streams (temporarly disable) |
3017 | | - // this.clientSupports['quicktime-mozilla'] = false; |
3018 | | - // this.clientSupports['quicktime-activex'] = false; |
3019 | | - // js_log(this.clientSupports); |
| 3241 | + } |
3020 | 3242 | }, |
| 3243 | + |
| 3244 | + /** |
| 3245 | + * Test IE for activeX by name |
| 3246 | + * |
| 3247 | + * @param {String} name Name of ActiveXObject to look for |
| 3248 | + */ |
3021 | 3249 | testActiveX : function ( name ) { |
3022 | 3250 | var hasObj = true; |
3023 | 3251 | try { |
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/genericEmbed.js |
— | — | @@ -1,6 +1,9 @@ |
2 | | -/* the most simple implementation used for unknown application/ogg plugin */ |
| 2 | +/* |
| 3 | +* Simple embed object for unknown application/ogg plugin |
| 4 | +*/ |
3 | 5 | var genericEmbed = { |
4 | | - supports: { |
| 6 | + // List of supported features of the generic plugin |
| 7 | + supports: { |
5 | 8 | 'play_head':false, |
6 | 9 | 'pause':false, |
7 | 10 | 'stop':true, |
— | — | @@ -8,10 +11,17 @@ |
9 | 12 | 'time_display':false, |
10 | 13 | 'volume_control':false |
11 | 14 | }, |
| 15 | + // Instance name: |
12 | 16 | instanceOf:'genericEmbed', |
| 17 | + /* |
| 18 | + * Generic embed html |
| 19 | + * |
| 20 | + * @return {String} |
| 21 | + * embed code for genneric ogg plugin |
| 22 | + */ |
13 | 23 | getEmbedHTML:function() { |
14 | 24 | return '<object type="application/ogg" ' + |
15 | 25 | 'width="' + this.width + '" height="' + this.height + '" ' + |
16 | | - 'data="' + this.getURI( this.seek_time_sec ) + '"></object>'; |
| 26 | + 'data="' + this.getSrc( this.seek_time_sec ) + '"></object>'; |
17 | 27 | } |
18 | 28 | }; |
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/javaEmbed.js |
— | — | @@ -1,3 +1,6 @@ |
| 2 | +/* |
| 3 | +* List of domains and hosted location of cortado. Lets clients avoid the security warning for cross domain cortado |
| 4 | +*/ |
2 | 5 | window.cortadoDomainLocations = { |
3 | 6 | 'upload.wikimedia.org' : 'http://upload.wikimedia.org/jars/cortado.jar', |
4 | 7 | 'tinyvid.tv' : 'http://tinyvid.tv/static/cortado.jar', |
— | — | @@ -5,9 +8,11 @@ |
6 | 9 | } |
7 | 10 | |
8 | 11 | var javaEmbed = { |
| 12 | + |
| 13 | + // instance name: |
9 | 14 | instanceOf:'javaEmbed', |
10 | | - iframe_src:'', |
11 | | - logged_domain_error:false, |
| 15 | + |
| 16 | + // Supported feature set of the cortado applet: |
12 | 17 | supports: { |
13 | 18 | 'play_head':true, |
14 | 19 | 'pause':true, |
— | — | @@ -16,15 +21,23 @@ |
17 | 22 | 'time_display':true, |
18 | 23 | 'volume_control':false |
19 | 24 | }, |
20 | | - getEmbedHTML : function () { |
| 25 | + |
| 26 | + /** |
| 27 | + * Wraps the embed object html output: |
| 28 | + */ |
| 29 | + getEmbedHTML: function () { |
21 | 30 | // big delay on embed html cuz its just for status updates and ie6 is crazy. |
22 | 31 | if ( this.controls ) |
23 | 32 | setTimeout( 'document.getElementById(\'' + this.id + '\').postEmbedJS()', 500 ); |
24 | 33 | // set a default duration of 30 seconds: cortao should detect duration. |
25 | 34 | return this.wrapEmebedContainer( this.getEmbedObj() ); |
26 | 35 | }, |
27 | | - getEmbedObj:function() { |
28 | | - js_log( "java play url:" + this.getURI( this.seek_time_sec ) ); |
| 36 | + |
| 37 | + /** |
| 38 | + * Gets the embed html code: |
| 39 | + */ |
| 40 | + getEmbedObj: function() { |
| 41 | + js_log( "java play url:" + this.getSrc( this.seek_time_sec ) ); |
29 | 42 | // get the duration |
30 | 43 | this.getDuration(); |
31 | 44 | // if still unset set to an arbitrary time 60 seconds: |
— | — | @@ -77,22 +90,28 @@ |
78 | 91 | return appplet_code; |
79 | 92 | } |
80 | 93 | }, |
81 | | - postEmbedJS:function() { |
82 | | - // reset logged domain error flag: |
83 | | - this.logged_domain_error = false; |
| 94 | + |
| 95 | + /** |
| 96 | + * Once the applet has been embed start monitoring playback |
| 97 | + */ |
| 98 | + postEmbedJS:function() { |
84 | 99 | // start monitor: |
85 | 100 | this.monitor(); |
86 | 101 | }, |
| 102 | + |
| 103 | + /** |
| 104 | + * Monitor applet playback, and update currentTime |
| 105 | + */ |
87 | 106 | monitor:function() { |
88 | | - this.getJCE(); |
| 107 | + this.getPlayerElement(); |
89 | 108 | if ( this.isPlaying() ) { |
90 | | - if ( this.jce && this.jce.getPlayPosition ) { |
| 109 | + if ( this.playerElement && this.playerElement.getPlayPosition ) { |
91 | 110 | try { |
92 | 111 | // 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() ); |
| 112 | + // js_log(' ct: ' + this.playerElement.getPlayPosition() + ' ' + this.supportsURLTimeEncoding()); |
| 113 | + this.currentTime = this.playerElement.getPlayPosition(); |
| 114 | + if ( this.playerElement.getPlayPosition() < 0 ) { |
| 115 | + js_log( 'pp:' + this.playerElement.getPlayPosition() ); |
97 | 116 | // probably reached clip end |
98 | 117 | this.onClipDone(); |
99 | 118 | } |
— | — | @@ -104,35 +123,43 @@ |
105 | 124 | // once currentTime is updated call parent_monitor |
106 | 125 | this.parent_monitor(); |
107 | 126 | }, |
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(); |
| 127 | + |
| 128 | + /** |
| 129 | + * Seek in the ogg stream |
| 130 | + * (Cortado seek does not seem to work very well) |
| 131 | + * @param {Float} percentage Percentage to seek into the stream |
| 132 | + */ |
| 133 | + doSeek:function( percentage ) { |
| 134 | + js_log( 'java:seek:p: ' + percentage + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec ); |
| 135 | + this.getPlayerElement(); |
114 | 136 | |
115 | 137 | 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() ) ); |
| 138 | + this.parent_doSeek( percentage ); |
| 139 | + // this.seek_time_sec = npt2seconds( this.start_ntp ) + parseFloat( percentage * this.getDuration() ); |
| 140 | + // this.playerElement.setParam('url', this.getSrc( this.seek_time_sec )) |
| 141 | + // this.playerElement.restart(); |
| 142 | + } else if ( this.playerElement ) { |
| 143 | + // do a (generally broken) local seek: |
| 144 | + js_log( "cortado javascript seems to always fail ... but here we go... doSeek(" + ( percentage * parseFloat( this.getDuration() ) ) ); |
| 145 | + this.playerElement.doSeek( percentage * parseFloat( this.getDuration() ) ); |
124 | 146 | } else { |
125 | | - this.doPlayThenSeek( perc ); |
| 147 | + this.doPlayThenSeek( percentage ); |
126 | 148 | } |
127 | 149 | }, |
128 | | - doPlayThenSeek:function( perc ) { |
129 | | - js_log( 'doPlayThenSeek Hack' ); |
| 150 | + |
| 151 | + /** |
| 152 | + * Issue a play request then seek to a percentage point in the stream |
| 153 | + * @param {Float} percentage Percentage to seek into the stream |
| 154 | + */ |
| 155 | + doPlayThenSeek: function( percentage ) { |
| 156 | + js_log( 'doPlayThenSeek' ); |
130 | 157 | var _this = this; |
131 | 158 | this.play(); |
132 | 159 | var rfsCount = 0; |
133 | 160 | var readyForSeek = function() { |
134 | | - _this.getJCE(); |
| 161 | + _this.getPlayerElement(); |
135 | 162 | // if we have .jre ~in theory~ we can seek (but probably not) |
136 | | - if ( _this.jce ) { |
| 163 | + if ( _this.playerElement ) { |
137 | 164 | _this.doSeek( perc ); |
138 | 165 | } else { |
139 | 166 | // try to get player for 10 seconds: |
— | — | @@ -146,32 +173,49 @@ |
147 | 174 | } |
148 | 175 | readyForSeek(); |
149 | 176 | }, |
150 | | - // get java cortado embed object |
151 | | - getJCE:function() { |
| 177 | + |
| 178 | + /** |
| 179 | + * Update the playerElement instance with a pointer to the embed object |
| 180 | + */ |
| 181 | + getPlayerElement:function() { |
152 | 182 | if ( embedTypes.mozilla ) { |
153 | | - this.jce = window.frames['cframe_' + this.id ].document.getElementById( this.pid ); |
| 183 | + this.playerElement = window.frames['cframe_' + this.id ].document.getElementById( this.pid ); |
154 | 184 | } else { |
155 | | - this.jce = $j( '#' + this.pid ).get( 0 ); |
| 185 | + this.playerElement = $j( '#' + this.pid ).get( 0 ); |
156 | 186 | } |
157 | 187 | }, |
158 | | - doThumbnailHTML:function() { |
| 188 | + |
| 189 | + /** |
| 190 | + * Show the Thumbnail |
| 191 | + */ |
| 192 | + showThumbnail:function() { |
159 | 193 | // empty out player html (jquery with java applets does mix) : |
160 | 194 | var pelm = document.getElementById( 'dc_' + this.id ); |
161 | 195 | if ( pelm ) { |
162 | 196 | pelm.innerHTML = ''; |
163 | 197 | } |
164 | | - this.parent_doThumbnailHTML(); |
| 198 | + this.parent_showThumbnail(); |
165 | 199 | }, |
| 200 | + |
| 201 | + /** |
| 202 | + * Issue the doPlay request to the playerElement |
| 203 | + * calls parent_play to update interface |
| 204 | + */ |
166 | 205 | play:function() { |
167 | | - this.getJCE(); |
| 206 | + this.getPlayerElement(); |
168 | 207 | this.parent_play(); |
169 | | - if ( this.jce ) |
170 | | - this.jce.doPlay(); |
| 208 | + if ( this.playerElement ) |
| 209 | + this.playerElement.doPlay(); |
171 | 210 | }, |
| 211 | + |
| 212 | + /** |
| 213 | + * Pause playback |
| 214 | + * calls parent_pause to update interface |
| 215 | + */ |
172 | 216 | pause:function() { |
173 | | - this.getJCE(); |
| 217 | + this.getPlayerElement(); |
174 | 218 | this.parent_pause(); |
175 | | - if ( this.jce ) |
176 | | - this.jce.doPause(); |
| 219 | + if ( this.playerElement ) |
| 220 | + this.playerElement.doPause(); |
177 | 221 | } |
178 | 222 | }; |
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/flowplayerEmbed.js |
— | — | @@ -1,6 +1,6 @@ |
2 | 2 | /** |
3 | | - * metavid: mv_flashEmbed builds off of flowplayer api (included first in this file) |
4 | | - * THIS WILL BE DEPRECIATED SOON |
| 3 | + * Builds off of flowplayer api (included first in this file) |
| 4 | + * THIS WILL BE DEPRECIATED SOON AS WE KNOW USE "kplayer" for our flash fallback support |
5 | 5 | */ |
6 | 6 | |
7 | 7 | /** |
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/htmlEmbed.js |
— | — | @@ -1,13 +1,14 @@ |
2 | 2 | /* |
3 | | - * used to embed HTML as a movie clip |
| 3 | + * Used to embed HTML as a movie clip |
4 | 4 | * for use with mv_playlist SMIL additions |
5 | | - * (we make assumptions about this.pc (parent clip) being available) |
6 | 5 | */ |
7 | 6 | var pcHtmlEmbedDefaults = { |
8 | 7 | 'dur':4 // default duration of 4 seconds |
9 | 8 | } |
10 | 9 | |
11 | 10 | var htmlEmbed = { |
| 11 | + |
| 12 | + // List of supported features |
12 | 13 | supports: { |
13 | 14 | 'play_head':true, |
14 | 15 | 'pause':true, |
— | — | @@ -16,13 +17,29 @@ |
17 | 18 | 'volume_control':true, |
18 | 19 | |
19 | 20 | 'overlays':true, |
20 | | - 'playlist_swap_loader':true // if the object supports playlist functions |
| 21 | + |
| 22 | + // if the object supports playlist functions |
| 23 | + 'playlist_swap_loader':true |
21 | 24 | }, |
| 25 | + |
| 26 | + // If the player is "ready to play" |
22 | 27 | ready_to_play:true, |
| 28 | + |
| 29 | + // Pause time used to track player time between pauses |
23 | 30 | pauseTime:0, |
| 31 | + |
| 32 | + // currentTime updated via internal clockStartTime var |
24 | 33 | currentTime:0, |
| 34 | + |
| 35 | + // StartOffset support seeking into the virtual player |
25 | 36 | start_offset:0, |
26 | | - monitorTimerId:false, |
| 37 | + |
| 38 | + // The local clock used to emulate playback time |
| 39 | + clockStartTime: 0 |
| 40 | + |
| 41 | + /** |
| 42 | + * Play function starts the v |
| 43 | + */ |
27 | 44 | play:function() { |
28 | 45 | // call the parent |
29 | 46 | this.parent_play(); |
— | — | @@ -34,11 +51,18 @@ |
35 | 52 | // Start up monitor: |
36 | 53 | this.monitor(); |
37 | 54 | }, |
| 55 | + |
| 56 | + /** |
| 57 | + * Stops the playback |
| 58 | + */ |
38 | 59 | stop:function() { |
39 | 60 | this.currentTime = 0; |
40 | | - this.pause(); |
41 | | - // window.clearInterval( this.monitorTimerId ); |
| 61 | + this.pause(); |
42 | 62 | }, |
| 63 | + |
| 64 | + /** |
| 65 | + * Preserves the pause time across for timed playback |
| 66 | + */ |
43 | 67 | pause:function() { |
44 | 68 | js_log( 'f:pause: htmlEmbedWrapper' ); |
45 | 69 | var ct = new Date(); |
— | — | @@ -47,16 +71,32 @@ |
48 | 72 | |
49 | 73 | window.clearInterval( this.monitorTimerId ); |
50 | 74 | }, |
| 75 | + |
| 76 | + /** |
| 77 | + * Seeks to a given percent and updates the pauseTime |
| 78 | + * |
| 79 | + * @param {Float} perc Pecentage to seek into the virtual player |
| 80 | + */ |
51 | 81 | doSeek:function( perc ){ |
52 | 82 | this.pauseTime = perc * this.getDuration(); |
53 | 83 | this.play(); |
54 | 84 | }, |
| 85 | + |
| 86 | + /** |
| 87 | + * Sets the current Time |
| 88 | + * |
| 89 | + * @param {Float} perc Pecentage to seek into the virtual player |
| 90 | + * @param {Function} callback Function called once time has been updated |
| 91 | + */ |
55 | 92 | setCurrentTime:function( perc, callback ){ |
56 | 93 | this.pauseTime = perc * this.getDuration(); |
57 | 94 | if( callback ) |
58 | 95 | callback(); |
59 | 96 | }, |
60 | | - // Monitor just needs to keep track of time |
| 97 | + |
| 98 | + /** |
| 99 | + * Monitor tracks of virtual player time |
| 100 | + */ |
61 | 101 | monitor:function() { |
62 | 102 | //js_log('html:monitor: '+ this.currentTime); |
63 | 103 | var ct = new Date(); |
— | — | @@ -67,7 +107,10 @@ |
68 | 108 | // Once currentTime is updated call parent_monitor |
69 | 109 | this.parent_monitor(); |
70 | 110 | }, |
71 | | - // set up minimal media_element emulation: |
| 111 | + |
| 112 | + /** |
| 113 | + * Minimal media_element emulation: |
| 114 | + */ |
72 | 115 | media_element: { |
73 | 116 | autoSelectSource:function() { |
74 | 117 | return true; |
— | — | @@ -82,9 +125,19 @@ |
83 | 126 | return false; |
84 | 127 | } |
85 | 128 | }, |
86 | | - inheritEmbedPlayer:function() { |
| 129 | + |
| 130 | + /** |
| 131 | + * HtmlEmbed supports virtual instances without inheriting the embedPlayer |
| 132 | + */ |
| 133 | + inheritEmbedPlayer: function() { |
87 | 134 | return true; |
88 | 135 | }, |
| 136 | + |
| 137 | + /** |
| 138 | + * Render out a Thumbnail representation for use in the sequencer |
| 139 | + * |
| 140 | + * @param {Object} options Thumbnail options |
| 141 | + */ |
89 | 142 | renderTimelineThumbnail:function( options ) { |
90 | 143 | js_log( "HTMLembed req w, height: " + options.width + ' ' + options.height ); |
91 | 144 | // generate a scaled down version _that_ we can clone if nessisary |
— | — | @@ -93,10 +146,13 @@ |
94 | 147 | |
95 | 148 | var thumb_render_id = this.id + '_thumb_render_' + options.height; |
96 | 149 | if ( $j( '#' + thumb_render_id ).length == 0 || do_refresh ) { |
97 | | - // set the font scale down percentage: (kind of arbitrary) |
| 150 | + |
| 151 | + // Set the font scale down percentage: (kind of arbitrary) |
98 | 152 | var scale_perc = options.width / this.pc.pp.width; |
| 153 | + |
99 | 154 | js_log( 'scale_perc:' + options.width + ' / ' + $j( this ).width() + ' = ' + scale_perc ); |
100 | | - // min scale font percent of 70 (overflow is hidden) |
| 155 | + |
| 156 | + // Min scale font percent of 70 (overflow is hidden) |
101 | 157 | var font_perc = ( Math.round( scale_perc * 100 ) < 80 ) ? 80 : Math.round( scale_perc * 100 ); |
102 | 158 | var thumb_class = ( typeof options['thumb_class'] != 'undefined' ) ? options['thumb_class'] : ''; |
103 | 159 | $j( 'body' ).append( '<div id="' + thumb_render_id + '" style="display:none">' + |
— | — | @@ -109,15 +165,16 @@ |
110 | 166 | '</div>' + |
111 | 167 | '</div>' |
112 | 168 | ); |
113 | | - // scale down the fonts: |
| 169 | + |
| 170 | + // Scale down the fonts: |
114 | 171 | $j( '#' + thumb_render_id + ' *' ).filter( 'span,div,p,h,h1,h2,h3,h4,h5,h6' ).css( 'font-size', font_perc + '%' ) |
115 | 172 | |
116 | | - // replace out links: |
| 173 | + // Replace out links: |
117 | 174 | $j( '#' + thumb_render_id + ' a' ).each( function() { |
118 | 175 | $j( this ).replaceWith( "<span>" + $j( this ).html() + "</span>" ); |
119 | 176 | } ); |
120 | 177 | |
121 | | - // scale images that have width or height: |
| 178 | + // Scale images that have width or height: |
122 | 179 | $j( '#' + thumb_render_id + ' img' ).filter( '[width]' ).each( function() { |
123 | 180 | $j( this ).attr( { |
124 | 181 | 'width': Math.round( $j( this ).attr( 'width' ) * scale_perc ), |
— | — | @@ -128,11 +185,17 @@ |
129 | 186 | } |
130 | 187 | return $j( '#' + thumb_render_id ).html(); |
131 | 188 | }, |
132 | | - // nothing to update in static html display: (return a static representation) |
133 | | - // @@todo render out a mini text "preview" |
| 189 | + /* |
| 190 | + * updates the ThumbTime |
| 191 | + * (does nothings since we display a single renderd html page) |
| 192 | + */ |
134 | 193 | updateThumbTime:function( float_time ) { |
135 | 194 | return ; |
136 | 195 | }, |
| 196 | + |
| 197 | + /** |
| 198 | + * gets the "embed" html for the html player |
| 199 | + */ |
137 | 200 | getEmbedHTML:function() { |
138 | 201 | js_log( 'f:html:getEmbedHTML: ' + this.id ); |
139 | 202 | // set up the css for our parent div: |
— | — | @@ -146,6 +209,11 @@ |
147 | 210 | // wrap output in videoPlayer_ div: |
148 | 211 | $j( this ).html( '<div id="videoPlayer_' + this.id + '">' + this.getThumbnailHTML() + '</div>' ); |
149 | 212 | }, |
| 213 | + |
| 214 | + /** |
| 215 | + * gets the ThumbnailHTML |
| 216 | + * ThumbnailHTML is used for both the "paused and playing states of the htmlEmbed player |
| 217 | + */ |
150 | 218 | getThumbnailHTML:function( opt ) { |
151 | 219 | var out = ''; |
152 | 220 | if ( !opt ) |
— | — | @@ -162,15 +230,26 @@ |
163 | 231 | // js_log('f:getThumbnailHTML: got thumb: '+out); |
164 | 232 | return out; |
165 | 233 | }, |
166 | | - doThumbnailHTML:function() { |
167 | | - js_log( 'htmlEmbed:doThumbnailHTML()' ); |
| 234 | + |
| 235 | + /** |
| 236 | + * re-show the Thumbnail |
| 237 | + */ |
| 238 | + showThumbnail:function() { |
| 239 | + js_log( 'htmlEmbed:showThumbnail()' ); |
168 | 240 | this.getEmbedHTML(); |
169 | 241 | }, |
170 | | - /* since its just html display get the "embed" right away */ |
| 242 | + |
| 243 | + /** |
| 244 | + * Display the "embed" html right away |
| 245 | + */ |
171 | 246 | getHTML:function() { |
172 | 247 | js_log( 'htmlEmbed::getHTML() ' + this.id ); |
173 | 248 | this.getEmbedHTML(); |
174 | 249 | }, |
| 250 | + |
| 251 | + /** |
| 252 | + * Gets the media duration |
| 253 | + */ |
175 | 254 | getDuration:function() { |
176 | 255 | if( !this.duration ){ |
177 | 256 | if( this.pc.dur ){ |
— | — | @@ -181,13 +260,21 @@ |
182 | 261 | } |
183 | 262 | return this.parent_getDuration(); |
184 | 263 | }, |
185 | | - updateVideoTime:function( start_ntp, end_ntp ) { |
| 264 | + |
| 265 | + /** |
| 266 | + * Updates the Video time |
| 267 | + * @param {String} start_npt Start time for update |
| 268 | + * @param {String} end_npt End time for update |
| 269 | + */ |
| 270 | + updateVideoTime:function( start_npt, end_npt ) { |
186 | 271 | // since we don't really have timeline for html elements just take the delta and set it as the duration |
187 | 272 | this.pc.dur = npt2seconds( end_ntp ) - npt2seconds( start_ntp ); |
188 | 273 | }, |
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() { |
| 274 | + |
| 275 | + /** |
| 276 | + * Local implementation of swapPlayerElement |
| 277 | + */ |
| 278 | + swapPlayerElement:function() { |
192 | 279 | this.loading_external_data = false |
193 | 280 | this.ready_to_play = true; |
194 | 281 | return ; |
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/vlcEmbed.js |
— | — | @@ -292,6 +292,6 @@ |
293 | 293 | }, |
294 | 294 | // get the embed vlc object |
295 | 295 | getVLC : function() { |
296 | | - this.vlc = this.getPluginEmbed(); |
| 296 | + this.vlc = $j('#' + this.pid ).get(0); |
297 | 297 | } |
298 | 298 | }; |
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/nativeEmbed.js |
— | — | @@ -5,13 +5,28 @@ |
6 | 6 | * Enables embedPlayer support for native html5 browser playback system |
7 | 7 | */ |
8 | 8 | var nativeEmbed = { |
| 9 | + |
| 10 | + //Instance Name |
9 | 11 | instanceOf:'nativeEmbed', |
10 | | - canPlayThrough:false, |
| 12 | + |
| 13 | + // Counts the number of times we tried to access the video element |
11 | 14 | grab_try_count:0, |
| 15 | + |
| 16 | + // Flag to only load the video ( not play it ) |
12 | 17 | onlyLoadFlag:false, |
13 | | - onLoadedCallback : new Array(), |
| 18 | + |
| 19 | + //Callback fired once video is "loaded" |
| 20 | + onLoadedCallback: null, |
| 21 | + |
| 22 | + //For retrying a player embed with a distinct url |
| 23 | + // NOTE: this bug workaround may no longer be applicable |
14 | 24 | urlAppend:'', |
| 25 | + |
| 26 | + // The previus "currentTime" to snif seek actions |
| 27 | + // NOTE the bug where onSeeked does not seem fire consistently may no longer be applicable |
15 | 28 | prevCurrentTime: -1, |
| 29 | + |
| 30 | + // Native player supported feature set |
16 | 31 | supports: { |
17 | 32 | 'play_head':true, |
18 | 33 | 'pause':true, |
— | — | @@ -21,15 +36,22 @@ |
22 | 37 | |
23 | 38 | 'overlays':true, |
24 | 39 | 'playlist_swap_loader':true // if the object supports playlist functions |
25 | | - }, |
| 40 | + }, |
| 41 | + /** |
| 42 | + * Wraps the embed object and returns the output |
| 43 | + */ |
26 | 44 | getEmbedHTML : function () { |
27 | 45 | var embed_code = this.getEmbedObj(); |
28 | 46 | js_log( "embed code: " + embed_code ) |
29 | 47 | setTimeout( '$j(\'#' + this.id + '\').get(0).postEmbedJS()', 150 ); |
30 | 48 | return this.wrapEmebedContainer( embed_code ); |
31 | 49 | }, |
| 50 | + |
| 51 | + /** |
| 52 | + * Get the native embeed code |
| 53 | + */ |
32 | 54 | getEmbedObj:function() { |
33 | | - // we want to let mwEmbed handle the controls so notice the absence of control attribute |
| 55 | + // We want to let mwEmbed handle the controls so notice the absence of control attribute |
34 | 56 | // controls=false results in controls being displayed: |
35 | 57 | // http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2008-August/016159.html |
36 | 58 | js_log( "native play url:" + this.getSrc() + ' start_offset: ' + this.start_ntp + ' end: ' + this.end_ntp ); |
— | — | @@ -37,96 +59,113 @@ |
38 | 60 | 'id="' + this.pid + '" ' + |
39 | 61 | 'style="width:' + this.width + 'px;height:' + this.height + 'px;" ' + |
40 | 62 | 'width="' + this.width + '" height="' + this.height + '" ' + |
41 | | - 'src="' + this.getSrc() + '" '; |
42 | | - |
43 | | - /*if(!this.onlyLoadFlag) |
44 | | - eb+='autoplay="true" ';*/ |
45 | | - |
46 | | - // continue with the other attr: |
47 | | - // NOTE: could be binded in "post embed js" |
48 | | - eb += 'oncanplaythrough="$j(\'#' + this.id + '\').get(0).oncanplaythrough();return false;" ' + |
49 | | - 'onloadedmetadata="$j(\'#' + this.id + '\').get(0).onloadedmetadata();return false;" ' + |
50 | | - 'loadedmetadata="$j(\'#' + this.id + '\').get(0).onloadedmetadata();return false;" ' + |
51 | | - 'onprogress="$j(\'#' + this.id + '\').get(0).onprogress( event );return false;" ' + |
52 | | - 'onended="$j(\'#' + this.id + '\').get(0).onended();return false;" ' + |
53 | | - 'onseeking="$j(\'#' + this.id + '\').get(0).onseeking();" ' + |
54 | | - 'onseeked="$j(\'#' + this.id + '\').get(0).onseeked();" >' + |
55 | | - '</video>'; |
| 63 | + 'src="' + this.getSrc() + '" ' + |
| 64 | + '</video>'; |
56 | 65 | return eb; |
57 | | - }, |
58 | | - // @@todo : loading progress |
| 66 | + }, |
| 67 | + /** |
| 68 | + * Post element javascript, binds event listeners and starts monitor |
| 69 | + */ |
59 | 70 | postEmbedJS:function() { |
60 | 71 | var _this = this; |
61 | 72 | js_log( "f:native:postEmbedJS:" ); |
62 | | - this.getVID(); |
63 | | - if ( typeof this.vid != 'undefined' ) { |
64 | | - // always load the media: |
| 73 | + this.getPlayerElement(); |
| 74 | + if ( typeof this.playerElement != 'undefined' ) { |
| 75 | + |
| 76 | + // Setup some bindings: |
| 77 | + var vid = $j( this.playerElement ).get(0); |
| 78 | + var wtf = function(){ |
| 79 | + alert("wtf"); |
| 80 | + } |
| 81 | + // Bind events to local js methods: |
| 82 | + vid.addEventListener( 'canplaythrough', function(){ _this.canplaythrough }, true); |
| 83 | + vid.addEventListener( 'loadedmetadata', function(){ _this.onloadedmetadata() }, true); |
| 84 | + vid.addEventListener( 'progress', function( e ){ _this.onprogress( e ) }, true); |
| 85 | + vid.addEventListener( 'ended', function(){ _this.onended() }, true); |
| 86 | + vid.addEventListener( 'seeking', function(){ _this.onseeking() }, true); |
| 87 | + vid.addEventListener( 'seeked', function(){ _this.onseeked() }, true); |
| 88 | + |
| 89 | + // Always load the media: |
65 | 90 | if ( this.onlyLoadFlag ) { |
66 | | - this.vid.load(); |
| 91 | + this.playerElement.load(); |
67 | 92 | } else { |
68 | | - // issue play request |
69 | | - this.vid.play(); |
| 93 | + // Issue play request |
| 94 | + this.playerElement.play(); |
70 | 95 | } |
71 | | - setTimeout( '$j(\'#' + this.id + '\').get(0).monitor()', 100 ); |
72 | | - } else { |
73 | | - js_log( 'could not grab vid obj trying again:' + typeof this.vid ); |
| 96 | + setTimeout( function(){ |
| 97 | + _this.monitor(); |
| 98 | + }, 100 ); |
| 99 | + |
| 100 | + } else { |
| 101 | + // False inserts don't seem to be as much of a problem as before: |
| 102 | + js_log( 'Could not grab vid obj trying again:' + typeof this.playerElement ); |
74 | 103 | this.grab_try_count++; |
75 | 104 | if ( this.grab_count == 20 ) { |
76 | | - js_log( ' could not get vid object after 20 tries re-run: getEmbedObj() ?' ) ; |
| 105 | + js_log( 'Could not get vid object after 20 tries re-run: getEmbedObj() ?' ) ; |
77 | 106 | } else { |
78 | 107 | setTimeout( function(){ |
79 | 108 | _this.postEmbedJS(); |
80 | 109 | }, 200 ); |
81 | 110 | } |
| 111 | + |
82 | 112 | } |
83 | | - }, |
84 | | - onseeking:function() { |
85 | | - js_log( "onseeking" ); |
86 | | - this.seeking = true; |
87 | | - this.setStatus( gM( 'mwe-seeking' ) ); |
88 | | - }, |
89 | | - onseeked: function() { |
90 | | - js_log("onseeked"); |
91 | | - this.seeking = false; |
92 | | - }, |
93 | | - doSeek:function( perc ) { |
94 | | - js_log( 'native:seek:p: ' + perc + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec ); |
| 113 | + }, |
| 114 | + |
| 115 | + /** |
| 116 | + * Issue a seeking request. |
| 117 | + * |
| 118 | + * @param {Float} percentage |
| 119 | + */ |
| 120 | + doSeek:function( percentage ) { |
| 121 | + js_log( 'native:seek:p: ' + percentage + ' : ' + this.supportsURLTimeEncoding() + ' dur: ' + this.getDuration() + ' sts:' + this.seek_time_sec ); |
95 | 122 | // @@todo check if the clip is loaded here (if so we can do a local seek) |
96 | 123 | if ( this.supportsURLTimeEncoding() ) { |
97 | 124 | // Make sure we could not do a local seek instead: |
98 | | - if ( perc < this.bufferedPercent && this.vid.duration && !this.didSeekJump ) { |
99 | | - js_log( "do local seek " + perc + ' is already buffered < ' + this.bufferedPercent ); |
100 | | - this.doNativeSeek( perc ); |
| 125 | + if ( percentage < this.bufferedPercent && this.playerElement.duration && !this.didSeekJump ) { |
| 126 | + js_log( "do local seek " + percentage + ' is already buffered < ' + this.bufferedPercent ); |
| 127 | + this.doNativeSeek( percentage ); |
101 | 128 | } else { |
102 | 129 | // We support URLTimeEncoding call parent seek: |
103 | | - this.parent_doSeek( perc ); |
| 130 | + this.parent_doSeek( percentage ); |
104 | 131 | } |
105 | | - } else if ( this.vid && this.vid.duration ) { |
106 | | - // (could also check bufferedPercent > perc seek (and issue oggz_chop request or not) |
107 | | - this.doNativeSeek( perc ); |
| 132 | + } else if ( this.playerElement && this.playerElement.duration ) { |
| 133 | + // (could also check bufferedPercent > percentage seek (and issue oggz_chop request or not) |
| 134 | + this.doNativeSeek( percentage ); |
108 | 135 | } else { |
109 | 136 | // try to do a play then seek: |
110 | | - this.doPlayThenSeek( perc ) |
| 137 | + this.doPlayThenSeek( percentage ) |
111 | 138 | } |
112 | 139 | }, |
113 | | - doNativeSeek:function( perc ) { |
114 | | - js_log( 'native::doNativeSeek::' + perc ); |
| 140 | + |
| 141 | + /** |
| 142 | + * Do a native seek by updating the currentTime |
| 143 | + */ |
| 144 | + doNativeSeek:function( percentage ) { |
| 145 | + js_log( 'native::doNativeSeek::' + percentage ); |
115 | 146 | this.seek_time_sec = 0; |
116 | | - this.vid.currentTime = perc * this.duration; |
| 147 | + this.playerElement.currentTime = percentage * this.duration; |
117 | 148 | this.monitor(); |
118 | 149 | }, |
119 | | - doPlayThenSeek:function( perc ) { |
| 150 | + |
| 151 | + /** |
| 152 | + * Do a play request |
| 153 | + * then check if the video is ready to play |
| 154 | + * then seek |
| 155 | + * |
| 156 | + * @param {Float} percentage Percentage of the stream to seek to between 0 and 1 |
| 157 | + */ |
| 158 | + doPlayThenSeek:function( percentage ) { |
120 | 159 | js_log( 'native::doPlayThenSeek::' ); |
121 | 160 | var _this = this; |
122 | 161 | this.play(); |
123 | 162 | var rfsCount = 0; |
124 | 163 | var readyForSeek = function() { |
125 | | - _this.getVID(); |
126 | | - if ( _this.vid ) |
127 | | - js_log( 'readyForSeek looking::' + _this.vid.duration ); |
| 164 | + _this.getPlayerElement(); |
| 165 | + if ( _this.playerElement ) |
| 166 | + js_log( 'readyForSeek looking::' + _this.playerElement.duration ); |
128 | 167 | // if we have duration then we are ready to do the seek |
129 | | - if ( _this.vid && _this.vid.duration ) { |
130 | | - _this.doNativeSeek( perc ); |
| 168 | + if ( _this.playerElement && _this.playerElement.duration ) { |
| 169 | + _this.doNativeSeek( percentage ); |
131 | 170 | } else { |
132 | 171 | // Try to get player for 40 seconds: |
133 | 172 | // (it would be nice if the onmetadata type callbacks where fired consistently) |
— | — | @@ -140,33 +179,44 @@ |
141 | 180 | } |
142 | 181 | readyForSeek(); |
143 | 182 | }, |
144 | | - setCurrentTime: function( pos, callback ) { |
| 183 | + |
| 184 | + /** |
| 185 | + * Set the current time with a callback |
| 186 | + */ |
| 187 | + setCurrentTime: function( position , callback ) { |
145 | 188 | var _this = this; |
146 | | - js_log( 'native:setCurrentTime::: ' + pos + ' : dur: ' + _this.getDuration() ); |
147 | | - this.getVID(); |
148 | | - if ( !this.vid ) { |
| 189 | + js_log( 'native:setCurrentTime::: ' + position + ' : dur: ' + _this.getDuration() ); |
| 190 | + this.getPlayerElement(); |
| 191 | + if ( !this.playerElement ) { |
149 | 192 | this.load( function() { |
150 | | - _this.doSeekedCb( pos, callback ); |
| 193 | + _this.doSeekedCb( position, callback ); |
151 | 194 | } ); |
152 | 195 | } else { |
153 | | - _this.doSeekedCb( pos, callback ); |
| 196 | + _this.doSeekedCb( position, callback ); |
154 | 197 | } |
155 | 198 | }, |
156 | | - doSeekedCb : function( pos, cb ){ |
| 199 | + /** |
| 200 | + * Do the seek request with a callback |
| 201 | + */ |
| 202 | + doSeekedCallback : function( position, callback ){ |
157 | 203 | var _this = this; |
158 | | - this.getVID(); |
| 204 | + this.getPlayerElement(); |
159 | 205 | var once = function( event ) { |
160 | | - js_log("did seek cb"); |
161 | | - cb(); |
162 | | - _this.vid.removeEventListener( 'seeked', once, false ); |
| 206 | + js_log("did seek callback"); |
| 207 | + callback(); |
| 208 | + _this.playerElement.removeEventListener( 'seeked', once, false ); |
163 | 209 | }; |
164 | 210 | // Assume we will get to add the Listener before the seek is done |
165 | | - _this.vid.currentTime = pos; |
166 | | - _this.vid.addEventListener( 'seeked', once, false ); |
| 211 | + _this.playerElement.currentTime = position; |
| 212 | + _this.playerElement.addEventListener( 'seeked', once, false ); |
167 | 213 | }, |
| 214 | + |
| 215 | + /** |
| 216 | + * Monitor the video playback & update the currentTime |
| 217 | + */ |
168 | 218 | monitor : function() { |
169 | | - this.getVID(); // make sure we have .vid obj |
170 | | - if ( !this.vid ) { |
| 219 | + this.getPlayerElement(); // make sure we have .vid obj |
| 220 | + if ( !this.playerElement ) { |
171 | 221 | js_log( 'could not find video embed: ' + this.id + ' stop monitor' ); |
172 | 222 | this.stopMonitor(); |
173 | 223 | return false; |
— | — | @@ -186,7 +236,7 @@ |
187 | 237 | this.prevCurrentTime = this.currentTime; |
188 | 238 | |
189 | 239 | // update currentTime |
190 | | - this.currentTime = this.vid.currentTime; |
| 240 | + this.currentTime = this.playerElement.currentTime; |
191 | 241 | |
192 | 242 | // js_log('currentTime:' + this.currentTime); |
193 | 243 | // js_log('this.currentTime: ' + this.currentTime ); |
— | — | @@ -197,113 +247,199 @@ |
198 | 248 | /** |
199 | 249 | * Get video src URI |
200 | 250 | */ |
201 | | - getSrc:function() { |
| 251 | + getSrc: function() { |
202 | 252 | var src = this.parent_getSrc(); |
203 | 253 | if ( this.urlAppend != '' ) |
204 | 254 | return src + ( ( src.indexOf( '?' ) == -1 ) ? '?':'&' ) + this.urlAppend; |
205 | 255 | return src; |
206 | | - }, |
207 | | - /* |
208 | | - * native callbacks for the video tag: |
209 | | - */ |
210 | | - oncanplaythrough : function() { |
211 | | - js_log('f:oncanplaythrough'); |
212 | | - this.getVID(); |
213 | | - if ( ! this.paused ) |
214 | | - this.vid.play(); |
215 | | - }, |
216 | | - onloadedmetadata: function() { |
217 | | - this.getVID(); |
218 | | - js_log( 'f:onloadedmetadata metadata ready (update duration)' ); |
219 | | - // update duration if not set (for now trust the getDuration more than this.vid.duration |
220 | | - if ( this.getDuration() == 0 && ! isNaN( this.vid.duration ) ) { |
221 | | - js_log( 'updaed duration via native video duration: ' + this.vid.duration ) |
222 | | - this.duration = this.vid.duration; |
223 | | - } |
224 | | - //fire "onLoaded" flags if set |
225 | | - while( this.onLoadedCallback.length ){ |
226 | | - func = this.onLoadedCallback.pop() |
227 | | - if( typeof func == 'function' ) |
228 | | - func(); |
229 | | - } |
230 | | - }, |
231 | | - onprogress: function( e ) { |
232 | | - this.bufferedPercent = e.loaded / e.total; |
233 | | - // js_log("onprogress:" +e.loaded + ' / ' + (e.total) + ' = ' + this.bufferedPercent); |
234 | | - }, |
235 | | - onended:function() { |
236 | | - var _this = this |
237 | | - this.getVID(); |
238 | | - js_log( 'native:onended:' + this.vid.currentTime + ' real dur:' + this.getDuration() ); |
239 | | - // 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) |
240 | | - if ( this.vid.currentTime < 1 && this.getDuration() > 1 && this.grab_try_count < 5 ) { |
241 | | - js_log( 'native on ended called with time:' + this.vid.currentTime + ' of total real dur: ' + this.getDuration() + ' attempting to reload src...' ); |
242 | | - var doRetry = function() { |
243 | | - _this.urlAppend = 'retry_src=' + _this.grab_try_count; |
244 | | - _this.doEmbedHTML(); |
245 | | - _this.grab_try_count++; |
246 | | - } |
247 | | - setTimeout( doRetry, 100 ); |
248 | | - } else { |
249 | | - js_log( 'native onClipDone done call' ); |
250 | | - this.onClipDone(); |
251 | | - } |
252 | | - }, |
253 | | - pause : function() { |
254 | | - this.getVID(); |
| 256 | + }, |
| 257 | + |
| 258 | + /** |
| 259 | + * Pause the video playback |
| 260 | + * calls parent_pause to update the interface |
| 261 | + */ |
| 262 | + pause: function() { |
| 263 | + this.getPlayerElement(); |
255 | 264 | this.parent_pause(); // update interface |
256 | | - if ( this.vid ) { |
257 | | - this.vid.pause(); |
| 265 | + if ( this.playerElement ) { |
| 266 | + this.playerElement.pause(); |
258 | 267 | } |
259 | 268 | // stop updates: |
260 | 269 | this.stopMonitor(); |
261 | 270 | }, |
262 | | - play:function() { |
263 | | - this.getVID(); |
| 271 | + |
| 272 | + /** |
| 273 | + * Play back the video stream |
| 274 | + * calls parent_play to update the interface |
| 275 | + */ |
| 276 | + play: function() { |
| 277 | + this.getPlayerElement(); |
264 | 278 | this.parent_play(); // update interface |
265 | | - if ( this.vid ) { |
266 | | - this.vid.play(); |
| 279 | + if ( this.playerElement ) { |
| 280 | + this.playerElement.play(); |
267 | 281 | // re-start the monitor: |
268 | 282 | this.monitor(); |
269 | 283 | } |
270 | 284 | }, |
271 | | - toggleMute:function() { |
| 285 | + |
| 286 | + /** |
| 287 | + * Toggle the Mute |
| 288 | + * calls parent_toggleMute to update the interface |
| 289 | + */ |
| 290 | + toggleMute: function() { |
272 | 291 | this.parent_toggleMute(); |
273 | | - this.getVID(); |
274 | | - if ( this.vid ) |
275 | | - this.vid.muted = this.muted; |
| 292 | + this.getPlayerElement(); |
| 293 | + if ( this.playerElement ) |
| 294 | + this.playerElement.muted = this.muted; |
276 | 295 | }, |
277 | | - updateVolumen:function( perc ) { |
278 | | - this.getVID(); |
279 | | - if ( this.vid ) |
280 | | - this.vid.volume = perc; |
| 296 | + |
| 297 | + /** |
| 298 | + * Update Volume |
| 299 | + * |
| 300 | + * @param {Float} percentage Value between 0 and 1 to set audio volume |
| 301 | + */ |
| 302 | + updateVolumen: function( percentage ) { |
| 303 | + this.getPlayerElement(); |
| 304 | + if ( this.playerElement ) |
| 305 | + this.playerElement.volume = percentage; |
281 | 306 | }, |
282 | | - getVolumen:function() { |
283 | | - this.getVID(); |
284 | | - if ( this.vid ) |
285 | | - return this.vid.volume; |
| 307 | + |
| 308 | + /** |
| 309 | + * get Volume |
| 310 | + * |
| 311 | + * @return {Float} |
| 312 | + * Audio volume between 0 and 1. |
| 313 | + */ |
| 314 | + getVolumen: function() { |
| 315 | + this.getPlayerElement(); |
| 316 | + if ( this.playerElement ) |
| 317 | + return this.playerElement.volume; |
286 | 318 | }, |
287 | | - getNativeDuration:function() { |
288 | | - if ( this.vid ) |
289 | | - return this.vid.duration; |
| 319 | + |
| 320 | + /** |
| 321 | + * Get the native media duration |
| 322 | + */ |
| 323 | + getNativeDuration: function() { |
| 324 | + if ( this.playerElement ) |
| 325 | + return this.playerElement.duration; |
290 | 326 | }, |
291 | | - load:function( callback ) { |
292 | | - this.getVID(); |
293 | | - if ( !this.vid ) { |
| 327 | + |
| 328 | + /** |
| 329 | + * load the video stream with a callback fired once the video is "loaded" |
| 330 | + * |
| 331 | + * @parma {Function} callbcak Function called once video is loaded |
| 332 | + */ |
| 333 | + load: function( callback ) { |
| 334 | + this.getPlayerElement(); |
| 335 | + if ( !this.playerElement ) { |
294 | 336 | // No vid loaded |
295 | 337 | js_log( 'native::load() ... doEmbed' ); |
296 | 338 | this.onlyLoadFlag = true; |
297 | 339 | this.doEmbedHTML(); |
298 | | - this.onLoadedCallback.push( callback ); |
| 340 | + this.onLoadedCallback = callback; |
299 | 341 | } else { |
300 | 342 | // Should not happen offten |
301 | | - this.vid.load(); |
| 343 | + this.playerElement.load(); |
302 | 344 | if( callback) |
303 | 345 | callback(); |
304 | 346 | } |
305 | 347 | }, |
306 | | - // get the embed vlc object |
307 | | - getVID : function () { |
308 | | - this.vid = $j( '#' + this.pid ).get( 0 ); |
| 348 | + |
| 349 | + /** |
| 350 | + * Get /update the playerElement value |
| 351 | + */ |
| 352 | + getPlayerElement : function () { |
| 353 | + this.playerElement = $j( '#' + this.pid ).get( 0 ); |
| 354 | + }, |
| 355 | + |
| 356 | + /** |
| 357 | + * Bindings for the Video Element Events |
| 358 | + */ |
| 359 | + |
| 360 | + /** |
| 361 | + * Local method for seeking event |
| 362 | + * fired when "seeking" |
| 363 | + */ |
| 364 | + onseeking:function() { |
| 365 | + js_log( "onseeking" ); |
| 366 | + this.seeking = true; |
| 367 | + this.setStatus( gM( 'mwe-seeking' ) ); |
| 368 | + }, |
| 369 | + |
| 370 | + /** |
| 371 | + * Local method for seeked event |
| 372 | + * fired when done seeking |
| 373 | + */ |
| 374 | + onseeked: function() { |
| 375 | + js_log("onseeked"); |
| 376 | + this.seeking = false; |
| 377 | + }, |
| 378 | + |
| 379 | + /** |
| 380 | + * Local method for can play through |
| 381 | + * fired when done video can play through without re-buffering |
| 382 | + */ |
| 383 | + oncanplaythrough : function() { |
| 384 | + js_log('f:oncanplaythrough'); |
| 385 | + this.getPlayerElement(); |
| 386 | + if ( ! this.paused ) |
| 387 | + this.playerElement.play(); |
| 388 | + }, |
| 389 | + |
| 390 | + /** |
| 391 | + * Local method for metadata ready |
| 392 | + * fired when metadata becomes avaliable |
| 393 | + * |
| 394 | + * Used to update the media duration to |
| 395 | + * accurately reflect the src duration |
| 396 | + */ |
| 397 | + onloadedmetadata: function() { |
| 398 | + this.getPlayerElement(); |
| 399 | + js_log( 'f:onloadedmetadata metadata ready (update duration)' ); |
| 400 | + // update duration if not set (for now trust the getDuration more than this.playerElement.duration |
| 401 | + if ( this.getDuration() == 0 && ! isNaN( this.playerElement.duration ) ) { |
| 402 | + js_log( 'updaed duration via native video duration: ' + this.playerElement.duration ) |
| 403 | + this.duration = this.playerElement.duration; |
| 404 | + } |
| 405 | + |
| 406 | + //Fire "onLoaded" flags if set |
| 407 | + if( typeof this.onLoadedCallback == 'function' ){ |
| 408 | + this.onLoadedCallback(); |
| 409 | + } |
| 410 | + }, |
| 411 | + |
| 412 | + /** |
| 413 | + * Local method for progress event |
| 414 | + * fired as the video is downloaded / buffered |
| 415 | + * |
| 416 | + * Used to update the bufferedPercent |
| 417 | + */ |
| 418 | + onprogress: function( e ) { |
| 419 | + this.bufferedPercent = e.loaded / e.total; |
| 420 | + }, |
| 421 | + |
| 422 | + /** |
| 423 | + * Local method for progress event |
| 424 | + * fired as the video is downloaded / buffered |
| 425 | + * |
| 426 | + * Used to update the bufferedPercent |
| 427 | + */ |
| 428 | + onended: function() { |
| 429 | + var _this = this |
| 430 | + this.getPlayerElement(); |
| 431 | + js_log( 'native:onended:' + this.playerElement.currentTime + ' real dur:' + this.getDuration() ); |
| 432 | + // 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) |
| 433 | + if ( this.playerElement.currentTime < 1 && this.getDuration() > 1 && this.grab_try_count < 5 ) { |
| 434 | + js_log( 'native on ended called with time:' + this.playerElement.currentTime + ' of total real dur: ' + this.getDuration() + ' attempting to reload src...' ); |
| 435 | + var doRetry = function() { |
| 436 | + _this.urlAppend = 'retry_src=' + _this.grab_try_count; |
| 437 | + _this.doEmbedHTML(); |
| 438 | + _this.grab_try_count++; |
| 439 | + } |
| 440 | + setTimeout( doRetry, 100 ); |
| 441 | + } else { |
| 442 | + js_log( 'native onClipDone done call' ); |
| 443 | + this.onClipDone(); |
| 444 | + } |
309 | 445 | } |
310 | 446 | }; |
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/kplayerEmbed.js |
— | — | @@ -1,5 +1,12 @@ |
| 2 | +/* |
| 3 | +* The "kaltura player" embedPlayer interface for fallback h.264 and flv video format support |
| 4 | +*/ |
2 | 5 | var kplayerEmbed = { |
| 6 | + |
| 7 | + // Instance name: |
3 | 8 | instanceOf:'kplayerEmbed', |
| 9 | + |
| 10 | + // List of supported features: |
4 | 11 | supports: { |
5 | 12 | 'play_head':true, |
6 | 13 | 'pause':true, |
— | — | @@ -9,6 +16,10 @@ |
10 | 17 | 'overlay':false, |
11 | 18 | 'fullscreen':false |
12 | 19 | }, |
| 20 | + |
| 21 | + /* |
| 22 | + * Get the Embed html by wraping the embed code in the embed container: |
| 23 | + */ |
13 | 24 | getEmbedHTML : function () { |
14 | 25 | var embed_code = this.getEmbedObj(); |
15 | 26 | alert |
— | — | @@ -19,6 +30,10 @@ |
20 | 31 | js_log( "return embed html" ); |
21 | 32 | return this.wrapEmebedContainer( embed_code ); |
22 | 33 | }, |
| 34 | + |
| 35 | + /** |
| 36 | + * Get the plugin embed html |
| 37 | + */ |
23 | 38 | getEmbedObj:function() { |
24 | 39 | var player_path = mw.getMwEmbedPath() + 'libEmbedPlayer/binPlayers/kaltura-player'; |
25 | 40 | return '<object width="' + this.width + '" height="' + this.height + '" '+ |
— | — | @@ -40,65 +55,92 @@ |
41 | 56 | '<param value="opaque" name="wmode"/>'+ |
42 | 57 | '</object>'; |
43 | 58 | }, |
| 59 | + |
| 60 | + /** |
| 61 | + * javascript run post player embeding |
| 62 | + */ |
44 | 63 | postEmbedJS:function() { |
45 | 64 | var _this = this; |
46 | | - this.getKDP(); |
47 | | - //alert( this.kdp ); |
48 | | - if( this.kdp && this.kdp.insertMedia){ |
| 65 | + this.getPlayerElement(); |
| 66 | + //alert( this.playerElement ); |
| 67 | + if( this.playerElement && this.playerElement.insertMedia){ |
49 | 68 | // Add KDP listeners |
50 | 69 | |
51 | | - //this.kdp.addJsListener("doPlay","kdpDoOnPlay"); |
52 | | - //this.kdp.addJsListener("doStop","kdpDoOnStop"); |
| 70 | + //this.playerElement.addJsListener("doPlay","kdpDoOnPlay"); |
| 71 | + //this.playerElement.addJsListener("doStop","kdpDoOnStop"); |
53 | 72 | //myKdp.addJsListener("fastForward","kdpDoOnFF"); |
54 | 73 | |
55 | | - _this.bindKdpFunc( 'doPause', 'kdpPause' ); |
56 | | - _this.bindKdpFunc( 'doPlay', 'play' ); |
57 | | - _this.bindKdpFunc( 'playerPlayEnd', 'onClipDone' ); |
| 74 | + _this.bindPlayerFunction( 'doPause', 'onPause' ); |
| 75 | + _this.bindPlayerFunction( 'doPlay', 'play' ); |
| 76 | + _this.bindPlayerFunction( 'playerPlayEnd', 'onClipDone' ); |
58 | 77 | |
59 | 78 | // KDP player likes an absolute url for the src: |
60 | 79 | var src = mw.absoluteUrl( _this.getSrc() ); |
61 | 80 | js_log('play src: ' + src); |
| 81 | + |
62 | 82 | // Insert the src: |
63 | | - this.kdp.insertMedia("-1", src, 'true' ); |
64 | | - this.kdp.dispatchKdpEvent('doPlay'); |
| 83 | + this.playerElement.insertMedia( "-1", src, 'true' ); |
| 84 | + this.playerElement.dispatchKdpEvent( 'doPlay' ); |
65 | 85 | |
66 | 86 | // Start the monitor |
67 | 87 | this.monitor(); |
68 | 88 | }else{ |
69 | | - js_log('insert media: not defiend' + typeof this.kdp.insertMedia ); |
| 89 | + js_log('insert media: not defiend' + typeof this.playerElement.insertMedia ); |
70 | 90 | setTimeout( function(){ |
71 | 91 | _this.postEmbedJS(); |
72 | 92 | }, 25); |
73 | 93 | } |
74 | 94 | }, |
| 95 | + |
75 | 96 | /** |
76 | | - * bindKdpFunc |
| 97 | + * Bind a Player Function, |
77 | 98 | * |
| 99 | + * Does some tricker to bind to "this" player instance: |
| 100 | + * |
78 | 101 | * @param {String} flash binding name |
79 | 102 | * @param {String} function callback name |
80 | 103 | */ |
81 | | - bindKdpFunc:function( bName, fName ){ |
| 104 | + bindPlayerFunction:function( bName, fName ){ |
82 | 105 | var cbid = fName + '_cb_' + this.id.replace(' ', '_'); |
83 | 106 | eval( 'window[ \'' + cbid +'\' ] = function(){$j(\'#' + this.id + '\').get(0).'+ fName +'();}' ); |
84 | | - this.kdp.addJsListener( bName , cbid); |
| 107 | + this.playerElement.addJsListener( bName , cbid); |
85 | 108 | }, |
86 | | - kdpPause:function(){ |
| 109 | + |
| 110 | + /** |
| 111 | + * on Pause callback from the kaltura flash player |
| 112 | + * calls parent_pause to update the interface |
| 113 | + */ |
| 114 | + onPause:function(){ |
87 | 115 | this.parent_pause(); |
88 | 116 | }, |
| 117 | + |
| 118 | + /** |
| 119 | + * play method |
| 120 | + * calls parent_play to update the interface |
| 121 | + */ |
89 | 122 | play:function() { |
90 | | - if( this.kdp && this.kdp.dispatchKdpEvent ) |
91 | | - this.kdp.dispatchKdpEvent('doPlay'); |
| 123 | + if( this.playerElement && this.playerElement.dispatchKdpEvent ) |
| 124 | + this.playerElement.dispatchKdpEvent('doPlay'); |
92 | 125 | this.parent_play(); |
93 | 126 | }, |
| 127 | + |
| 128 | + /** |
| 129 | + * pause method |
| 130 | + * calls parent_pause to update the interface |
| 131 | + */ |
94 | 132 | pause:function() { |
95 | | - this.kdp.dispatchKdpEvent('doPause'); |
| 133 | + this.playerElement.dispatchKdpEvent('doPause'); |
96 | 134 | this.parent_pause(); |
97 | 135 | }, |
| 136 | + |
| 137 | + /** |
| 138 | + * Issues a seek to the playerElement |
| 139 | + */ |
98 | 140 | doSeek:function( prec ){ |
99 | 141 | var _this = this; |
100 | | - if( this.kdp ){ |
| 142 | + if( this.playerElement ){ |
101 | 143 | var seek_time = prec * this.getDuration(); |
102 | | - this.kdp.dispatchKdpEvent('doSeek', seek_time); |
| 144 | + this.playerElement.dispatchKdpEvent('doSeek', seek_time); |
103 | 145 | // Kdp is missing seek done callback |
104 | 146 | setTimeout(function(){ |
105 | 147 | _this.seeking= false; |
— | — | @@ -106,35 +148,37 @@ |
107 | 149 | } |
108 | 150 | this.monitor(); |
109 | 151 | }, |
110 | | - updateVolumen:function( perc ) { |
111 | | - if( this.kdp && this.kdp.dispatchKdpEvent ) |
112 | | - this.kdp.dispatchKdpEvent('volumeChange', perc); |
| 152 | + |
| 153 | + /** |
| 154 | + * Issues a volume update to the playerElement |
| 155 | + */ |
| 156 | + updateVolumen:function( percentage ) { |
| 157 | + if( this.playerElement && this.playerElement.dispatchKdpEvent ) |
| 158 | + this.playerElement.dispatchKdpEvent('volumeChange', percentage); |
113 | 159 | }, |
| 160 | + |
| 161 | + /** |
| 162 | + * Monitors playback updating the current Time |
| 163 | + */ |
114 | 164 | monitor:function() { |
115 | | - if( this.kdp && this.kdp.getMediaSeekTime ){ |
116 | | - this.currentTime = this.kdp.getMediaSeekTime(); |
| 165 | + if( this.playerElement && this.playerElement.getMediaSeekTime ){ |
| 166 | + this.currentTime = this.playerElement.getMediaSeekTime(); |
117 | 167 | } |
118 | 168 | this.parent_monitor(); |
119 | 169 | }, |
120 | | - // get the embed fla object |
121 | | - getKDP: function () { |
122 | | - this.kdp = document.getElementById( this.pid ); |
| 170 | + |
| 171 | + /** |
| 172 | + * Get the embed fla object player Element |
| 173 | + */ |
| 174 | + getPlayerElement: function () { |
| 175 | + this.playerElement = document.getElementById( this.pid ); |
123 | 176 | } |
124 | 177 | } |
125 | | - |
126 | | -function kdpDoOnPause( player ){ |
127 | | - var cat = player |
128 | | - debugger; |
129 | | -} |
130 | | - |
| 178 | +/** |
| 179 | +* function called once player is ready. |
| 180 | +* |
| 181 | +* NOTE: playerID is not always passed so we can't use this: |
| 182 | +*/ |
131 | 183 | 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 | | - */ |
| 184 | + js_log( "player is ready::" + playerId); |
141 | 185 | } |
Index: branches/js2-work/phase3/js2/mwEmbed/libEmbedPlayer/omtkEmbed.js |
— | — | @@ -1,15 +1,36 @@ |
| 2 | +/* |
| 3 | +* omtk media player supports ogg vorbis playback. |
| 4 | +* omtk is not feature complete and fails on some ogg vorbis streams. |
| 5 | +* |
| 6 | +* This script will be depreciated unless the omtk flash applet improves in quality |
| 7 | +*/ |
2 | 8 | var omtkEmbed = { |
| 9 | + |
| 10 | + // Instance name |
3 | 11 | instanceOf:'omtkEmbed', |
| 12 | + |
| 13 | + // Supported player features |
4 | 14 | supports: { |
5 | 15 | 'pause':true, |
6 | | - 'time_display':true |
| 16 | + 'time_display':true |
7 | 17 | }, |
| 18 | + |
| 19 | + /** |
| 20 | + * Wrap the embed code |
| 21 | + */ |
8 | 22 | getEmbedHTML : function () { |
| 23 | + var _this = this; |
9 | 24 | var embed_code = this.getEmbedObj(); |
10 | 25 | // Need omtk to fire an onReady event. |
11 | | - setTimeout( '$j(\'#' + this.id + '\').get(0).postEmbedJS()', 2000 ); |
| 26 | + setTimeout( function(){ |
| 27 | + _this.postEmbedJS(); |
| 28 | + }, 2000 ); |
12 | 29 | return this.wrapEmebedContainer( embed_code ); |
13 | 30 | }, |
| 31 | + |
| 32 | + /** |
| 33 | + * Get the embed object html |
| 34 | + */ |
14 | 35 | getEmbedObj:function() { |
15 | 36 | var player_path = mw.getMwEmbedPath() + 'libEmbedPlayer/binPlayers/omtk-fx/omtkp.swf'; |
16 | 37 | // player_path = 'omtkp.swf'; |
— | — | @@ -25,37 +46,53 @@ |
26 | 47 | '<!--<![endif]-->' + "\n" + |
27 | 48 | '</object>'; |
28 | 49 | }, |
| 50 | + |
| 51 | + /** |
| 52 | + * Run post embed javascript |
| 53 | + */ |
29 | 54 | postEmbedJS:function() { |
30 | | - this.getOMTK(); |
| 55 | + this.getPlayerElement(); |
31 | 56 | // play the url: |
32 | 57 | js_log( "play: pid:" + this.pid + ' src:' + this.src ); |
33 | 58 | |
34 | | - this.omtk.play( this.src ); |
| 59 | + this.playerElement.play( this.src ); |
35 | 60 | |
36 | 61 | this.monitor(); |
37 | 62 | // $j('#omtk_player').get(0).play(this.src); |
38 | 63 | // $j('#'+this.pid).get(0).play( this.src ); |
39 | 64 | }, |
| 65 | + |
| 66 | + /** |
| 67 | + * omtk does not support pause, issue the "stop" request |
| 68 | + */ |
40 | 69 | pause:function() { |
41 | 70 | this.stop(); |
42 | 71 | }, |
| 72 | + |
| 73 | + /** |
| 74 | + * Monitor the audio playback and update the position |
| 75 | + */ |
43 | 76 | monitor:function() { |
44 | | - if ( this.omtk.getPosition ) |
45 | | - this.currentTime = this.omtk.getPosition() / 1000; |
| 77 | + if ( this.playerElement.getPosition ) |
| 78 | + this.currentTime = this.playerElement.getPosition() / 1000; |
46 | 79 | |
47 | 80 | this.parent_monitor(); |
48 | 81 | }, |
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 ); |
| 82 | + |
| 83 | + /** |
| 84 | + * Update the playerElement pointer |
| 85 | + */ |
| 86 | + getPlayerElement : function () { |
| 87 | + this.playerElement = $j( '#' + this.pid ).get( 0 ); |
| 88 | + if ( !this.playerElement.play ) |
| 89 | + this.playerElement = $j( '#' + this.pid + '_ie' ).get( 0 ); |
53 | 90 | |
54 | | - if ( this.omtk.play ) { |
| 91 | + if ( this.playerElement.play ) { |
55 | 92 | // js_log('omtk obj is missing .play (probably not omtk obj)'); |
56 | 93 | } |
57 | 94 | }, |
58 | 95 | } |
59 | | - |
| 96 | +// Some auto-called globals (bad) |
60 | 97 | function OMTK_P_complete() { |
61 | 98 | js_log( 'OMTK_P_complete' ); |
62 | 99 | } |
Index: branches/js2-work/phase3/js2/mwEmbed/libSequencer/mvPlayList.js |
— | — | @@ -163,7 +163,7 @@ |
164 | 164 | } ); |
165 | 165 | |
166 | 166 | }, |
167 | | - showPlayerselect:function() { |
| 167 | + showPlayerSelect:function() { |
168 | 168 | this.cur_clip.embed.showPlayerselect(); |
169 | 169 | }, |
170 | 170 | closeDisplayedHTML:function() { |
— | — | @@ -552,7 +552,7 @@ |
553 | 553 | setStatus:function( value ) { |
554 | 554 | $j( '#' + this.id + ' .time-disp' ).text( value ); |
555 | 555 | }, |
556 | | - setSliderValue:function( value ) { |
| 556 | + updatePlayHead:function( value ) { |
557 | 557 | // slider is on 1000 scale: |
558 | 558 | var val = parseInt( value * 1000 ); |
559 | 559 | //js_log( 'update slider: #' + this.id + ' .play_head to ' + val ); |
— | — | @@ -689,7 +689,7 @@ |
690 | 690 | var clip_time = this.cur_clip.dur_offset; |
691 | 691 | } |
692 | 692 | |
693 | | - this.setSliderValue( clip_time / this.getDuration() ); |
| 693 | + this.updatePlayHead( clip_time / this.getDuration() ); |
694 | 694 | } |
695 | 695 | }, |
696 | 696 | playPrev: function() { |
— | — | @@ -857,7 +857,7 @@ |
858 | 858 | // reset the currentTime: |
859 | 859 | this.currentTime = 0; |
860 | 860 | // rest the sldier |
861 | | - this.setSliderValue( 0 ); |
| 861 | + this.updatePlayHead( 0 ); |
862 | 862 | // FIXME still some issues with "stoping" and reseting the playlist |
863 | 863 | }, |
864 | 864 | doSeek:function( v ) { |
— | — | @@ -1364,9 +1364,9 @@ |
1365 | 1365 | setStatus:function( value ) { |
1366 | 1366 | // status updates handled by playlist obj |
1367 | 1367 | }, |
1368 | | - setSliderValue:function( value ) { |
1369 | | - //js_log( 'PlMvEmbed:setSliderValue:' + value ); |
1370 | | - // setSlider value handled by playlist obj |
| 1368 | + updatePlayHead:function( value ) { |
| 1369 | + //js_log( 'PlMvEmbed:updatePlayHead:' + value ); |
| 1370 | + // updatePlayHead handled by playlist obj |
1371 | 1371 | } |
1372 | 1372 | } |
1373 | 1373 | |
— | — | @@ -1522,14 +1522,16 @@ |
1523 | 1523 | if ( this.currentTime > this.getDuration() ) |
1524 | 1524 | this.stop(); |
1525 | 1525 | |
| 1526 | + |
| 1527 | + var relative_time = ( this.start_offset ) ? ( this.currentTime - this.start_offset) : this.currentTime; |
1526 | 1528 | // update the playlist current time: |
1527 | 1529 | // check for a trsnOut from the previus clip to subtract |
1528 | | - this.currentTime = this.cur_clip.dur_offset + this.cur_clip.embed.relativeCurrentTime(); |
| 1530 | + this.currentTime = this.cur_clip.dur_offset + relative_time; |
1529 | 1531 | |
1530 | 1532 | // update slider: |
1531 | 1533 | if ( !this.userSlide ) { |
1532 | 1534 | this.setStatus( seconds2npt( this.currentTime ) + '/' + seconds2npt( this.getDuration() ) ); |
1533 | | - this.setSliderValue( this.currentTime / this.getDuration() ); |
| 1535 | + this.updatePlayHead( this.currentTime / this.getDuration() ); |
1534 | 1536 | } |
1535 | 1537 | // pre-load any future clips: |
1536 | 1538 | this.loadFutureClips(); |