diff --git a/flowplayer.admin.inc b/flowplayer.admin.inc index 9cf9d20..e15c6db 100644 --- a/flowplayer.admin.inc +++ b/flowplayer.admin.inc @@ -10,6 +10,17 @@ */ function flowplayer_admin_settings() { $form = array(); + + $flowplayer_path = flowplayer_get_path(); + + $form['flowplayer_path'] = array( + '#type' => 'textfield', + '#title' => t('Flowplayer Library Path'), + '#default_value' => $flowplayer_path, + '#description' => t('The location where Flowplayer and plugins are installed. Relative paths are from the Drupal root directory.'), + '#after_build' => array('_flowplayer_admin_settings_check_plugin_path'), + ); + $form['flowplayer_key'] = array( '#type' => 'textfield', '#title' => t('License Key'), @@ -131,3 +142,20 @@ function flowplayer_admin_settings() { return system_settings_form($form); } + +/** + * Checks if the directory in $form_element exists and contains a file named + * 'flowplayer.swf'. If validation fails, the form element is flagged + * with an error from within the file_check_directory function. + * + * @param $form_element + * The form element containing the name of the directory to check. + */ +function _flowplayer_admin_settings_check_plugin_path($form_element) { + $library_path = $form_element['#value']; + if (!is_dir($library_path) || !(file_exists($library_path .'/flowplayer.swf') && file_exists($library_path .'/flowplayer.min.js'))) { + form_set_error($form_element['#parents'][0], t('You need to download and set up flowplayer. For more information see README.txt.')); + } + + return $form_element; +} \ No newline at end of file diff --git a/flowplayer.module b/flowplayer.module index b22940f..c29c24a 100644 --- a/flowplayer.module +++ b/flowplayer.module @@ -6,6 +6,11 @@ */ /** + * The default path to the Colorbox directory. + */ +define('FLOWPLAYER_PATH', 'sites/all/libraries/flowplayer'); + +/** * Implementation of hook_help(). * * The code provided in this function is a demonstration of how to use jcarousel_add(). @@ -79,16 +84,24 @@ function flowplayer_add($selector = NULL, $config = NULL) { // Maintain kill switches for both Flowplayer and the Drupal behaviors. static $flowplayer_added = FALSE; static $flowplayer_selectors = array(); + + // Get path to flowplayer libraries. + $flowplayer_path = flowplayer_get_path(); + if (!$flowplayer_path) { + watchdog('flowplayer', 'Flowplayer was not found. Please read the manual for mor instructions on how to set up flowplayer.', array(), WATCHDOG_ERROR); + return FALSE; + } + // Add Flowplayer to the page if it hasn't been added yet. if ($flowplayer_added === FALSE) { // Add the FlowPlayer JavaScript and CSS to the page. - drupal_add_js(drupal_get_path('module', 'flowplayer') .'/flowplayer/flowplayer.min.js'); + drupal_add_js($flowplayer_path .'/flowplayer.min.js'); drupal_add_css(drupal_get_path('module', 'flowplayer') .'/flowplayer.css'); // Tell the JavaScript where flowplayer.swf is. $settings = array( - 'flowplayerSwf' => drupal_get_path('module', 'flowplayer') .'/flowplayer/flowplayer.swf', + 'flowplayerSwf' => $flowplayer_path . '/flowplayer.swf', ); drupal_add_js($settings, 'setting'); $flowplayer_added = TRUE; @@ -234,3 +247,32 @@ function theme_flowplayer($config = NULL, $id = 'flowplayer', $attributes = arra // Return the markup. return "
$contents
"; } + +/** + * Return the path to the Flowplayer plugins. + */ +function flowplayer_get_path() { + static $library_path = NULL; + + // Try to locate the library path in any possible setup. + if ($library_path == NULL) { + // First check the default location. + $path = variable_get('flowplayer_path', FLOWPLAYER_PATH); + if (is_dir($path)) { + $library_path = $path; + } + // Ask the libraries module as a fallback. + elseif ($library_path == NULL && module_exists('libraries')) { + if ($path = libraries_get_path('flowplayer')) { + $library_path = $path; + variable_set('flowplayer_path', $library_path); + } + } + // If no path is found suggest the default one. + elseif ($library_path == NULL) { + $library_path = FLOWPLAYER_PATH; + } + } + + return $library_path; +} \ No newline at end of file diff --git a/flowplayer/README.txt b/flowplayer/README.txt deleted file mode 100644 index 05950ca..0000000 --- a/flowplayer/README.txt +++ /dev/null @@ -1,255 +0,0 @@ -Version history: - -3.1.5 ------ -Fixes: -- The player went to a locked state when resuming playback after a period that was long enought to send the -netConnection to an invalid state. Now when resuming playback on an invalid connection the clip starts again from -the beginning. This is only when using RTMP connections and does not affect progressive download playback. -- Custom netConnect and netStream events did not pass the info object to JS listeners - -3.1.4 ------ -Fixes: -- player did not initialize if the controlbar plugin was disabled and if the play button overlay was disabled with play: null -- works properly without cachebusting on IE -- RSS playlist parsing now respects the isDefault attribute used in mRSS media group items -- Fixed passing of connection arguments - -3.1.3 ------ -- enhancements to RSS playlist parsing: Now skips all media:content that have unsupported types. Now the type attribute -of the media:content element is mandatory and has to be present in the RSS file -- Possibility to pass a RSS file name with playFeed("playlist.rss") and setPlaylist("playlist.rss") calls. -- changes to the ConnectionProvider and URLResolver APIs -- Now automatically uses a plugin that is called 'rtmp' for all clips that have the rtmp-protocol in their URLs. -- Added possibility to specify all clip properties in an RSS playlist - -Fixes: -- the result of URL resolvers in now cached, and the resolvers will not be used again when a clip is replayed -- some style properties like 'backgroundGradient' had no effect in config -- video goes tiny on Firefox: http://flowplayer.org/forum/8/23226 -- RSS playlists: The 'type' attribute value 'audio/mp3' in the media:content element caused an error. -- Dispatches onMetadata() if an URL resolver changes the clip URL (changes to a different file) -- error codes and error message were not properly passed to onEvent JS listeners - -3.1.2 ------ -- The domain of the logo url must the same domain from where the player SWF is loaded from. -- Fullscreen can be toggled by doublclick on the video area. -Fixes: -- Player was not initialized correctly when instream playlists were used and the provider used in the instream clips was defined in the common clip. -- A separator in the Context Menu made the callbacks in the following menu items out of order. Related forum post: http://flowplayer.org/forum/8/22541 -- the width and height settings of a logo were ignored if the logo was a sWF file -- volume control and mute/unmute were not working after an instream clip had been played -- now possible to use RTMP for mp3 files -- Issue 12: cuepointMultiplier was undefined in the clip object set to JS event listeners -- Issue 14: onBeforeStop was unnecessarily fired when calling setPlaylist() and the player was not playing, - additionally onStop was never fired even if onBeforeStop was -- fixed screen vertical placement problems that reappeared with 3.1.1 -- The rotating animation now has the same size and position as it has after initialized - -3.1.1 ------ -- External configuration files -- Instream playback -- Added toggleFullscreen() the API -- Possibility to specify controls configuration in clips -- Seek target position is now sent in the onBeforeSeek event -Fixes: -- The screen size was initially too small on Firefox (Mac) -- Did not persist a zero volume value: http://www.flowplayer.org/forum/8/18413 - -3.1.0 ------ -New features: -- clip's can have urlResolvers and connectionProviders -- Added new configuration options 'connectionCallbacks' and 'streamCallbacks'. Both accept an Array of event names as a value. - When these events get fired on the connection or stream object, corresponding Clip events will be fired by the player. - This can be used for example when firing custom events from RTMP server apps -- Added new clip event types: 'onConnectionEvent' and 'onStreamEvent' these get fired when the predefined events happen on the connection and stream objects. -- Added Security.allowDomain() to allow loaded plugins to script the player -- Added addClip(clip, index) to the API, index is optional -- Possibility to view videos without metadata, using clip.metaData: false -- Now the player's preloader uses the rotating animation instead of a percent text to indicate the progress - of loading the player SWF. You can disable the aninamtion by setting buffering: false -- calling close() now does not send the onStop event -- Clip's custom properties are now present in the root of the clip argument in all clip events that are sent to JS. - -Bug fixes: -- The preloader sometimes failed to initialize the player -- Allow seeking while in buffering state: http://flowplayer.org/forum/8/16505 -- Replay of a RTMP stream was failing after the connection had expired -- Security error when clicking on the screen if there is an image in the playlist loaded from a foreign domain -- loadPlugin() was not working -- now fullscreen works with Flash versions older than 9.0.115, in versions that do not support hardware scaling -- replaying a RTMP stream with an image in front of the stream in the playlist was not working (video stayed hidden). Happened - because the server does not send metadata if replaying the same stream. -- the scrubber is disabled if the clip is not seekable in the first frame: http://flowplayer.org/forum/8/16526 - By default if the clip has one of following extensions (the typical flash video extensions) it is seekable - in the first frame: 'f4b', 'f4p', 'f4v', 'flv'. Added new clip property seekableOnBegin that can be used to override the default. - -3.0.6 ------ -- added possibility to associate a linkUrl and linkWindow to the canvas -Fixes: -- fix for entering fullscreen for Flash versions that don't support the hardware scaled fullscreen-mode -- when showing images the duration tracking starts only after the image has been completely loaded: http://flowplayer.org/forum/2/15301 -- fix for verifying license keys for domains that have more than 4 labels in them -- if plugin loading failis because of a IO error, the plugin will be discarded and the player initialization continues: - -3.0.4 ------ -- The "play" pseudo-plugin now supports fadeIn(), fadeOut(), showPlugin(), hidePlugin() and - additionally you can configure it like this: - // make only the play button invisible (buffering animation is still used) - play: { display: 'none' } - // disable the play button and the buffering animation - play: null - // disable the buffering animation - buffering: null -- Added possibility to seek when in the buffering state: http://flowplayer.org/forum/3/13896 -- Added copyright notices and other GPL required entries to the user interface - -Fixes: -- clip urls were not resolved correctly if the HTML page URL had a query string starting with a question mark (http://flowplayer.org/forum/8/14016#post-14016) -- Fixed context menu for with IE (commercial version) -- a cuepoint at time zero was fired several times -- screen is now arranged correctly even when only bottom or top is defined for it in the configuration -- Fixed context menu for with IE (commercial version) -- a cuepoint at time zero was fired several times -- screen is now arranged correctly even when only bottom or top is defined for it in the configuration -- Now possible to call play() in an onError handler: http://flowplayer.org/forum/8/12939 -- Does not throw an error if the player cannot persist the volume on the client computer: http://flowplayer.org/forum/8/13286#post-13495 -- Triggering fullscreen does not pause the player in IE -- The play button overlay no longer has a gap between it's pieces when a label is used: http://flowplayer.org/forum/8/14250 -- clip.update() JS call now resets the duration -- a label configured for the play button overlay did not work in the commercial version - -3.0.3 ------ -- fixed cuepoint firing: Does not skip cuepoints any more -- Plugins can now be loaded from a different domain to the flowplayer.swf -- Specifying a clip to play by just using the 'clip' node in the configuration was not working, a playlist definition was required. This is now fixed. -- Fixed: A playlist with different providers caused the onMetadata event to fire events with metadata from the previous clip in the playlist. Occurred when moving in the playlist with next() and prev() -- the opacity setting now works with the logo -- fadeOut() call to the "screen" plugin was sending the listenerId and pluginName arguments in wrong order -- stop(), pause(), resume(), close() no longer return the flowplayer object to JS -- changing the size of the screen in a onFullscreen listener now always works, there was a bug that caused this to fail occasionally -- fixed using arbitrary SWFs as plugins -- the API method setPlaylist() no longer starts playing if autoPlay: true, neither it starts buffering if autoBuffering: true -- the API method play() now accepts an array of clip objects as an argument, the playlist is replaced with the specified clips and playback starts from the 1st clip - -3.0.2 ------ -- setting play: null now works again -- pressing the play again button overlay does not open a linkUrl associated with a clip -- now displays a live feed even when the RTMP server does not send any metadata and the onStart method is not therefore dispatched -- added onMetaData clip event -- fixed 'orig' scaling: the player went to 'fit' scaling after coming back from fullscreen. This is now fixed and the original dimensions are preserved in non-fullscreen mode. -- cuepoint times are now given in milliseconds, the firing precision is 100 ms. All cuepoint times are rounded to the nearest 100 ms value (for example 1120 rounds to 1100) -- backgroundGradient was drawn over the background image in the canvas and in the content and controlbar plugins. Now it's drawn below the image. -- added cuepointMultiplier property to clips. This can be used to multiply the time values read from cuepoint metadata embedded into video files. -- the player's framerate was increased to 24 FPS, makes all animations smoother - -3.0.1 ------ -- Fixed negative cuepoints from common clip. Now these are properly propagated to the clips in playlist. -- buffering animation is now the same size as the play button overlay -- commercial version now supports license keys that allows the use of subdomains -- error messages are now automatically hidden after a 4 second delay. They are also hidden when a new clips - starts playing (when onBeforeBegin is fired) -- added possibility to disable the buffering animation like so: buffering: false -- pressing the play button overlay does not open a linkUrl associated with a clip -- license key verification failed if a port number was used in the URL (like in this url: http://mydomain.com:8080/video.html) -- added audio support, clip has a new "image" property -- workaround for missing "NetStream.Play.Start" notfication that was happending with Red5. Because of this issue the video was not shown. -- commercial version has the possibility to change the zIndex of the logo - -3.0.0 ------ -- Removed security errors that happened when loading images from foreign domains (domains other than the domain of the core SWF). - Using a backgroundImage on canvas, in the content plugin, and for the controls is also possible to be loaded - from a foreign domain - BUT backgroundRepeat cannot be used for foreign images. -- Now allows the embedding HTML to script the player even if the player is loaded from another domain. -- Added a 'live' property to Clips, used for live streams. -- A player embedded to a foreign domain now loads images, css files and other resources from the domain where the palyer SWF was loaded from. This is to generate shorter embed-codes. -- Added linkUrl and linkWindow properties to the logo, in commercial version you can set these to point to a linked page. The linked page gets opened - when the logo is clicked. Possible values for linkWindow: - * "_self" specifies the current frame in the current window. - * "_blank" specifies a new window. - * "_parent" specifies the parent of the current frame. - * "_top" specifies the top-level frame in the current window. -- Added linkUrl and linkWindow properties to clips. The linked page is opened when the video are is clicked and the corresponding clip has a linkUrl specified. -- Made the play button overlay and the "Play again" button slightly bigger. - -RC4 ---- -- Now shows a "Play again" button at the end of the video/playlist -- Commercial version shows a Flowplayer logo if invalidKey was supplied, but the otherwise the player works -- setting play: null in configuration will disable the play button overlay -- setting opacity for "play" also sets it for the buffering animation -- Fixed firing of cuepoints too early. Cuepoint firing is now based on stream time and does not rely on timers -- added onXMPData event listener -- Should not stop playback too early before the clip is really completed -- The START event is now delayed so that the metadata is available when the event is fired, METADATA event was removed, - new event BEGIN that is dispatched when the playback has been successfully started. Metadata is not normally - available when BEGIN is fired. - -RC3 ---- -- stopBuffering() now dispatches the onStop event first if the player is playing/paused/buffering at the time of calling it -- fixed detection of images based on file extensions -- fixed some issues with having images in the playlist -- made it possible to autoBuffer next video while showing an image (image without a duration) - -RC2 ---- -- fixed: setting the screen height in configuration did not have any effect - -RC1 ------ -- better error message if plugin loading fails, shows the URL used -- validates our redesigned multidomain license key correctly -- fix to prevent the play button going visible when the onBufferEmpty event occurs -- the commercial swf now correctly loads the controls using version information -- fixed: the play button overlay became invisible with long fadeOutSpeeds - -beta6 ------ -- removed the onFirstFramePause event -- playing a clip for the second time caused a doubled sound -- pausing on first frame did not work on some FLV files - -beta5 ------ -- logo only uses percentage scaling if it's a SWF file (there is ".swf" in it's url) -- context menu now correctly builds up from string entries in configuration --always closes the previous connection before starting a new clip - -beta4 ------ -- now it's possible to load a plugin into the panel without specifying any position/dimensions - information, the plugin is placed to left: "50%", top: "50%" and using the plugin DisplayObject's width & height -- The Flowplayer API was not fully initialized when onLoad was invoked on Flash plugins - -beta3 ------ -- tweaking logo placement -- "play" did not show up after repeated pause/resume -- player now loads the latest controls SWF version, right now the latest SWF is called 'flowplayer.controls-3.0.0-beta2.swf' - -beta2 ------ -- fixed support for RTMP stream groups -- changed to loop through available fonts in order to find a suitable font also in IE -- Preloader was broken on IE: When the player SWf was in browser's cache it did not initialize properly -- Context menu now correctly handles menu items that are configured by their string labels only (not using json objects) -- fixed custom logo positioning (was moved to the left edge of screen in fullscreen) -- "play" now always follows the position and size of the screen -- video was stretched below the controls in fullscreen when autoHide: 'never' -- logo now takes 6.5% of the screen height, width is scaled so that the aspect ratio is preserved - -beta1 ------ -- First public beta release diff --git a/flowplayer/flowplayer.audio.swf b/flowplayer/flowplayer.audio.swf deleted file mode 100644 index 09514e7..0000000 Binary files a/flowplayer/flowplayer.audio.swf and /dev/null differ diff --git a/flowplayer/flowplayer.captions.swf b/flowplayer/flowplayer.captions.swf deleted file mode 100644 index eaf385b..0000000 Binary files a/flowplayer/flowplayer.captions.swf and /dev/null differ diff --git a/flowplayer/flowplayer.controls.swf b/flowplayer/flowplayer.controls.swf deleted file mode 100644 index 740e1cb..0000000 Binary files a/flowplayer/flowplayer.controls.swf and /dev/null differ diff --git a/flowplayer/flowplayer.min.js b/flowplayer/flowplayer.min.js deleted file mode 100644 index 2baa001..0000000 --- a/flowplayer/flowplayer.min.js +++ /dev/null @@ -1,24 +0,0 @@ -/* - * flowplayer.js 3.2.0. The Flowplayer API - * - * Copyright 2009 Flowplayer Oy - * - * This file is part of Flowplayer. - * - * Flowplayer is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * Flowplayer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with Flowplayer. If not, see . - * - * Date: 2010-05-03 20:23:59 +0000 (Mon, 03 May 2010) - * Revision: 468 - */ -(function(){function g(o){console.log("$f.fireEvent",[].slice.call(o))}function k(q){if(!q||typeof q!="object"){return q}var o=new q.constructor();for(var p in q){if(q.hasOwnProperty(p)){o[p]=k(q[p])}}return o}function m(t,q){if(!t){return}var o,p=0,r=t.length;if(r===undefined){for(o in t){if(q.call(t[o],o,t[o])===false){break}}}else{for(var s=t[0];p1){var t=arguments[1],q=(arguments.length==3)?arguments[2]:{};if(typeof t=="string"){t={src:t}}t=i({bgcolor:"#000000",version:[9,0],expressInstall:"http://static.flowplayer.org/swf/expressinstall.swf",cachebusting:true},t);if(typeof o=="string"){if(o.indexOf(".")!=-1){var s=[];m(n(o),function(){s.push(new b(this,k(t),k(q)))});return new d(s)}else{var r=c(o);return new b(r!==null?r:o,t,q)}}else{if(o){return new b(o,t,q)}}}return null};i(window.$f,{fireEvent:function(){var o=[].slice.call(arguments);var q=$f(o[0]);return q?q._fireEvent(o.slice(1)):null},addPlugin:function(o,p){b.prototype[o]=p;return $f},each:m,extend:i});if(typeof jQuery=="function"){jQuery.fn.flowplayer=function(q,p){if(!arguments.length||typeof arguments[0]=="number"){var o=[];this.each(function(){var r=$f(this);if(r){o.push(r)}});return arguments.length?o[arguments[0]]:new d(o)}return this.each(function(){$f(this,k(q),p?k(p):{})})}}})();(function(){var h=document.all,j="http://www.adobe.com/go/getflashplayer",c=typeof jQuery=="function",e=/(\d+)[^\d]+(\d+)[^\d]*(\d*)/,b={width:"100%",height:"100%",id:"_"+(""+Math.random()).slice(9),allowfullscreen:true,allowscriptaccess:"always",quality:"high",version:[3,0],onFail:null,expressInstall:null,w3c:false,cachebusting:false};if(window.attachEvent){window.attachEvent("onbeforeunload",function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){}})}function i(l,f){if(f){for(key in f){if(f.hasOwnProperty(key)){l[key]=f[key]}}}return l}function a(f,n){var m=[];for(var l in f){if(f.hasOwnProperty(l)){m[l]=n(f[l])}}return m}window.flashembed=function(f,m,l){if(typeof f=="string"){f=document.getElementById(f.replace("#",""))}if(!f){return}if(typeof m=="string"){m={src:m}}return new d(f,i(i({},b),m),l)};var g=i(window.flashembed,{conf:b,getVersion:function(){var f;try{f=navigator.plugins["Shockwave Flash"].description.slice(16)}catch(n){try{var l=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");f=l&&l.GetVariable("$version")}catch(m){}}f=e.exec(f);return[f[1],f[3]]},asString:function(l){if(l===null||l===undefined){return null}var f=typeof l;if(f=="object"&&l.push){f="array"}switch(f){case"string":l=l.replace(new RegExp('(["\\\\])',"g"),"\\$1");l=l.replace(/^\s?(\d+\.?\d+)%/,"$1pct");return'"'+l+'"';case"array":return"["+a(l,function(o){return g.asString(o)}).join(",")+"]";case"function":return'"function()"';case"object":var m=[];for(var n in l){if(l.hasOwnProperty(n)){m.push('"'+n+'":'+g.asString(l[n]))}}return"{"+m.join(",")+"}"}return String(l).replace(/\s/g," ").replace(/\'/g,'"')},getHTML:function(o,l){o=i({},o);var n=''}o.width=o.height=o.id=o.w3c=o.src=null;o.onFail=o.version=o.expressInstall=null;for(var m in o){if(o[m]){n+=''}}var p="";if(l){for(var f in l){if(l[f]){var q=l[f];p+=f+"="+(/function|object/.test(typeof q)?g.asString(q):q)+"&"}}p=p.slice(0,-1);n+='"}n+="";return n},isSupported:function(f){return k[0]>f[0]||k[0]==f[0]&&k[1]>=f[1]}});var k=g.getVersion();function d(f,n,m){if(g.isSupported(n.version)){f.innerHTML=g.getHTML(n,m)}else{if(n.expressInstall&&g.isSupported([6,65])){f.innerHTML=g.getHTML(i(n,{src:n.expressInstall}),{MMredirectURL:location.href,MMplayerType:"PlugIn",MMdoctitle:document.title})}else{if(!f.innerHTML.replace(/\s/g,"")){f.innerHTML="

Flash version "+n.version+" or greater is required

"+(k[0]>0?"Your version is "+k:"You have no flash plugin installed")+"

"+(f.tagName=="A"?"

Click here to download latest version

":"

Download latest version from here

");if(f.tagName=="A"){f.onclick=function(){location.href=j}}}if(n.onFail){var l=n.onFail.call(this);if(typeof l=="string"){f.innerHTML=l}}}}if(h){window[n.id]=document.getElementById(n.id)}i(this,{getRoot:function(){return f},getOptions:function(){return n},getConf:function(){return m},getApi:function(){return f.firstChild}})}if(c){jQuery.tools=jQuery.tools||{version:"3.2.0"};jQuery.tools.flashembed={conf:b};jQuery.fn.flashembed=function(l,f){return this.each(function(){$(this).data("flashembed",flashembed(this,l,f))})}}})(); \ No newline at end of file diff --git a/flowplayer/flowplayer.rtmp.swf b/flowplayer/flowplayer.rtmp.swf deleted file mode 100644 index ea2c636..0000000 Binary files a/flowplayer/flowplayer.rtmp.swf and /dev/null differ diff --git a/flowplayer/flowplayer.swf b/flowplayer/flowplayer.swf deleted file mode 100644 index 8b3f72a..0000000 Binary files a/flowplayer/flowplayer.swf and /dev/null differ