Changeset 2173


Ignore:
Timestamp:
04/20/12 11:13:23 (13 months ago)
Author:
pablo
Message:

Additional video and controlbar functionality

Location:
branches/jw6
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • branches/jw6/bin-debug/jwplayer.js

    r2172 r2173  
    237237        } 
    238238 
    239  
     239        /** Format the elapsed / remaining text. **/ 
     240        utils.timeFormat = function(sec) { 
     241                if (sec > 0) { 
     242                        str = Math.floor(sec / 60) < 10 ? "0" + Math.floor(sec / 60) + ":" : Math.floor(sec / 60) + ":"; 
     243                        str += Math.floor(sec % 60) < 10 ? "0" + Math.floor(sec % 60) : Math.floor(sec % 60); 
     244                        return str; 
     245                } else { 
     246                        return "00:00"; 
     247                } 
     248        } 
     249 
     250        /** Logger * */ 
     251        jwplayer.utils.log = function(msg, obj) { 
     252                if (typeof console != "undefined" && typeof console.log != "undefined") { 
     253                        if (obj) { 
     254                                console.log(msg, obj); 
     255                        } else { 
     256                                console.log(msg); 
     257                        } 
     258                } 
     259        }; 
     260 
     261        /** Replacement for getBoundingClientRect, which isn't supported in iOS 3.1.2 **/ 
     262        jwplayer.utils.getBoundingClientRect = function(element) { 
     263                if (typeof element.getBoundingClientRect == "function") { 
     264                        return element.getBoundingClientRect(); 
     265                } else { 
     266                        return {  
     267                                left: element.offsetLeft + document.body.scrollLeft,  
     268                                top: element.offsetTop + document.body.scrollTop,  
     269                                width: element.offsetWidth,  
     270                                height: element.offsetHeight 
     271                        }; 
     272                } 
     273        } 
     274         
    240275})(jwplayer); 
    241276/** 
     
    545580})(jwplayer.utils); 
    546581/** 
     582 * Event namespace defintion for the JW Player 
     583 *  
     584 * @author pablo 
     585 * @version 6.0 
     586 */ 
     587(function(jwplayer) { 
     588        jwplayer.events = { 
     589                // General Events 
     590                COMPLETE : 'COMPLETE', 
     591                ERROR : 'ERROR', 
     592 
     593                // API Events 
     594                API_READY : 'jwplayerAPIReady', 
     595                JWPLAYER_READY : 'jwplayerReady', 
     596                JWPLAYER_FULLSCREEN : 'jwplayerFullscreen', 
     597                JWPLAYER_RESIZE : 'jwplayerResize', 
     598                JWPLAYER_ERROR : 'jwplayerError', 
     599 
     600                // Media Events 
     601                JWPLAYER_MEDIA_BEFOREPLAY : 'jwplayerMediaBeforePlay', 
     602                JWPLAYER_MEDIA_BEFORECOMPLETE : 'jwplayerMediaBeforeComplete', 
     603                JWPLAYER_COMPONENT_SHOW : 'jwplayerComponentShow', 
     604                JWPLAYER_COMPONENT_HIDE : 'jwplayerComponentHide', 
     605                JWPLAYER_MEDIA_BUFFER : 'jwplayerMediaBuffer', 
     606                JWPLAYER_MEDIA_BUFFER_FULL : 'jwplayerMediaBufferFull', 
     607                JWPLAYER_MEDIA_ERROR : 'jwplayerMediaError', 
     608                JWPLAYER_MEDIA_LOADED : 'jwplayerMediaLoaded', 
     609                JWPLAYER_MEDIA_COMPLETE : 'jwplayerMediaComplete', 
     610                JWPLAYER_MEDIA_SEEK : 'jwplayerMediaSeek', 
     611                JWPLAYER_MEDIA_TIME : 'jwplayerMediaTime', 
     612                JWPLAYER_MEDIA_VOLUME : 'jwplayerMediaVolume', 
     613                JWPLAYER_MEDIA_META : 'jwplayerMediaMeta', 
     614                JWPLAYER_MEDIA_MUTE : 'jwplayerMediaMute', 
     615 
     616                // State events 
     617                JWPLAYER_PLAYER_STATE : 'jwplayerPlayerState', 
     618                state : { 
     619                        BUFFERING : 'BUFFERING', 
     620                        IDLE : 'IDLE', 
     621                        PAUSED : 'PAUSED', 
     622                        PLAYING : 'PLAYING', 
     623                        COMPLETED : 'COMPLETED' 
     624                }, 
     625 
     626                // Playlist Events 
     627                JWPLAYER_PLAYLIST_LOADED : 'jwplayerPlaylistLoaded', 
     628                JWPLAYER_PLAYLIST_ITEM : 'jwplayerPlaylistItem', 
     629 
     630                // Instream events 
     631                JWPLAYER_INSTREAM_CLICK : 'jwplayerInstreamClicked', 
     632                JWPLAYER_INSTREAM_DESTROYED : 'jwplayerInstreamDestroyed' 
     633        }; 
     634 
     635})(jwplayer); 
     636/** 
     637 * Event dispatcher for the JW Player 
     638 * 
     639 * @author zach 
     640 * @modified pablo 
     641 * @version 6.0 
     642 */ 
     643(function(jwplayer) { 
     644        jwplayer.events.eventdispatcher = function(id, debug) { 
     645                var _id = id, 
     646                        _debug = debug, 
     647                        _listeners, _globallisteners; 
     648                 
     649                /** Clears all event listeners **/ 
     650                this.resetEventListeners = function() { 
     651                        _listeners = {}; 
     652                        _globallisteners = []; 
     653                }; 
     654                 
     655                this.resetEventListeners(); 
     656                 
     657                /** Add an event listener for a specific type of event. **/ 
     658                this.addEventListener = function(type, listener, count) { 
     659                        try { 
     660                                if (!jwplayer.utils.exists(_listeners[type])) { 
     661                                        _listeners[type] = []; 
     662                                } 
     663                                 
     664                                if (typeof(listener) == "string") { 
     665                                        eval("listener = " + listener); 
     666                                } 
     667                                _listeners[type].push({ 
     668                                        listener: listener, 
     669                                        count: count 
     670                                }); 
     671                        } catch (err) { 
     672                                jwplayer.utils.log("error", err); 
     673                        } 
     674                        return false; 
     675                }; 
     676                 
     677                 
     678                /** Remove an event listener for a specific type of event. **/ 
     679                this.removeEventListener = function(type, listener) { 
     680                        if (!_listeners[type]) { 
     681                                return; 
     682                        } 
     683                        try { 
     684                                for (var listenerIndex = 0; listenerIndex < _listeners[type].length; listenerIndex++) { 
     685                                        if (_listeners[type][listenerIndex].listener.toString() == listener.toString()) { 
     686                                                _listeners[type].splice(listenerIndex, 1); 
     687                                                break; 
     688                                        } 
     689                                } 
     690                        } catch (err) { 
     691                                jwplayer.utils.log("error", err); 
     692                        } 
     693                        return false; 
     694                }; 
     695                 
     696                /** Add an event listener for all events. **/ 
     697                this.addGlobalListener = function(listener, count) { 
     698                        try { 
     699                                if (typeof(listener) == "string") { 
     700                                        eval("listener = " + listener); 
     701                                } 
     702                                _globallisteners.push({ 
     703                                        listener: listener, 
     704                                        count: count 
     705                                }); 
     706                        } catch (err) { 
     707                                jwplayer.utils.log("error", err); 
     708                        } 
     709                        return false; 
     710                }; 
     711                 
     712                /** Add an event listener for all events. **/ 
     713                this.removeGlobalListener = function(listener) { 
     714                        if (!listener) { 
     715                                return; 
     716                        } 
     717                        try { 
     718                                for (var globalListenerIndex = 0; globalListenerIndex < _globallisteners.length; globalListenerIndex++) { 
     719                                        if (_globallisteners[globalListenerIndex].listener.toString() == listener.toString()) { 
     720                                                _globallisteners.splice(globalListenerIndex, 1); 
     721                                                break; 
     722                                        } 
     723                                } 
     724                        } catch (err) { 
     725                                jwplayer.utils.log("error", err); 
     726                        } 
     727                        return false; 
     728                }; 
     729                 
     730                 
     731                /** Send an event **/ 
     732                this.sendEvent = function(type, data) { 
     733                        if (!jwplayer.utils.exists(data)) { 
     734                                data = {}; 
     735                        } 
     736                        jwplayer.utils.extend(data, { 
     737                                id: _id, 
     738                                version: jwplayer.version, 
     739                                type: type 
     740                        }); 
     741                        if (_debug) { 
     742                                jwplayer.utils.log(type, data); 
     743                        } 
     744                        if (typeof _listeners[type] != "undefined") { 
     745                                for (var listenerIndex = 0; listenerIndex < _listeners[type].length; listenerIndex++) { 
     746                                        try { 
     747                                                _listeners[type][listenerIndex].listener(data); 
     748                                        } catch (err) { 
     749                                                jwplayer.utils.log("There was an error while handling a listener: " + err.toString(), _listeners[type][listenerIndex].listener); 
     750                                        } 
     751                                        if (_listeners[type][listenerIndex]) { 
     752                                                if (_listeners[type][listenerIndex].count === 1) { 
     753                                                        delete _listeners[type][listenerIndex]; 
     754                                                } else if (_listeners[type][listenerIndex].count > 0) { 
     755                                                        _listeners[type][listenerIndex].count = _listeners[type][listenerIndex].count - 1; 
     756                                                } 
     757                                        } 
     758                                } 
     759                        } 
     760                        for (var globalListenerIndex = 0; globalListenerIndex < _globallisteners.length; globalListenerIndex++) { 
     761                                try { 
     762                                        _globallisteners[globalListenerIndex].listener(data); 
     763                                } catch (err) { 
     764                                        jwplayer.utils.log("There was an error while handling a listener: " + err.toString(), _globallisteners[globalListenerIndex].listener); 
     765                                } 
     766                                if (_globallisteners[globalListenerIndex]) { 
     767                                        if (_globallisteners[globalListenerIndex].count === 1) { 
     768                                                delete _globallisteners[globalListenerIndex]; 
     769                                        } else if (_globallisteners[globalListenerIndex].count > 0) { 
     770                                                _globallisteners[globalListenerIndex].count = _globallisteners[globalListenerIndex].count - 1; 
     771                                        } 
     772                                } 
     773                        } 
     774                }; 
     775        }; 
     776})(jwplayer); 
     777/** 
    547778 * jwplayer.html5 namespace 
    548779 * 
     
    581812                JW_CSS_RIGHT = "right", 
    582813                JW_CSS_100PCT = "100%", 
     814                JW_CSS_SMOOTH_EASE = "width .25s linear 0s, left .25s linear 0s, opacity .25s ease 0s" 
    583815                 
    584816                CB_CLASS = '.jwcontrolbar'; 
     
    586818        /** HTML5 Controlbar class **/ 
    587819        html5.controlbar = function(api, config) { 
    588                 var _api; 
    589  
    590                 var _defaults = { 
    591                         backgroundcolor : "", 
    592                         margin : 10, 
    593                         font : "Arial,sans-serif", 
    594                         fontsize : 10, 
    595                         fontcolor : parseInt("000000", 16), 
    596                         fontstyle : "normal", 
    597                         fontweight : "bold", 
    598                         buttoncolor : parseInt("ffffff", 16), 
    599                         // position : html5.view.positions.BOTTOM, 
    600                         position: "OVER", 
    601                         idlehide : false, 
    602                         hideplaylistcontrols : false, 
    603                         forcenextprev : false, 
    604                         layout : { 
    605                                 "left" : { 
    606                                         "position" : "left", 
    607                                         "elements" : [ { 
    608                                                 "name" : "play", 
    609                                                 "type" : CB_BUTTON 
    610                                         }, { 
    611                                                 "name" : "divider", 
    612                                                 "type" : CB_DIVIDER 
    613                                         }, { 
    614                                                 "name" : "prev", 
    615                                                 "type" : CB_BUTTON 
    616                                         }, { 
    617                                                 "name" : "divider", 
    618                                                 "type" : CB_DIVIDER 
    619                                         }, { 
    620                                                 "name" : "next", 
    621                                                 "type" : CB_BUTTON 
    622                                         }, { 
    623                                                 "name" : "divider", 
    624                                                 "type" : CB_DIVIDER 
    625                                         }, { 
    626                                                 "name" : "elapsed", 
    627                                                 "type" : CB_TEXT 
    628                                         } ] 
    629                                 }, 
    630                                 "center" : { 
    631                                         "position" : "center", 
    632                                         "elements" : [ { 
    633                                                 "name" : "time", 
    634                                                 "type" : CB_SLIDER 
    635                                         } ] 
    636                                 }, 
    637                                 "right" : { 
    638                                         "position" : "right", 
    639                                         "elements" : [ { 
    640                                                 "name" : "duration", 
    641                                                 "type" : CB_TEXT 
    642                                         }, { 
    643                                                 "name" : "blank", 
    644                                                 "type" : CB_BUTTON 
    645                                         }, { 
    646                                                 "name" : "divider", 
    647                                                 "type" : CB_DIVIDER 
    648                                         }, { 
    649                                                 "name" : "mute", 
    650                                                 "type" : CB_BUTTON 
    651                                         }, { 
    652                                                 "name" : "volume", 
    653                                                 "type" : CB_SLIDER 
    654                                         }, { 
    655                                                 "name" : "divider", 
    656                                                 "type" : CB_DIVIDER 
    657                                         }, { 
    658                                                 "name" : "fullscreen", 
    659                                                 "type" : CB_BUTTON 
    660                                         } ] 
    661                                 } 
    662                         } 
    663                 }; 
    664                  
    665                 var _settings, _layout, _elements; 
    666                  
    667                 var _controlbar, _id; 
    668                  
    669                 var _toggles = { 
    670                         play: "pause", 
    671                         mute: "unmute", 
    672                         fullscreen: "normalscreen" 
    673                 } 
    674                  
    675                 var _toggleStates = { 
    676                         play: false, 
    677                         mute: false, 
    678                         fullscreen: false 
    679                 } 
    680                  
    681                 var _buttonMapping = { 
    682                         play: _play, 
    683                         mute: _mute, 
    684                         fullscreen: _fullscreen 
    685                 }; 
     820                var _api, 
     821 
     822                        _defaults = { 
     823                                backgroundcolor : "", 
     824                                margin : 10, 
     825                                font : "Arial,sans-serif", 
     826                                fontsize : 10, 
     827                                fontcolor : parseInt("000000", 16), 
     828                                fontstyle : "normal", 
     829                                fontweight : "bold", 
     830                                buttoncolor : parseInt("ffffff", 16), 
     831                                // position : html5.view.positions.BOTTOM, 
     832                                position: "OVER", 
     833                                idlehide : false, 
     834                                hideplaylistcontrols : false, 
     835                                forcenextprev : false, 
     836                                layout : { 
     837                                        left: { 
     838                                                position: "left", 
     839                                                elements: [ { 
     840                                                        name: "play", 
     841                                                        type: CB_BUTTON 
     842                                                }, { 
     843                                                        name: "divider", 
     844                                                        type: CB_DIVIDER 
     845                                                }, { 
     846                                                        name: "prev", 
     847                                                        type: CB_BUTTON 
     848                                                }, { 
     849                                                        name: "divider", 
     850                                                        type: CB_DIVIDER 
     851                                                }, { 
     852                                                        name: "next", 
     853                                                        type: CB_BUTTON 
     854                                                }, { 
     855                                                        name: "divider", 
     856                                                        type: CB_DIVIDER 
     857                                                }, { 
     858                                                        name: "elapsed", 
     859                                                        type: CB_TEXT 
     860                                                } ] 
     861                                        }, 
     862                                        center: { 
     863                                                position: "center", 
     864                                                elements: [ { 
     865                                                        name: "time", 
     866                                                        type: CB_SLIDER 
     867                                                } ] 
     868                                        }, 
     869                                        right: { 
     870                                                position: "right", 
     871                                                elements: [ { 
     872                                                        name: "duration", 
     873                                                        type: CB_TEXT 
     874                                                }, { 
     875                                                        name: "blank", 
     876                                                        type: CB_BUTTON 
     877                                                }, { 
     878                                                        name: "divider", 
     879                                                        type: CB_DIVIDER 
     880                                                }, { 
     881                                                        name: "mute", 
     882                                                        type: CB_BUTTON 
     883                                                }, { 
     884                                                        name: "volume", 
     885                                                        type: CB_SLIDER 
     886                                                }, { 
     887                                                        name: "divider", 
     888                                                        type: CB_DIVIDER 
     889                                                }, { 
     890                                                        name: "fullscreen", 
     891                                                        type: CB_BUTTON 
     892                                                } ] 
     893                                        } 
     894                                } 
     895                        }, 
     896                 
     897                        _settings,  
     898                        _layout,  
     899                        _elements,  
     900                        _controlbar,  
     901                        _id, 
     902                        _duration, 
     903                         
     904                        _toggles = { 
     905                                play: "pause", 
     906                                mute: "unmute", 
     907                                fullscreen: "normalscreen" 
     908                        }, 
     909                         
     910                        _toggleStates = { 
     911                                play: false, 
     912                                mute: false, 
     913                                fullscreen: false 
     914                        }, 
     915                         
     916                        _buttonMapping = { 
     917                                play: _play, 
     918                                mute: _mute, 
     919                                fullscreen: _fullscreen, 
     920                                next: _next, 
     921                                prev: _prev 
     922                        }, 
     923                         
     924                        _sliderMapping = { 
     925                                time: _seek, 
     926                                volume: _volume 
     927                        } 
     928                 
     929                 
    686930 
    687931                function _init() { 
     
    690934                        _api = api; 
    691935                         
     936 
    692937                        config = _utils.extend({}, config); 
    693938                        _id = _api.id + "_controlbar"; 
     939                        _duration = 0; 
    694940 
    695941                        _controlbar = _createSpan(); 
    696942                        _controlbar.id = _id; 
    697943                        _controlbar.className = "jwcontrolbar"; 
     944 
     945                        // Slider listeners 
     946                        window.addEventListener('mousemove', _sliderMouseEvent, false); 
     947                        window.addEventListener('mouseup', _sliderMouseEvent, false); 
    698948 
    699949                        (new html5.skinloader(config.skin, function(skin) { 
     
    703953                                _createStyles(); 
    704954                                _buildControlbar(); 
    705                         }, function(err) { console.log(err); })); 
    706                          
    707                          
    708                 } 
     955                                _addEventListeners(); 
     956                        }, function(err) { _utils.log(err); })); 
     957                } 
     958                 
     959                function _addEventListeners() { 
     960                        _api.addEventListener(jwplayer.events.JWPLAYER_MEDIA_TIME, _timeUpdated); 
     961                        _api.addEventListener(jwplayer.events.JWPLAYER_PLAYER_STATE, _stateHandler); 
     962                        _api.addEventListener(jwplayer.events.JWPLAYER_MEDIA_MUTE, _muteHandler); 
     963                        _api.addEventListener(jwplayer.events.JWPLAYER_MEDIA_VOLUME, _volumeHandler); 
     964                        _api.addEventListener(jwplayer.events.JWPLAYER_MEDIA_BUFFER, _bufferHandler); 
     965                } 
     966                 
     967                function _timeUpdated(evt) { 
     968                        _duration = evt.duration; 
     969                         
     970                        if (_elements.elapsed) { 
     971                                _elements.elapsed.innerHTML = _utils.timeFormat(evt.position); 
     972                        } 
     973                        if (_elements.duration) { 
     974                                _elements.duration.innerHTML = _utils.timeFormat(evt.duration); 
     975                        } 
     976                        if (evt.duration > 0) { 
     977                                _setProgress(evt.position / evt.duration); 
     978                        } else { 
     979                                _setProgress(0); 
     980                        } 
     981                } 
     982                 
     983                function _stateHandler(evt) { 
     984                        switch (evt.newstate) { 
     985                        case jwplayer.events.state.PLAYING: 
     986                        case jwplayer.events.state.BUFFERING: 
     987                                if (_elements['timeSliderThumb']) { 
     988                                        _elements['timeSliderThumb'].style.opacity = 1; 
     989                                } 
     990                                if (_elements["timeRail"]) { 
     991                                        _elements["timeRail"].className = "jwrail jwsmooth"; 
     992                                } 
     993                                _toggleButton("play", true); 
     994                                break; 
     995                        case jwplayer.events.state.PAUSED: 
     996                                if (!_dragging) { 
     997                                        _toggleButton("play", false); 
     998                                } 
     999                                break; 
     1000                        case jwplayer.events.state.IDLE: 
     1001                        case jwplayer.events.state.COMPLETED: 
     1002                                _toggleButton("play", false); 
     1003                                if (_elements['timeSliderThumb']) { 
     1004                                        _elements['timeSliderThumb'].style.opacity = 0; 
     1005                                } 
     1006                                _setBuffer(0); 
     1007                                _timeUpdated({ position: 0, duration: 0}); 
     1008                                if (_elements["timeRail"]) { 
     1009                                        _elements["timeRail"].className = "jwrail"; 
     1010                                } 
     1011                                break; 
     1012                        } 
     1013                } 
     1014                 
     1015                function _muteHandler(evt) { 
     1016                        _toggleButton("mute", evt.mute); 
     1017                } 
     1018 
     1019                function _volumeHandler(evt) { 
     1020                        _setVolume(evt.volume / 100); 
     1021                } 
     1022 
     1023                function _bufferHandler(evt) { 
     1024                        _setBuffer(evt.bufferPercent / 100); 
     1025                } 
     1026 
    7091027 
    7101028                /** 
     
    7211039                        }); 
    7221040                         
    723                         _style(_internalSelector(".text"), { 
     1041                        _style(_internalSelector(".jwtext"), { 
    7241042                                font: _settings.fontsize + "px/" + _getSkinElement("background").height + "px " + _settings.font, 
    7251043                                color: _settings.fontcolor, 
     
    7471065                                left: _getSkinElement('capLeft').width, 
    7481066                                right: _getSkinElement('capRight').width, 
    749                                 'backgroundRepeat': "repeat-x" 
     1067                                'background-repeat': "repeat-x" 
    7501068                        }, true); 
    7511069 
     
    7841102                        var element = _createSpan(); 
    7851103                        //element.id = _createElementId(name); 
    786                         element.className = name; 
    787                          
    788                         var center = nocenter ? "" : "center"; 
     1104                        element.className = 'jw'+name; 
     1105                         
     1106                        var center = nocenter ? " left center" : " center"; 
    7891107 
    7901108                        var skinElem = _getSkinElement(name); 
     
    7981116                        if (stretch) { 
    7991117                                newStyle = { 
    800                                         background: "url('" + skinElem.src + "') "+center+" repeat-x" 
     1118                                        background: "url('" + skinElem.src + "') repeat-x " + center 
    8011119                                }; 
    8021120                        } else { 
    8031121                                newStyle = { 
    804                                         background: "url('" + skinElem.src + "') "+center+" no-repeat", 
     1122                                        background: "url('" + skinElem.src + "') no-repeat" + center, 
    8051123                                        width: skinElem.width 
    8061124                                }; 
    8071125                        } 
    8081126                         
    809                         _style(_internalSelector('.'+name), _utils.extend(newStyle, style)); 
     1127                        _style(_internalSelector('.jw'+name), _utils.extend(newStyle, style)); 
    8101128                        _elements[name] = element; 
    8111129                        return element; 
     
    8131131 
    8141132                function _buildButton(name) { 
     1133                        if (!_getSkinElement(name + "Button").src) { 
     1134                                return null; 
     1135                        } 
     1136                         
    8151137                        var element = document.createElement("button"); 
    8161138                        //element.id = _createElementId(name); 
    817                         element.className = name; 
    818                         element.addEventListener("click", (function(name) { return function() { _buttonClickHandler(name) } })(name)); 
     1139                        element.className = 'jw'+name; 
     1140                        element.addEventListener("click", _buttonClickHandler(name), false); 
    8191141 
    8201142                        var outSkin = _getSkinElement(name + "Button"); 
     
    8221144                         
    8231145                        element.innerHTML = "&nbsp;"; 
    824                         if (!_getSkinElement(name + "Button").src) { 
    825                                 return element; 
    826                         } 
    827                          
    828                         _buttonStyle(_internalSelector('.'+name), outSkin, overSkin); 
     1146                         
     1147                        _buttonStyle(_internalSelector('.jw'+name), outSkin, overSkin); 
    8291148                        var toggle = _toggles[name]; 
    8301149                        if (toggle) { 
    831                                 _buttonStyle(_internalSelector('.'+name+'.toggle'), _getSkinElement(toggle+"Button"), _getSkinElement(toggle+"ButtonOver")); 
     1150                                _buttonStyle(_internalSelector('.jw'+name+'.jwtoggle'), _getSkinElement(toggle+"Button"), _getSkinElement(toggle+"ButtonOver")); 
    8321151                        } 
    8331152 
     
    8551174                 
    8561175                function _buttonClickHandler(name) { 
    857                         if (_buttonMapping[name]) { 
    858                                 _buttonMapping[name](); 
     1176                        return function() { 
     1177                                if (_buttonMapping[name]) { 
     1178                                        _buttonMapping[name](); 
     1179                                } 
    8591180                        } 
    8601181                } 
     
    8671188                                _api.jwPlay(); 
    8681189                        } 
    869                         _toggleButton("play"); 
    8701190                } 
    8711191                 
    8721192                function _mute() { 
    873                         _toggleButton("mute"); 
     1193                        _api.jwSetMute(); 
     1194                } 
     1195                 
     1196                function _volume(pct) { 
     1197                        if (pct < 0.1) pct = 0; 
     1198                        if (pct > 0.9) pct = 1; 
     1199                        _api.jwSetVolume(pct * 100) 
     1200                } 
     1201                 
     1202                function _seek(pct) { 
     1203                        if (!_dragging) { 
     1204                                _api.jwPlay(); 
     1205                        } 
     1206                        _api.jwSeek(pct * _duration); 
    8741207                } 
    8751208                 
     
    8771210                        _toggleButton("fullscreen"); 
    8781211                } 
    879                  
    880                 function _toggleButton(name) { 
    881                         _elements[name].className = name + (_toggleStates[name] ? "" : " toggle"); 
    882                         _toggleStates[name] ^= true; 
     1212 
     1213                function _next() { 
     1214                        _api.jwPlaylistNext(); 
     1215                } 
     1216 
     1217                function _prev() { 
     1218                        _api.jwPlaylistNext(); 
     1219                } 
     1220 
     1221                function _toggleButton(name, state) { 
     1222                        if (!_utils.exists(state)) { 
     1223                                state = !_toggleStates[name]; 
     1224                        } 
     1225                        if (_elements[name]) { 
     1226                                _elements[name].className = 'jw' + name + (state ? " jwtoggle" : ""); 
     1227                        } 
     1228                        _toggleStates[name] = state; 
    8831229                } 
    8841230                 
    8851231                function _createElementId(name) { 
    886                         //return (_id + "_" + name + Math.round(Math.random()*10000000)); 
    8871232                        return _id + "_" + name; 
    8881233                } 
     
    8911236                        var element = _createSpan(); 
    8921237                        element.id = _createElementId(name);  
    893                         element.className = "text " + name; 
     1238                        element.className = "jwtext jw" + name; 
    8941239                         
    8951240                        var css = {}; 
     
    9011246                        } 
    9021247 
    903                         _style(_internalSelector('.'+name), css); 
     1248                        _style(_internalSelector('.jw'+name), css); 
    9041249                        element.innerHTML = "00:00"; 
    9051250                        _elements[name] = element; 
     
    9101255                        if (divider.width) { 
    9111256                                var element = _createSpan(); 
    912                                 element.className = "blankDivider"; 
     1257                                element.className = "jwblankDivider"; 
    9131258                                _style(element, { 
    9141259                                        width: parseInt(divider.width) 
     
    9241269                function _buildSlider(name) { 
    9251270                        var slider = _createSpan(); 
    926                         //slider.id = _createElementId(name); 
    927                         slider.className = "slider " + name; 
    928  
    929                         var rail = _createSpan(); 
    930                         rail.className = "rail"; 
    931  
    932                         var railElements = ['Rail', 'Buffer', 'Progress']; 
    933  
    934                         for (var i=0; i<railElements.length; i++) { 
    935                                 var element = _buildImage(name + "Slider" + railElements[i], null, true, (name=="volume")); 
    936                                 if (element) { 
    937                                         element.className += " stretch"; 
    938                                         rail.appendChild(element); 
    939                                 } 
    940                         } 
    941                          
    942                         var thumb = _buildImage(name + "SliderThumb"); 
    943                         if (thumb) { 
    944                                 thumb.className += " thumb"; 
    945                                 rail.appendChild(thumb); 
    946                         } 
     1271                        slider.className = "jwslider jw" + name; 
     1272 
    9471273 
    9481274                        var capLeft = _buildImage(name + "SliderCapLeft"); 
    9491275                        var capRight = _buildImage(name + "SliderCapRight"); 
    950                         if (capRight) capRight.className += " capRight"; 
    951  
     1276                        if (capRight) capRight.className += " jwcapRight"; 
     1277 
     1278                        var rail = _buildSliderRail(name); 
     1279                         
    9521280                        if (capLeft) slider.appendChild(capLeft); 
    9531281                        slider.appendChild(rail); 
    9541282                        if (capLeft) slider.appendChild(capRight); 
    9551283 
    956                         _style(_internalSelector("." + name + " .rail"), { 
     1284                        _style(_internalSelector(".jw" + name + " .jwrail"), { 
    9571285                                left: _getSkinElement(name+"SliderCapLeft").width, 
    9581286                                right: _getSkinElement(name+"SliderCapRight").width, 
    9591287                        }); 
     1288 
     1289                        _elements[name] = slider; 
    9601290 
    9611291                        if (name == "time") { 
     
    9671297                        } 
    9681298 
    969                         _elements[name] = slider; 
    970                          
    971                 return slider; 
    972                 } 
     1299                         
     1300                        return slider; 
     1301                } 
     1302                 
     1303                function _buildSliderRail(name) { 
     1304                        var rail = _createSpan(); 
     1305                        rail.className = "jwrail jwsmooth"; 
     1306 
     1307                        var railElements = ['Rail', 'Buffer', 'Progress']; 
     1308 
     1309                        for (var i=0; i<railElements.length; i++) { 
     1310                                var element = _buildImage(name + "Slider" + railElements[i], null, true, (name=="volume")); 
     1311                                if (element) { 
     1312                                        element.className += " jwstretch"; 
     1313                                        rail.appendChild(element); 
     1314                                } 
     1315                        } 
     1316                         
     1317                        var thumb = _buildImage(name + "SliderThumb"); 
     1318                        if (thumb) { 
     1319                                thumb.className += " jwthumb"; 
     1320                                thumb.style.opacity = 0; 
     1321                                rail.appendChild(thumb); 
     1322                        } 
     1323                         
     1324                        rail.addEventListener('mousedown', _sliderMouseDown(name), false); 
     1325                         
     1326                        _elements[name+'Rail'] = rail; 
     1327                         
     1328                        return rail; 
     1329                } 
     1330                 
     1331                var _dragging; 
     1332                 
     1333                function _sliderMouseDown(name) { 
     1334                        return (function(evt) { 
     1335                                if (evt.button != 0) 
     1336                                        return; 
     1337                                 
     1338                                _elements[name+'Rail'].className = "jwrail"; 
     1339                                 
     1340                                if (name == "time") { 
     1341                                        if (_api.jwGetState() != jwplayer.events.state.IDLE) { 
     1342                                                _api.jwPause(); 
     1343                                                _dragging = name; 
     1344                                        } 
     1345                                } else { 
     1346                                        _dragging = name; 
     1347                                } 
     1348                        }); 
     1349                } 
     1350                 
     1351                var _lastSeekTime = 0; 
     1352                 
     1353                function _sliderMouseEvent(evt) { 
     1354                        if (!_dragging || evt.button != 0) { 
     1355                                return; 
     1356                        } 
     1357                         
     1358                        var rail = _elements[_dragging].getElementsByClassName('jwrail')[0], 
     1359                                railRect = _utils.getBoundingClientRect(rail), 
     1360                                pct = (evt.clientX - railRect.left) / railRect.width; 
     1361                         
     1362                        if (evt.type == 'mouseup') { 
     1363                                var name = _dragging; 
     1364                                _elements[name+'Rail'].className = "jwrail jwsmooth"; 
     1365                                _dragging = null; 
     1366                                _sliderMapping[name](pct); 
     1367                        } else { 
     1368                                if (_dragging == "time") { 
     1369                                        _setProgress(pct); 
     1370                                } else { 
     1371                                        _setVolume(pct); 
     1372                                } 
     1373                                var currentTime = (new Date()).getTime(); 
     1374                                if (currentTime - _lastSeekTime > 500) { 
     1375                                        _lastSeekTime = currentTime; 
     1376                                        _sliderMapping[_dragging](pct); 
     1377                                } 
     1378                        } 
     1379                } 
     1380 
    9731381         
    9741382                function _styleTimeSlider(slider) { 
    9751383                        if (_elements['timeSliderThumb']) { 
    976                                 _style(_internalSelector(".timeSliderThumb"), { 
     1384                                _style(_internalSelector(".jwtimeSliderThumb"), { 
    9771385                                        'margin-left': (_getSkinElement("timeSliderThumb").width/-2) 
    9781386                                }); 
     
    9891397                                railWidth = _getSkinElement("volumeSliderRail").width; 
    9901398                         
    991                         _style(_internalSelector(".volume"), { 
     1399                        _style(_internalSelector(".jwvolume"), { 
    9921400                                width: (capLeftWidth + railWidth + capRightWidth) 
    9931401                        }); 
     
    10041412                        _controlbar.appendChild(_groups.right); 
    10051413                         
    1006                         _style(_internalSelector(".right"), { 
     1414                        _style(_internalSelector(".jwright"), { 
    10071415                                right: _getSkinElement("capRight").width 
    10081416                        }); 
     
    10121420                function _buildGroup(pos) { 
    10131421                        var elem = _createSpan(); 
    1014                         elem.className = "group " + pos; 
     1422                        elem.className = "jwgroup jw" + pos; 
    10151423                        _groups[pos] = elem; 
    10161424                        if (_layout[pos]) { 
     
    10311439 
    10321440                var _resize = this.resize = function(width, height) { 
    1033                         _style(_internalSelector('.group.center'), { 
    1034                                 left: _utils.parseDimension(_groups.left.offsetWidth) + _getSkinElement("capLeft").width, 
    1035                                 right: _utils.parseDimension(_groups.right.offsetWidth) + _getSkinElement("capRight").width 
     1441                        _style(_internalSelector('.jwgroup.jwcenter'), { 
     1442                                left: Math.round(_utils.parseDimension(_groups.left.offsetWidth) + _getSkinElement("capLeft").width), 
     1443                                right: Math.round(_utils.parseDimension(_groups.right.offsetWidth) + _getSkinElement("capRight").width) 
    10361444                        }); 
    10371445                } 
     
    10431451                var _setBuffer = this.setBuffer = function(pct) { 
    10441452                        pct = Math.min(Math.max(0, pct), 1); 
    1045                         _elements['timeSliderBuffer'].style.width = 100 * pct + "%"; 
     1453                        _elements['timeSliderBuffer'].style.width = pct * _utils.getBoundingClientRect(_elements['timeSliderRail']).width + "px"; 
    10461454                } 
    10471455 
    10481456                function _sliderPercent(name, pct, fixedWidth) { 
     1457                        if (!_elements[name]) return; 
     1458 
    10491459                        pct = Math.min(Math.max(0, pct), 1); 
    10501460                         
    10511461                        var progress = _elements[name+'SliderProgress']; 
    10521462                        var thumb = _elements[name+'SliderThumb']; 
    1053                          
     1463                        var width = pct * _utils.getBoundingClientRect(_elements[name+'SliderRail']).width + "px"; 
     1464                 
    10541465                        if (progress) { 
    1055                                 progress.style.width = 100 * pct + "%"; 
     1466                                progress.style.width = width;  
    10561467                        } 
    10571468                        if (thumb) { 
    1058                                 thumb.style.left = pct * _utils.parseDimension(_elements[name+'SliderRail'].clientWidth) + "px"; 
    1059                                 //thumb.style.opacity = 0.5; //(pct <= 0 || pct >= 1) ? 0 : 1; 
    1060                         } 
    1061                 } 
    1062                  
    1063                 var _setVolume = this.setVolume = function(pct) { 
     1469                                thumb.style.left = width; 
     1470                        } 
     1471                } 
     1472                 
     1473                function _setVolume (pct) { 
    10641474                        _sliderPercent('volume', pct, true); 
    10651475                } 
    10661476 
    1067                 var _setProgress = this.setProgress = function(pct) { 
     1477                function _setProgress(pct) { 
    10681478                        _sliderPercent('time', pct); 
    10691479                } 
     
    11051515                        'user-drag': JW_CSS_NONE 
    11061516                }); 
    1107             _style(CB_CLASS+' .group', { 
     1517            _style(CB_CLASS+' .jwgroup', { 
    11081518                display: JW_CSS_INLINE 
    11091519            }); 
    1110             _style(CB_CLASS+' span, '+CB_CLASS+' .group button,'+CB_CLASS+' .left', { 
     1520            _style(CB_CLASS+' span, '+CB_CLASS+' .jwgroup button,'+CB_CLASS+' .jwleft', { 
    11111521                position: JW_CSS_RELATIVE, 
    11121522                        'float': JW_CSS_LEFT 
    11131523            }); 
    1114                 _style(CB_CLASS+' .right', { 
    1115                         position: JW_CSS_RELATIVE, 
    1116                         'float': JW_CSS_RIGHT 
     1524                _style(CB_CLASS+' .jwright', { 
     1525                        position: JW_CSS_ABSOLUTE 
    11171526                }); 
    1118             _style(CB_CLASS+' .center', { 
    1119                 position: JW_CSS_ABSOLUTE, 
    1120                         'float': JW_CSS_LEFT 
     1527            _style(CB_CLASS+' .jwcenter', { 
     1528                position: JW_CSS_ABSOLUTE 
    11211529            }); 
    11221530            _style(CB_CLASS+' button', { 
     
    11251533                border: JW_CSS_NONE, 
    11261534                cursor: 'pointer', 
    1127                 '-webkit-transition': 'background .5s', 
    1128                 '-moz-transition': 'background .5s', 
    1129                 '-o-transition': 'background 1s' 
     1535                '-webkit-transition': 'background-image .25s', 
     1536                '-moz-transition': 'background-image .25s', 
     1537                '-o-transition': 'background-image .25s' 
    11301538            }); 
    1131             _style(CB_CLASS+' button:hover', { 
    1132                 '-webkit-transition': 'background 0s', 
    1133                 '-moz-transition': 'background 0s', 
    1134                 '-o-transition': 'background 0s' 
    1135             }); 
    1136             _style(CB_CLASS+' .capRight', {  
     1539            _style(CB_CLASS+' .jwcapRight', {  
    11371540                        right: 0, 
    11381541                        position: JW_CSS_ABSOLUTE 
    11391542                }); 
    1140             _style(CB_CLASS+' .time,' + CB_CLASS + ' .group span.stretch', { 
     1543            _style(CB_CLASS+' .jwtime,' + CB_CLASS + ' .jwgroup span.jwstretch', { 
    11411544                position: JW_CSS_ABSOLUTE, 
    11421545                height: JW_CSS_100PCT, 
     
    11441547                left: 0 
    11451548            }); 
    1146             _style(CB_CLASS+' .rail,' + CB_CLASS + ' .thumb', { 
     1549            _style(CB_CLASS+' .jwrail,' + CB_CLASS + ' .jwthumb', { 
    11471550                position: JW_CSS_ABSOLUTE, 
    11481551                height: JW_CSS_100PCT, 
    11491552                cursor: 'pointer' 
    11501553            }); 
    1151             _style(CB_CLASS + ' .timeSliderThumb', { 
    1152                 '-webkit-transition': 'left .5s linear 0s, opacity .5s ease .5s', 
    1153                 '-moz-transition': 'left .5s linear 0s, opacity .5s ease .5s' 
    1154                 //-o-transition: 'left .5s linear 0s, opacity .5s ease .5s' -- this produces console errors in Opera 
    1155             });              
    1156             _style(CB_CLASS + ' .timeSliderProgress,' + CB_CLASS + ' .timeSliderBuffer', { 
    1157                 '-webkit-transition': 'width .5s linear', 
    1158                 '-moz-transition': 'width .5s linear', 
    1159                 '-o-transition': 'width .5s linear' 
     1554            _style(CB_CLASS + ' .jwtime .jwsmooth span', { 
     1555                '-webkit-transition': JW_CSS_SMOOTH_EASE, 
     1556                '-moz-transition': JW_CSS_SMOOTH_EASE, 
     1557                '-o-transition': JW_CSS_SMOOTH_EASE 
    11601558            }); 
    1161             _style(CB_CLASS + ' .volume', { 
    1162                 display: JW_CSS_INLINE_BLOCK 
    1163             }); 
    1164             _style(CB_CLASS + ' .divider+.divider', { 
     1559            _style(CB_CLASS + ' .jwdivider+.jwdivider', { 
    11651560                display: JW_CSS_NONE 
    11661561            }); 
    1167             _style(CB_CLASS + ' .text', { 
     1562            _style(CB_CLASS + ' .jwtext', { 
    11681563                        padding: '0 5px', 
    1169                         textAlign: 'center' 
     1564                        'text-align': 'center' 
    11701565                }); 
    11711566 
     
    11731568         
    11741569        _generalStyles(); 
     1570         
    11751571})(jwplayer.html5);/** 
    11761572 * jwplayer.html5 API 
     
    11801576 */ 
    11811577(function(html5) { 
     1578        var _utils = jwplayer.utils; 
     1579         
    11821580        html5.controller = function(model, view) { 
    1183                 var _model,  
     1581                var _model = model,  
    11841582                        _view = view, 
    1185                         _video, _controlbar; 
    1186                  
     1583                        _video = model.video, 
     1584                        _debug = 'console', 
     1585                        _eventDispatcher = new jwplayer.events.eventdispatcher(_model.id, _debug); 
     1586                 
     1587                _utils.extend(this, _eventDispatcher); 
     1588 
    11871589                function _init() { 
    1188                         _model = model; 
    1189                         _view = view; 
    1190                         _video = model.video; 
    1191                         _controlbar = view.controlbar; 
     1590                        _model.addGlobalListener(_forward); 
     1591                } 
     1592                 
     1593                function _forward(evt) { 
     1594                        _eventDispatcher.sendEvent(evt.type, evt); 
     1595                } 
     1596 
     1597                var file; 
     1598                 
     1599                this.load = function(item) { 
     1600                        if (_video.getTag().canPlayType("video/mp4")) { 
     1601                                file = "http://playertest.longtailvideo.com/bunny.mp4";          
     1602                        } else if (_video.getTag().canPlayType("video/webm")) { 
     1603                                file = "http://playertest.longtailvideo.com/bunny.webm";                 
     1604                        } else { 
     1605                                file = "http://playertest.longtailvideo.com/bunny.ogv";          
     1606                        } 
    11921607                } 
    11931608                 
    11941609                this.play = function() { 
    1195                         if (_video.getTag().canPlayType("video/mp4")) { 
    1196                                 _video.load("http://content.bitsontherun.com/videos/nPripu9l-1ahmry41.mp4");             
    1197                         } else { 
    1198                                 _video.load("http://content.bitsontherun.com/videos/nPripu9l-1Lq5Mnwq.webm");            
     1610                        if (_model.state == jwplayer.events.state.IDLE) { 
     1611                                _video.load(file); 
    11991612                        } 
    12001613                        _video.play(); 
     
    12061619 
    12071620                this.pause = function() { 
    1208                         _video.pause(); 
    1209                 } 
     1621                        if (_model.state == jwplayer.events.state.PLAYING || _model.state == jwplayer.events.state.BUFFERING) { 
     1622                                _video.pause(); 
     1623                        } 
     1624                } 
     1625 
     1626                this.seek = function(pos) { 
     1627                        _video.seek(pos); 
     1628                } 
     1629                 
     1630                this.volume = function(vol) { 
     1631                        _video.volume(vol); 
     1632                } 
     1633                 
     1634                this.mute = function(state) { 
     1635                        if (!_utils.exists(state)) state = !_model.mute; 
     1636                        _video.mute(state); 
     1637                } 
     1638 
     1639                this.prev = function() { 
     1640                } 
     1641 
     1642                this.next = function() { 
     1643                } 
     1644                 
     1645                this.item = function(item) {} 
     1646                 
     1647                this.fullscreen = function(state) {} 
    12101648 
    12111649                _init(); 
     
    12511689                function _init() { 
    12521690                        _model = { 
     1691                                id: "player", 
    12531692                                video: new html5.video(document.createElement("video")), 
    1254                                 settings: config 
     1693                                settings: config, 
     1694                                volume: 0, 
     1695                                state: jwplayer.events.state.IDLE, 
     1696                                mute: false 
    12551697                        }; 
    1256                  
    1257                         _api.id = "player"; 
     1698                         
     1699                        jwplayer.utils.extend(_model, new jwplayer.events.eventdispatcher()); 
     1700                        _model.video.addGlobalListener(function(evt) { 
     1701                                switch (evt.type) { 
     1702                                case jwplayer.events.JWPLAYER_MEDIA_MUTE: 
     1703                                        if (_model.mute == evt.mute) return; 
     1704                                        _model.mute = evt.mute; 
     1705                                        break; 
     1706                                case jwplayer.events.JWPLAYER_MEDIA_VOLUME: 
     1707                                        if (_model.volume == evt.volume) return; 
     1708                                        _model.volume = evt.volume; 
     1709                                        break; 
     1710                                case jwplayer.events.JWPLAYER_PLAYER_STATE: 
     1711                                        if (_model.state == evt.newstate) return; 
     1712                                        _model.state = evt.newstate; 
     1713                                } 
     1714                                _model.sendEvent(evt.type, evt); 
     1715                        }); 
     1716                 
     1717                        _api.id = _model.id; 
    12581718                        _api.settings = _model.settings; 
    1259  
    1260                         _view = { 
    1261                                 container: document.getElementById(_api.id), 
    1262                                 controlbar: new html5.controlbar(_api, _model.settings) 
    1263                         }; 
     1719                         
     1720                        _view = {}; 
    12641721                         
    12651722                        _controller = new html5.controller(_model, _view); 
     1723                        _api.addEventListener = _controller.addEventListener; 
     1724                        _api.removeEventListener = _controller.removeEventListener; 
     1725                         
     1726                        _view.container = document.getElementById(_api.id), 
     1727                        _view.controlbar = new html5.controlbar(_api, _model.settings) 
     1728 
    12661729                 
    12671730                        jwplayer.utils.appendStylesheet("#"+_api.id+" video", { 
     
    12691732                                height: "100%", 
    12701733                                background: "#000", 
    1271                                 display: "none" 
     1734                                opacity: 0, 
     1735                                '-webkit-transition': 'opacity .15s ease' 
    12721736                        }); 
    12731737                         
     
    12751739                        _view.container.appendChild(_view.controlbar.getDisplayElement()); 
    12761740                         
     1741                        _controller.load(); 
    12771742                } 
    12781743                 
     
    12801745                this.jwPause = function(){ _controller.pause() }; 
    12811746                this.jwStop = function(){ _controller.stop() }; 
     1747                this.jwSeek = function(pos){ _controller.seek(pos) }; 
     1748                this.jwSetVolume = function(vol){ _controller.volume(vol) }; 
     1749                this.jwSetMute = function(state){ _controller.mute(state) }; 
     1750                this.jwLoad = function(item) { _controller.load(item); } 
     1751                this.jwPlaylistNext = function() { _controller.next(); } 
     1752                this.jwPlaylistPrev = function() { _controller.prev(); } 
     1753                this.jwPlaylistItem = function(item) { _controller.item(item); } 
     1754                this.jwFullscreen = function(state) { _controller.fullscreen(state); } 
     1755                 
     1756                this.jwGetState = function(){ return _model.state }; 
     1757                this.jwGetVolume = function(){ return _model.volume }; 
     1758                this.jwGetMute = function(){ return _model.mute }; 
     1759                this.jwGetFullscreen = function(){ return false }; 
     1760 
     1761 
     1762                 
    12821763                 
    12831764                _init(); 
     
    15412022 */ 
    15422023(function(jwplayerhtml5) { 
    1543          
    1544   /** HTML5 video class * */ 
    1545   jwplayerhtml5.video = function(videotag) { 
    1546            
    1547           var _mediaEvents = { 
    1548                   "abort": _videoEventHandler, 
    1549                   "canplay": _canPlayHandler, 
    1550                   "canplaythrough": _videoEventHandler, 
    1551                   "durationchange": _videoEventHandler, 
    1552                   "emptied": _videoEventHandler, 
    1553                   "ended": _videoEventHandler, 
    1554                   "error": _errorHandler, 
    1555                   "loadeddata": _videoEventHandler, 
    1556                   "loadedmetadata": _videoEventHandler, 
    1557                   "loadstart": _videoEventHandler, 
    1558                   "pause": _videoEventHandler, 
    1559                   "play": _videoEventHandler, 
    1560                   "playing": _videoEventHandler, 
    1561                   "progress": _videoEventHandler, 
    1562                   "ratechange": _videoEventHandler, 
    1563                   "readystatechange": _videoEventHandler, 
    1564                   "seeked": _videoEventHandler, 
    1565                   "seeking": _videoEventHandler, 
    1566                   "stalled": _videoEventHandler, 
    1567                   "suspend": _videoEventHandler, 
    1568                   "timeupdate": _videoEventHandler, 
    1569                   "volumechange": _videoEventHandler, 
    1570                   "waiting": _videoEventHandler 
    1571           }; 
    1572            
    1573           // Reference to the video tag 
    1574           var _video; 
    1575           // Whether seeking is ready yet 
    1576           var _canSeek; 
    1577           // If we should seek on canplay 
    1578           var _delayedSeek; 
    1579            
    1580           // Constructor 
    1581           function _init(videotag) { 
    1582                 _video = videotag; 
    1583                 _setupListeners(); 
    1584           } 
    1585            
    1586           function _setupListeners() { 
    1587                   for (var evt in _mediaEvents) { 
    1588                           _video.addEventListener(evt, _mediaEvents[evt]); 
    1589                   } 
    1590           } 
    1591            
    1592           function _videoEventHandler(evt) { 
    1593                   console.log("%s %o (%s,%s)", evt.type, evt, _bufferedStart(), _bufferedEnd()); 
    1594           } 
    1595  
    1596           function _canPlayHandler(evt) { 
    1597                   _canSeek = true; 
    1598                   _videoEventHandler(evt); 
    1599                   if (_delayedSeek > 0) { 
    1600                           _seek(_delayedSeek); 
    1601                   } 
    1602           } 
    1603            
    1604           function _errorHandler(evt) { 
    1605                   console.log("Error: %o", _video.error); 
    1606                   _videoEventHandler(evt); 
    1607           } 
    1608  
    1609           function _bufferedStart() { 
    1610                  if (_video.buffered.length > 0) 
    1611                          return _video.buffered.start(0); 
    1612                  else 
    1613                          return 0; 
    1614           } 
    1615            
    1616           function _bufferedEnd() { 
    1617                   if (_video.buffered.length > 0) 
    1618                          return Math.ceil(_video.buffered.end(_video.buffered.length-1)); 
    1619                   else 
    1620                          return 0; 
    1621           } 
    1622  
    1623           var _file; 
    1624            
    1625           this.load = function(videoURL) { 
    1626                   _canSeek = false; 
    1627                   _delayedSeek = 0; 
    1628                   _file = videoURL; 
    1629                   _video.src = _file; 
    1630                   _video.load(); 
    1631                   //_video.pause(); 
    1632           } 
    1633            
    1634           this.stop = function() { 
    1635                   //_video.src = ""; 
    1636                   _video.removeAttribute("src"); 
    1637                   _video.load(); 
    1638                   _video.style.display = "none"; 
    1639           } 
    1640            
    1641           this.play = function() { 
    1642                   _video.style.display = "block"; 
    1643                   _video.play(); 
    1644           } 
    1645  
    1646           this.pause = function() { 
    1647                   _video.pause(); 
    1648           } 
    1649  
    1650           var _seek = this.seek = function(pos) { 
    1651                   if (_canSeek) { 
    1652                           _delayedSeek = 0; 
    1653                           _video.play(); 
    1654                           _video.currentTime = pos; 
    1655                   } else { 
    1656                           _delayedSeek = pos; 
    1657                   } 
    1658           } 
    1659  
    1660           // Provide access to video tag 
    1661           // TODO: remove 
    1662           this.getTag = function() { 
    1663                   return videotag; 
    1664           } 
    1665            
    1666           // Call constructor 
    1667           _init(videotag); 
    1668            
    1669   } 
    1670    
     2024 
     2025        var _utils = jwplayer.utils; 
     2026 
     2027        /** HTML5 video class * */ 
     2028        jwplayerhtml5.video = function(videotag) { 
     2029 
     2030                var _mediaEvents = { 
     2031                        "abort" : _generalHandler, 
     2032                        "canplay" : _canPlayHandler, 
     2033                        "canplaythrough" : _generalHandler, 
     2034                        "durationchange" : _durationUpdateHandler, 
     2035                        "emptied" : _generalHandler, 
     2036                        "ended" : _generalHandler, 
     2037                        "error" : _errorHandler, 
     2038                        "loadeddata" : _generalHandler, 
     2039                        "loadedmetadata" : _generalHandler, 
     2040                        "loadstart" : _generalHandler, 
     2041                        "pause" : _playHandler, 
     2042                        "play" : _playHandler, 
     2043                        "playing" : _generalHandler, 
     2044                        "progress" : _generalHandler, 
     2045                        "ratechange" : _generalHandler, 
     2046                        "readystatechange" : _generalHandler, 
     2047                        "seeked" : _generalHandler, 
     2048                        "seeking" : _generalHandler, 
     2049                        "stalled" : _generalHandler, 
     2050                        "suspend" : _generalHandler, 
     2051                        "timeupdate" : _timeUpdateHandler, 
     2052                        "volumechange" : _volumeHandler, 
     2053                        "waiting" : _generalHandler 
     2054                }, 
     2055 
     2056                // Reference to the video tag 
     2057                _video, 
     2058                // Whether seeking is ready yet 
     2059                _canSeek, 
     2060                // If we should seek on canplay 
     2061                _delayedSeek, 
     2062                // Current media state 
     2063                _state = jwplayer.events.state.IDLE, 
     2064                // Save the volume state before muting 
     2065                _lastVolume = 0, 
     2066                // Using setInterval to check buffered ranges 
     2067                _bufferInterval = -1, 
     2068                // Last sent buffer amount 
     2069                _bufferPercent = -1, 
     2070                // Event dispatcher 
     2071                _eventDispatcher = new jwplayer.events.eventdispatcher(); 
     2072 
     2073                _utils.extend(this, _eventDispatcher); 
     2074 
     2075                // Constructor 
     2076                function _init(videotag) { 
     2077                        _video = videotag; 
     2078                        _setupListeners(); 
     2079                } 
     2080 
     2081                function _setupListeners() { 
     2082                        for (var evt in _mediaEvents) { 
     2083                                _video.addEventListener(evt, _mediaEvents[evt], false); 
     2084                        } 
     2085                } 
     2086 
     2087                function _sendEvent(type, data) { 
     2088                        _eventDispatcher.sendEvent(type, data); 
     2089                } 
     2090 
     2091                 
     2092                function _generalHandler(evt) { 
     2093                        //console.log("%s %o (%s,%s)", evt.type, evt); 
     2094                } 
     2095 
     2096                function _durationUpdateHandler(evt) { 
     2097                        _duration = _video.duration; 
     2098                        _timeUpdateHandler(); 
     2099                } 
     2100 
     2101                function _timeUpdateHandler(evt) { 
     2102                        if (_state == jwplayer.events.state.PLAYING) { 
     2103                                _sendEvent(jwplayer.events.JWPLAYER_MEDIA_TIME, { 
     2104                                        position : _video.currentTime, 
     2105                                        duration : _duration 
     2106                                }); 
     2107                                if (_video.currentTime >= _duration) { 
     2108                                        _complete(); 
     2109                                } 
     2110                        } 
     2111                } 
     2112 
     2113                function _canPlayHandler(evt) { 
     2114                        _canSeek = true; 
     2115                        _generalHandler(evt); 
     2116                        if (_delayedSeek > 0) { 
     2117                                _seek(_delayedSeek); 
     2118                        } 
     2119                } 
     2120 
     2121                function _playHandler(evt) { 
     2122                        if (_video.paused) { 
     2123                                _setState(jwplayer.events.state.PAUSED); 
     2124                        } else { 
     2125                                _setState(jwplayer.events.state.PLAYING); 
     2126                        } 
     2127                } 
     2128 
     2129                function _errorHandler(evt) { 
     2130                        console.log("Error: %o", _video.error); 
     2131                        _generalHandler(evt); 
     2132                } 
     2133 
     2134                this.load = function(videoURL) { 
     2135                        _canSeek = false; 
     2136                        _delayedSeek = 0; 
     2137                        _duration = 0; 
     2138                        _video.src = videoURL; 
     2139                        _video.load(); 
     2140                         
     2141                        _bufferInterval = setInterval(_sendBufferUpdate, 100); 
     2142                        // _video.pause(); 
     2143                } 
     2144 
     2145                var _stop = this.stop = function() { 
     2146                        // _video.src = ""; 
     2147                        _video.removeAttribute("src"); 
     2148                        _video.load(); 
     2149                        _video.style.opacity = 0; 
     2150                        clearInterval(_bufferInterval); 
     2151                        _setState(jwplayer.events.state.IDLE); 
     2152                } 
     2153 
     2154                this.play = function() { 
     2155                        _video.style.opacity = 1; 
     2156                        _video.play(); 
     2157                } 
     2158 
     2159                this.pause = function() { 
     2160                        _video.pause(); 
     2161                } 
     2162 
     2163                var _seek = this.seek = function(pos) { 
     2164                        if (_canSeek) { 
     2165                                _delayedSeek = 0; 
     2166                                // _video.play(); 
     2167                                _video.currentTime = pos; 
     2168                        } else { 
     2169                                _delayedSeek = pos; 
     2170                        } 
     2171                } 
     2172 
     2173                var _volume = this.volume = function(vol) { 
     2174                        if (_video.muted) _video.muted = false; 
     2175                        _video.volume = vol / 100; 
     2176 
     2177                } 
     2178                 
     2179                function _volumeHandler(evt) { 
     2180                        _sendEvent(jwplayer.events.JWPLAYER_MEDIA_VOLUME, { 
     2181                                volume: Math.round(_video.volume * 100) 
     2182                        }); 
     2183                        _sendEvent(jwplayer.events.JWPLAYER_MEDIA_MUTE, { 
     2184                                mute: _video.muted 
     2185                        }); 
     2186                } 
     2187                 
     2188                this.mute = function(state) { 
     2189                        if (!_utils.exists(state)) state = !_video.mute; 
     2190                        if (state) { 
     2191                                _lastVolume = _video.volume * 100; 
     2192                                _volume(0); 
     2193                                _video.muted = true; 
     2194                        } else { 
     2195                                _volume(_lastVolume); 
     2196                        } 
     2197                } 
     2198 
     2199                /** Set the current player state * */ 
     2200                function _setState(newstate) { 
     2201                        // Handles a FF 3.5 issue 
     2202                        if (newstate == jwplayer.events.state.PAUSED && _state == jwplayer.events.state.IDLE) { 
     2203                                return; 
     2204                        } 
     2205 
     2206                        if (_state != newstate) { 
     2207                                var oldstate = _state; 
     2208                                _state = newstate; 
     2209                                _sendEvent(jwplayer.events.JWPLAYER_PLAYER_STATE, { 
     2210                                        oldstate : oldstate, 
     2211                                        newstate : newstate 
     2212                                }); 
     2213                        } 
     2214                } 
     2215                 
     2216                function _sendBufferUpdate() { 
     2217                        var newBuffer = _getBuffer(); 
     2218                        if (newBuffer != _bufferPercent) { 
     2219                                _bufferPercent = newBuffer; 
     2220                                _sendEvent(jwplayer.events.JWPLAYER_MEDIA_BUFFER, { 
     2221                                        bufferPercent: Math.round(_bufferPercent * 100) 
     2222                                }); 
     2223                        } 
     2224                        if (newBuffer >= 1) { 
     2225                                clearInterval(_bufferInterval); 
     2226                        } 
     2227                } 
     2228                 
     2229                function _getBuffer() { 
     2230                        if (_video.buffered.length == 0 || _video.duration == 0) 
     2231                                return 0; 
     2232                        else 
     2233                                return _video.buffered.end(_video.buffered.length-1) / _video.duration; 
     2234                } 
     2235                 
     2236 
     2237                function _complete() { 
     2238                        _stop(); 
     2239                        _sendEvent(jwplayer.events.JWPLAYER_MEDIA_COMPLETE); 
     2240                } 
     2241                 
     2242                // Provide access to video tag 
     2243                // TODO: remove 
     2244                this.getTag = function() { 
     2245                        return videotag; 
     2246                } 
     2247 
     2248                // Call constructor 
     2249                _init(videotag); 
     2250 
     2251        } 
     2252 
    16712253})(jwplayer.html5);/** 
    16722254 * jwplayer.html5 namespace 
  • branches/jw6/build/build.xml

    r2172 r2173  
    1010                        <fileset dir="${basedir}/src/js/utils" includes="jwplayer.utils.js" excludes="" /> 
    1111                        <fileset dir="${basedir}/src/js/utils" includes="jwplayer.utils.*.js" excludes="" /> 
     12                        <fileset dir="${basedir}/src/js/events" includes="jwplayer.events.js" /> 
     13                        <fileset dir="${basedir}/src/js/events" includes="jwplayer.events.*.js" excludes="jwplayer.events.js" /> 
    1214                        <fileset dir="${basedir}/src/js/html5" includes="jwplayer.html5.js" /> 
    1315                        <fileset dir="${basedir}/src/js/html5" includes="jwplayer.html5*.js" excludes="jwplayer.html5.js" /> 
  • branches/jw6/jwplayer.min.js

    r2172 r2173  
    1 if(typeof jwplayer=="undefined"){jwplayer=function(a){if(jwplayer.api){return jwplayer.api.selectPlayer(a)}};var $jw=jwplayer;jwplayer.version="6.0";jwplayer.vid=document.createElement("video");jwplayer.audio=document.createElement("audio");jwplayer.source=document.createElement("source");(function(c){var b=c.utils=function(){};b.exists=function(h){switch(typeof(h)){case"string":return(h.length>0);break;case"object":return(h!==null);case"undefined":return false}return true};var e;var d={};b.css=function(h,k){if(b.exists(h)){for(var i in k){try{if(typeof k[i]==="undefined"){continue}else{if(typeof k[i]=="number"&&!(i=="zIndex"||i=="opacity")){if(isNaN(k[i])){continue}if(i.match(/color/i)){k[i]="#"+b.strings.pad(k[i].toString(16),6)}else{k[i]=Math.ceil(k[i])+"px"}}}if(k[i]){h.style[i]=k[i]}}catch(j){}}}};b.appendStylesheet=function(h,j){if(!e){e=document.createElement("style");e.type="text/css";document.getElementsByTagName("head")[0].appendChild(e)}if(!d[h]){d[h]={}}for(var i in j){var k=g(i,j[i]);if(b.exists(d[h][i])&&!b.exists(k)){delete d[h][i]}else{d[h][i]=k}}f()};function g(h,i){if(typeof i==="undefined"){return undefined}if(typeof i=="number"){if(isNaN(i)){return undefined}switch(h){case"z-index":case"opacity":return i;break;default:if(h.match(/color/i)){return"#"+b.strings.pad(i.toString(16),6)}else{return Math.ceil(i)+"px"}break}}else{return i}}function f(){if(e){var h="";for(var k in d){var j=d[k];h+=k+"{\n";for(var i in j){h+="  "+i+": "+j[i]+";\n"}h+="}\n"}e.innerHTML=h}}b.clearCss=function(h){for(var i in d){if(i.indexOf(h)>=0){delete d[i]}}f()};b.getAbsolutePath=function(o,n){if(!b.exists(n)){n=document.location.href}if(!b.exists(o)){return undefined}if(a(o)){return o}var p=n.substring(0,n.indexOf("://")+3);var m=n.substring(p.length,n.indexOf("/",p.length+1));var j;if(o.indexOf("/")===0){j=o.split("/")}else{var k=n.split("?")[0];k=k.substring(p.length+m.length+1,k.lastIndexOf("/"));j=k.split("/").concat(o.split("/"))}var h=[];for(var l=0;l<j.length;l++){if(!j[l]||!b.exists(j[l])||j[l]=="."){continue}else{if(j[l]==".."){h.pop()}else{h.push(j[l])}}}return p+m+"/"+h.join("/")};function a(i){if(!b.exists(i)){return}var j=i.indexOf("://");var h=i.indexOf("?");return(j>0&&(h<0||(h>j)))}b.extend=function(){var h=b.extend["arguments"];if(h.length>1){for(var k=1;k<h.length;k++){for(var j in h[k]){h[0][j]=h[k][j]}}return h[0]}return null};b.parseDimension=function(h){if(typeof h=="string"){if(h===""){return 0}else{if(h.lastIndexOf("%")>-1){return h}else{return parseInt(h.replace("px",""),10)}}}return h}})(jwplayer);(function(a){a.ajax=function(f,e,b){var d;if(window.XMLHttpRequest){d=new XMLHttpRequest()}else{d=new ActiveXObject("Microsoft.XMLHTTP")}d.onreadystatechange=function(){if(d.readyState===4){if(d.status===200){if(e){if(!jwplayer.utils.exists(d.responseXML)){try{if(window.DOMParser){var g=(new DOMParser()).parseFromString(d.responseText,"text/xml");if(g){d=jwplayer.utils.extend({},d,{responseXML:g})}}else{g=new ActiveXObject("Microsoft.XMLDOM");g.async="false";g.loadXML(d.responseText);d=jwplayer.utils.extend({},d,{responseXML:g})}}catch(h){if(b){b(f)}}}e(d)}}else{if(b){b(f)}}}};try{d.open("GET",f,true);d.send(null)}catch(c){if(b){b(f)}}return d}})(jwplayer.utils);(function(a){jwplayer.utils.strings=function(){};jwplayer.utils.strings.trim=function(b){return b.replace(/^\s*/,"").replace(/\s*$/,"")};jwplayer.utils.strings.pad=function(c,d,b){if(!b){b="0"}while(c.length<d){c=b+c}return c};jwplayer.utils.strings.serialize=function(b){if(b==null){return null}else{if(b=="true"){return true}else{if(b=="false"){return false}else{if(isNaN(Number(b))||b.length>5||b.length==0){return b}else{return Number(b)}}}}};jwplayer.utils.strings.seconds=function(d){d=d.replace(",",".");var b=d.split(":");var c=0;if(d.substr(-1)=="s"){c=Number(d.substr(0,d.length-1))}else{if(d.substr(-1)=="m"){c=Number(d.substr(0,d.length-1))*60}else{if(d.substr(-1)=="h"){c=Number(d.substr(0,d.length-1))*3600}else{if(b.length>1){c=Number(b[b.length-1]);c+=Number(b[b.length-2])*60;if(b.length==3){c+=Number(b[b.length-3])*3600}}else{c=Number(d)}}}}return c};jwplayer.utils.strings.xmlAttribute=function(b,c){for(var d=0;d<b.attributes.length;d++){if(b.attributes[d].name&&b.attributes[d].name.toLowerCase()==c.toLowerCase()){return b.attributes[d].value.toString()}}return""};jwplayer.utils.strings.jsonToString=function(f){var h=h||{};if(h&&h.stringify){return h.stringify(f)}var c=typeof(f);if(c!="object"||f===null){if(c=="string"){f='"'+f.replace(/"/g,'\\"')+'"'}else{return String(f)}}else{var g=[],b=(f&&f.constructor==Array);for(var d in f){var e=f[d];switch(typeof(e)){case"string":e='"'+e.replace(/"/g,'\\"')+'"';break;case"object":if(jwplayer.utils.exists(e)){e=jwplayer.utils.strings.jsonToString(e)}break}if(b){if(typeof(e)!="function"){g.push(String(e))}}else{if(typeof(e)!="function"){g.push('"'+d+'":'+String(e))}}}if(b){return"["+String(g)+"]"}else{return"{"+String(g)+"}"}}}})(jwplayer.utils);(function(b){var d=new RegExp(/^(#|0x)[0-9a-fA-F]{3,6}/);jwplayer.utils.typechecker=function(g,f){f=!jwplayer.utils.exists(f)?c(g):f;return e(g,f)};function c(f){var g=["true","false","t","f"];if(g.toString().indexOf(f.toLowerCase().replace(" ",""))>=0){return"boolean"}else{if(d.test(f)){return"color"}else{if(!isNaN(parseInt(f,10))&&parseInt(f,10).toString().length==f.length){return"integer"}else{if(!isNaN(parseFloat(f))&&parseFloat(f).toString().length==f.length){return"float"}}}}return"string"}function e(g,f){if(!jwplayer.utils.exists(f)){return g}switch(f){case"color":if(g.length>0){return a(g)}return null;case"integer":return parseInt(g,10);case"float":return parseFloat(g);case"boolean":if(g.toLowerCase()=="true"){return true}else{if(g=="1"){return true}}return false}return g}function a(f){switch(f.toLowerCase()){case"blue":return parseInt("0000FF",16);case"green":return parseInt("00FF00",16);case"red":return parseInt("FF0000",16);case"cyan":return parseInt("00FFFF",16);case"magenta":return parseInt("FF00FF",16);case"yellow":return parseInt("FFFF00",16);case"black":return parseInt("000000",16);case"white":return parseInt("FFFFFF",16);default:f=f.replace(/(#|0x)?([0-9A-F]{3,6})$/gi,"$2");if(f.length==3){f=f.charAt(0)+f.charAt(0)+f.charAt(1)+f.charAt(1)+f.charAt(2)+f.charAt(2)}return parseInt(f,16)}return parseInt("000000",16)}})(jwplayer.utils);(function(a){a.html5={}})(jwplayer);(function(h){var i=jwplayer.utils,g=i.appendStylesheet,b="button",m="text",d="divider",n="slider",e="relative",f="absolute",a="none",l="block",o="inline",k="inline-block",c="left",r="right",j="100%",q=".jwcontrolbar";h.controlbar=function(w,V){var u;var v={backgroundcolor:"",margin:10,font:"Arial,sans-serif",fontsize:10,fontcolor:parseInt("000000",16),fontstyle:"normal",fontweight:"bold",buttoncolor:parseInt("ffffff",16),position:"OVER",idlehide:false,hideplaylistcontrols:false,forcenextprev:false,layout:{left:{position:"left",elements:[{name:"play",type:b},{name:"divider",type:d},{name:"prev",type:b},{name:"divider",type:d},{name:"next",type:b},{name:"divider",type:d},{name:"elapsed",type:m}]},center:{position:"center",elements:[{name:"time",type:n}]},right:{position:"right",elements:[{name:"duration",type:m},{name:"blank",type:b},{name:"divider",type:d},{name:"mute",type:b},{name:"volume",type:n},{name:"divider",type:d},{name:"fullscreen",type:b}]}}};var D,ad,R;var ab,U;var G={play:"pause",mute:"unmute",fullscreen:"normalscreen"};var ac={play:false,mute:false,fullscreen:false};var t={play:L,mute:y,fullscreen:I};function af(){R={};u=w;V=i.extend({},V);U=u.id+"_controlbar";ab=z();ab.id=U;ab.className="jwcontrolbar";(new h.skinloader(V.skin,function(ai){u.skin=ai;D=i.extend({},v,u.skin.controlbar.settings,u.settings.controlbar);ad=(ai.controlbar.layout.left||ai.controlbar.layout.right||ai.controlbar.layout.center)?ai.controlbar.layout:v.layout;F();X()},function(ai){console.log(ai)}))}function F(){i.clearCss("#"+U);g("#"+U,{height:K("background").height,bottom:D.position=="OVER"?D.margin:0,left:D.position=="OVER"?D.margin:0,right:D.position=="OVER"?D.margin:0});g(W(".text"),{font:D.fontsize+"px/"+K("background").height+"px "+D.font,color:D.fontcolor,"font-weight":D.fontweight,"font-style":D.fontstyle,"text-align":"center",padding:"0 5px"})}function W(ai){return"#"+U+" "+ai}function z(){return document.createElement("span")}function X(){var ak=S("capLeft");var aj=S("capRight");var ai=S("background",{position:f,left:K("capLeft").width,right:K("capRight").width,backgroundRepeat:"repeat-x"},true);ab.style.opacity=0;if(ai){ab.appendChild(ai)}if(ak){ab.appendChild(ak)}Y();if(aj){ab.appendChild(aj)}setTimeout(function(){O();h.utils.animations.fadeIn(ab,250)},1000)}function A(ai){switch(ai.type){case d:return N(ai);break;case m:return T(ai.name);break;case b:if(ai.name!="blank"){return M(ai.name)}break;case n:return B(ai.name);break}}function S(ak,an,aj,ap){var am=z();am.className=ak;var ai=ap?"":"center";var al=K(ak);am.innerHTML="&nbsp;";if(!al||al.src==""){return}var ao;if(aj){ao={background:"url('"+al.src+"') "+ai+" repeat-x"}}else{ao={background:"url('"+al.src+"') "+ai+" no-repeat",width:al.width}}g(W("."+ak),i.extend(ao,an));R[ak]=am;return am}function M(ak){var al=document.createElement("button");al.className=ak;al.addEventListener("click",(function(an){return function(){P(an)}})(ak));var am=K(ak+"Button");var aj=K(ak+"ButtonOver");al.innerHTML="&nbsp;";if(!K(ak+"Button").src){return al}E(W("."+ak),am,aj);var ai=G[ak];if(ai){E(W("."+ak+".toggle"),K(ai+"Button"),K(ai+"ButtonOver"))}R[ak]=al;return al}function E(ai,aj,ak){if(!aj.src){return}g(ai,{width:aj.width,background:"url("+aj.src+") center no-repeat"});if(ak.src){g(ai+":hover",{background:"url("+ak.src+") center no-repeat"})}}function P(ai){if(t[ai]){t[ai]()}}function L(){if(ac.play){u.jwPause()}else{u.jwPlay()}C("play")}function y(){C("mute")}function I(){C("fullscreen")}function C(ai){R[ai].className=ai+(ac[ai]?"":" toggle");ac[ai]^=true}function x(ai){return U+"_"+ai}function T(ai,am){var ak=z();ak.id=x(ai);ak.className="text "+ai;var aj={};var al=K(ai+"Background");if(al.src){aj.background="url("+al.src+") no-repeat center";aj["background-size"]="100% "+K("background").height+"px"}g(W("."+ai),aj);ak.innerHTML="00:00";R[ai]=ak;return ak}function N(aj){if(aj.width){var ai=z();ai.className="blankDivider";g(ai,{width:parseInt(aj.width)});return ai}else{if(aj.element){return S(aj.element)}else{return S(aj.name)}}}function B(aj){var al=z();al.className="slider "+aj;var ak=z();ak.className="rail";var an=["Rail","Buffer","Progress"];for(var ao=0;ao<an.length;ao++){var ap=S(aj+"Slider"+an[ao],null,true,(aj=="volume"));if(ap){ap.className+=" stretch";ak.appendChild(ap)}}var ai=S(aj+"SliderThumb");if(ai){ai.className+=" thumb";ak.appendChild(ai)}var am=S(aj+"SliderCapLeft");var aq=S(aj+"SliderCapRight");if(aq){aq.className+=" capRight"}if(am){al.appendChild(am)}al.appendChild(ak);if(am){al.appendChild(aq)}g(W("."+aj+" .rail"),{left:K(aj+"SliderCapLeft").width,right:K(aj+"SliderCapRight").width,});if(aj=="time"){ag(al);aa(0);ae(0)}else{if(aj=="volume"){Z(al)}}R[aj]=al;return al}function ag(ai){if(R.timeSliderThumb){g(W(".timeSliderThumb"),{"margin-left":(K("timeSliderThumb").width/-2)})}ae(0);aa(0)}function Z(ak){var aj=K("volumeSliderCapLeft").width,ai=K("volumeSliderCapRight").width,al=K("volumeSliderRail").width;g(W(".volume"),{width:(aj+al+ai)})}var H={};function Y(){ah("left");ah("center");ah("right");ab.appendChild(H.left);ab.appendChild(H.center);ab.appendChild(H.right);g(W(".right"),{right:K("capRight").width})}function ah(aj){var ai=z();ai.className="group "+aj;H[aj]=ai;if(ad[aj]){J(ad[aj],H[aj])}}function J(al,ai){if(al&&al.elements.length>0){for(var ak=0;ak<al.elements.length;ak++){var aj=A(al.elements[ak]);if(aj){ai.appendChild(aj)}}}}var O=this.resize=function(aj,ai){g(W(".group.center"),{left:i.parseDimension(H.left.offsetWidth)+K("capLeft").width,right:i.parseDimension(H.right.offsetWidth)+K("capRight").width})};this.getDisplayElement=function(){return ab};var ae=this.setBuffer=function(ai){ai=Math.min(Math.max(0,ai),1);R.timeSliderBuffer.style.width=100*ai+"%"};function Q(ak,al,am){al=Math.min(Math.max(0,al),1);var aj=R[ak+"SliderProgress"];var ai=R[ak+"SliderThumb"];if(aj){aj.style.width=100*al+"%"}if(ai){ai.style.left=al*i.parseDimension(R[ak+"SliderRail"].clientWidth)+"px"}}var s=this.setVolume=function(ai){Q("volume",ai,true)};var aa=this.setProgress=function(ai){Q("time",ai)};this.getSkin=function(){return u.skin};function K(ai){if(u.skin.controlbar.elements[ai]){return u.skin.controlbar.elements[ai]}else{return{width:0,height:0,src:"",image:undefined,ready:false}}}af()};function p(){g(q,{position:f,overflow:"hidden"});g(q+" span",{height:j,"-webkit-user-select":a,"-webkit-user-drag":a,"user-select":a,"user-drag":a});g(q+" .group",{display:o});g(q+" span, "+q+" .group button,"+q+" .left",{position:e,"float":c});g(q+" .right",{position:e,"float":r});g(q+" .center",{position:f,"float":c});g(q+" button",{display:k,height:j,border:a,cursor:"pointer","-webkit-transition":"background .5s","-moz-transition":"background .5s","-o-transition":"background 1s"});g(q+" button:hover",{"-webkit-transition":"background 0s","-moz-transition":"background 0s","-o-transition":"background 0s"});g(q+" .capRight",{right:0,position:f});g(q+" .time,"+q+" .group span.stretch",{position:f,height:j,width:j,left:0});g(q+" .rail,"+q+" .thumb",{position:f,height:j,cursor:"pointer"});g(q+" .timeSliderThumb",{"-webkit-transition":"left .5s linear 0s, opacity .5s ease .5s","-moz-transition":"left .5s linear 0s, opacity .5s ease .5s"});g(q+" .timeSliderProgress,"+q+" .timeSliderBuffer",{"-webkit-transition":"width .5s linear","-moz-transition":"width .5s linear","-o-transition":"width .5s linear"});g(q+" .volume",{display:k});g(q+" .divider+.divider",{display:a});g(q+" .text",{padding:"0 5px",textAlign:"center"})}p()})(jwplayer.html5);(function(a){a.controller=function(d,c){var g,h=c,b,f;function e(){g=d;h=c;b=d.video;f=c.controlbar}this.play=function(){if(b.getTag().canPlayType("video/mp4")){b.load("http://content.bitsontherun.com/videos/nPripu9l-1ahmry41.mp4")}else{b.load("http://content.bitsontherun.com/videos/nPripu9l-1Lq5Mnwq.webm")}b.play()};this.stop=function(){b.stop()};this.pause=function(){b.pause()};e()}})(jwplayer.html5);(function(a){a.html5.defaultskin=function(){this.text='<?xml version="1.0" ?><skin author="LongTail Video" name="Five" version="1.1"><components><component name="controlbar"><settings><setting name="margin" value="20"/><setting name="fontsize" value="11"/><setting name="fontcolor" value="0x000000"/></settings><layout><group position="left"><button name="play"/><divider name="divider"/><button name="prev"/><divider name="divider"/><button name="next"/><divider name="divider"/><text name="elapsed"/></group><group position="center"><slider name="time"/></group><group position="right"><text name="duration"/><divider name="divider"/><button name="blank"/><divider name="divider"/><button name="mute"/><slider name="volume"/><divider name="divider"/><button name="fullscreen"/></group></layout><elements><element name="background" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAIAAABvFaqvAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAElJREFUOI3t1LERACAMQlFgGvcfxNIhHMK4gsUvUviOmgtNsiAZkBSEKxKEnCYkkQrJn/YwbUNiSDDYRZaQRDaShv+oX9GBZEIuK+8hXVLs+/YAAAAASUVORK5CYII="/><element name="blankButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAYCAYAAAAyJzegAAAAFElEQVQYV2P8//8/AzpgHBUc7oIAGZdH0RjKN8EAAAAASUVORK5CYII="/><element name="capLeft" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAYAAAA7zJfaAAAAQElEQVQIWz3LsRGAMADDQJ0XB5bMINABZ9GENGrszxhjT2WLSqxEJG2JQrTMdV2q5LpOAvyRaVmsi7WdeZ/7+AAaOTq7BVrfOQAAAABJRU5ErkJggg=="/><element name="capRight" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAYAAAA7zJfaAAAAQElEQVQIWz3LsRGAMADDQJ0XB5bMINABZ9GENGrszxhjT2WLSqxEJG2JQrTMdV2q5LpOAvyRaVmsi7WdeZ/7+AAaOTq7BVrfOQAAAABJRU5ErkJggg=="/><element name="divider" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAIAAAC0rgCNAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADhJREFUCB0FwcENgEAAw7Aq+893g8APUILNOQcbFRktVGqUVFRkWNz3xTa2sUaLNUosKlRUvvf5AdbWOTtzmzyWAAAAAElFTkSuQmCC"/><element name="playButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAYCAYAAAAVibZIAAAANUlEQVR42u2RsQkAAAjD/NTTPaW6dXLrINJA1kBpGPMAjDWmOgp1HFQXx+b1KOefO4oxY57R73YnVYCQUCQAAAAASUVORK5CYII="/><element name="pauseButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAYCAYAAAAVibZIAAAAIUlEQVQ4jWNgGAWjYOiD/0gYG3/U0FFDB4Oho2AUDAYAAEwiL9HrpdMVAAAAAElFTkSuQmCC"/><element name="prevButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAYCAYAAAAVibZIAAAAQklEQVQ4y2NgGAWjYOiD/1AMA/JAfB5NjCJD/YH4PRaLyDa0H4lNNUP/DxlD59PCUBCIp3ZEwYA+NZLUKBgFgwEAAN+HLX9sB8u8AAAAAElFTkSuQmCC"/><element name="nextButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAYCAYAAAAVibZIAAAAQElEQVQ4y2NgGAWjYOiD/0B8Hojl0cT+U2ooCL8HYn9qGwrD/bQw9P+QMXQ+tSMqnpoRBUpS+tRMUqNgFAwGAADxZy1/mHvFnAAAAABJRU5ErkJggg=="/><element name="timeSliderRail" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAOElEQVRIDe3BwQkAIRADwAhhw/nU/kWwUK+KPITMABFh19Y+F0acY8CJvX9wYpXgRElwolSIiMf9ZWEDhtwurFsAAAAASUVORK5CYII="/><element name="timeSliderBuffer" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAN0lEQVRIDe3BwQkAMQwDMBcc55mRe9zi7RR+FCwBEWG39vcfGHFm4MTuhhMlwYlVBSdKhYh43AW/LQMKm1spzwAAAABJRU5ErkJggg=="/><element name="timeSliderProgress" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAIElEQVRIiWNgGAWjYBTQBfynMR61YCRYMApGwSigMQAAiVWPcbq6UkIAAAAASUVORK5CYII="/><element name="timeSliderThumb" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAYCAYAAAA/OUfnAAAAO0lEQVQYlWP4//8/Awwz0JgDBP/BeN6Cxf/hnI2btiI4u/fsQ3AOHjqK4Jw4eQbBOX/hEoKDYjSd/AMA4cS4mfLsorgAAAAASUVORK5CYII="/><element name="muteButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAYCAYAAADKx8xXAAAAJklEQVQ4y2NgGAUjDcwH4v/kaPxPikZkxcNVI9mBQ5XoGAWDFwAAsKAXKQQmfbUAAAAASUVORK5CYII="/><element name="unmuteButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAYCAYAAADKx8xXAAAAMklEQVQ4y2NgGAWDHPyntub5xBr6Hwv/Pzk2/yfVG/8psRFE25Oq8T+tQnsIaB4FVAcAi2YVysVY52AAAAAASUVORK5CYII="/><element name="volumeSliderRail" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYAgMAAACdGdVrAAAACVBMVEUAAACmpqampqbBXAu8AAAAAnRSTlMAgJsrThgAAAArSURBVAhbY2AgErBAyA4I2QEhOyBkB4TsYOhAoaCCUCUwDTDtMMNgRuMHAFB5FoGH5T0UAAAAAElFTkSuQmCC"/><element name="volumeSliderProgress" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYAgMAAACdGdVrAAAACVBMVEUAAAAAAAAAAACDY+nAAAAAAnRSTlMAgJsrThgAAAArSURBVAhbY2AgErBAyA4I2QEhOyBkB4TsYOhAoaCCUCUwDTDtMMNgRuMHAFB5FoGH5T0UAAAAAElFTkSuQmCC"/><element name="volumeSliderCapRight" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAYCAYAAAAyJzegAAAAFElEQVQYV2P8//8/AzpgHBUc7oIAGZdH0RjKN8EAAAAASUVORK5CYII="/><element name="fullscreenButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAQklEQVRIiWNgGAWjYMiD/0iYFDmSLbDHImdPLQtgBpEiR7Zl2NijAA5oEkT/0Whi5UiyAJ8BVMsHNMtoo2AUDAIAAGdcIN3IDNXoAAAAAElFTkSuQmCC"/><element name="normalscreenButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAP0lEQVRIx2NgGAWjYMiD/1RSQ5QB/wmIUWzJfzx8qhj+n4DYCAY0DyJ7PBbYU8sHMEvwiZFtODXUjIJRMJgBACpWIN2ZxdPTAAAAAElFTkSuQmCC"/></elements></component><component name="display"><elements><element name="background" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyAQMAAAAk8RryAAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlOZpuml+rYAAAASSURBVBhXY2AYJuA/GBwY6jQAyDyoK8QcL4QAAAAASUVORK5CYII="/><element name="playIcon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiUlEQVR42u3XSw2AMBREURwgAQlIQAISKgUpSEFKJeCg5b0E0kWBTVcD9ySTsL0Jn9IBAAAA+K2UUrBlW/Rr5ZDoIeeuoFkxJD9ss03aIXXQqB9SttoG7ZA6qNcOKdttiwcJh9RB+iFl4SshkRBuLR72+9cvH0SOKI2HRo7x/Fi1/uoCAAAAwLsD8ki99IlO2dQAAAAASUVORK5CYII="/><element name="muteIcon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAVUlEQVR42u3WMQrAIAxAUW/g/SdvGmvpoOBeSHgPsjj5QTANAACARCJilIhYM0tEvJM+Ik3Id9E957kQIb+F3OdCPC0hPkQriqWx9hp/x/QGAABQyAPLB22VGrpLDgAAAABJRU5ErkJggg=="/><element name="errorIcon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAA/0lEQVR42u2U0QmEMBAF7cASLMESUoIlpARLSCkpwRJSgiWkhOvAXD4WsgRkyaG5DbyB+Yvg8KITAAAAAAAYk+u61mwk15EjPtlEfihmqIiZR1Qx80ghjgdUuiHXGHSVsoag0x6x8DUoyjD5KovmEJ9NTDMRPIT0mtdIUkjlonuNohO+Ha99DTmkuGgKCTcvebAzx82ZoCWC3/3aIMWSRucaxcjORSFY4xpFdjYJGp1rFGcyCYZ/RVh6AUnfcNZ2zih3/mGj1jVCdiNDwyrq1rA/xMdeEXvDVdnYc1vDc3uPkDObXrlaxbNHSOohQhr/WOeLEWfWTgAAAAAAADzNF9sHJ7PJ57MlAAAAAElFTkSuQmCC"/><element name="bufferIcon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAACBklEQVR42u3Zv0sCYRzH8USTzOsHHEWGkC1HgaDgkktGDjUYtDQ01RDSljQ1BLU02+rk1NTm2NLq4Nx/0L/h9fnCd3j4cnZe1/U8xiO8h3uurufF0/3COd/3/0UWYiEWYiEWYiGJQ+J8xuPxKhXjEMZANinjIZhkGuVRNioE4wVURo4JkHm0xKWmhRAc1bh1EyCUw5BcBIjHiApKa4CErko6DEJwuRo6IRKzyJD8FJAyI3Zp2zRImiBcRhlfo5RtlxCcE3CcDNpGrhYIT2IhAJKilO0VRmzJ32fAMTpBTS0QMfGwlcuKMRftE0DJ0wCJdcOsCkBdXP3Mh9CEFUBTPS9mDZJBG6io4aqVzMdCokCw9H3kT6j/C/9iDdSeUMNC7DkyyxAs/Rk6Qss8FPWRZgdVtUH4DjxEn1zxh+/zj1wHlf4MQhNGrwqA6sY40U8JonRJwEQh+AO3AvCG6gHv4U7IY4krxkroWoAOkoQMGfCBrgIm+YBGqPENpIJ66CJg3x66Y0gnSUidAEEnNr9jjLiWMn5DiWP0OC/oAsCgkq43xBdGDMQr7YASP/vEkHvdl1+JOCcEV5sC4hGEOzTlPuKgd0b0xD4JkRcOgnRRTjdErkYhAsQVq6IdUuPJtmk7BCL3t/h88cx91pKQkI/pkDx6pmYTIjEoxiHsN1YWYiEWYiEWknhflZ5IErA5nr8AAAAASUVORK5CYII="/></elements></component><component name="dock"><settings><setting name="fontcolor" value="0xffffff"/></settings><elements><element name="button" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyAQMAAAAk8RryAAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlOZpuml+rYAAAASSURBVBhXY2AYJuA/GBwY6jQAyDyoK8QcL4QAAAAASUVORK5CYII="/></elements></component><component name="playlist"><settings><setting name="backgroundcolor" value="0xe8e8e8"/></settings><elements><element name="item" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAIAAAC1nk4lAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHBJREFUaN7t2MENwCAMBEEe9N8wSKYC/D8YV7CyJoRkVtVImxkZPQInMxoP0XiIxkM0HsGbjjSNBx544IEHHnjggUe/6UQeey0PIh7XTftGxKPj4eXCtLsHHh+ZxkO0Iw8PR55Ni8ZD9Hu/EAoP0dc5RRg9qeRjVF8AAAAASUVORK5CYII="/><element name="sliderCapTop" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAHCAYAAADnCQYGAAAAFUlEQVQokWP8//8/A7UB46ihI9hQAKt6FPPXhVGHAAAAAElFTkSuQmCC"/><element name="sliderRail" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAUCAYAAABiS3YzAAAAKElEQVQ4y2P4//8/Az68bNmy/+iYkB6GUUNHDR01dNTQUUNHDaXcUABUDOKhcxnsSwAAAABJRU5ErkJggg=="/><element name="sliderThumb" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAUCAYAAABiS3YzAAAAJUlEQVQ4T2P4//8/Ay4MBP9xYbz6Rg0dNXTU0FFDRw0dNZRyQwHH4NBa7GJsXAAAAABJRU5ErkJggg=="/><element name="sliderCapBottom" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAHCAYAAADnCQYGAAAAFUlEQVQokWP8//8/A7UB46ihI9hQAKt6FPPXhVGHAAAAAElFTkSuQmCC"/></elements></component></components></skin>';this.xml=null;if(window.DOMParser){parser=new DOMParser();this.xml=parser.parseFromString(this.text,"text/xml")}else{this.xml=new ActiveXObject("Microsoft.XMLDOM");this.xml.async="false";this.xml.loadXML(this.text)}return this}})(jwplayer);(function(a){a.player=function(b){var f,g,e,c=this;function d(){f={video:new a.video(document.createElement("video")),settings:b};c.id="player";c.settings=f.settings;g={container:document.getElementById(c.id),controlbar:new a.controlbar(c,f.settings)};e=new a.controller(f,g);jwplayer.utils.appendStylesheet("#"+c.id+" video",{width:"100%",height:"100%",background:"#000",display:"none"});g.container.appendChild(f.video.getTag());g.container.appendChild(g.controlbar.getDisplayElement())}this.jwPlay=function(){e.play()};this.jwPause=function(){e.pause()};this.jwStop=function(){e.stop()};d()}})(jwplayer.html5);(function(a){a.html5.skin=function(){var b={};var c=false;this.load=function(d,e){new a.html5.skinloader(d,function(f){c=true;b=f;e()},function(){new a.html5.skinloader("",function(f){c=true;b=f;e()})})};this.getSkinElement=function(d,e){if(c){try{return b[d].elements[e]}catch(f){a.utils.log("No such skin component / element: ",[d,e])}}return null};this.getComponentSettings=function(d){if(c&&b&&b[d]){return b[d].settings}return null};this.getComponentLayout=function(d){if(c){var e=b[d].layout;if(e&&(e.left||e.right||e.center)){return b[d].layout}}return null}}})(jwplayer);(function(a){a.html5.skinloader=function(f,o,j){var n={};var c=o;var k=j;var e=true;var i;var m=f;var r=false;function l(){if(typeof m!="string"||m===""){d(a.html5.defaultskin().xml)}else{a.utils.ajax(a.utils.getAbsolutePath(m),function(s){try{if(a.utils.exists(s.responseXML)){d(s.responseXML);return}}catch(t){h()}d(a.html5.defaultskin().xml)},function(s){d(a.html5.defaultskin().xml)})}}function d(x){var D=x.getElementsByTagName("component");if(D.length===0){return}for(var G=0;G<D.length;G++){var B=D[G].getAttribute("name");var A={settings:{},elements:{},layout:{}};n[B]=A;var F=D[G].getElementsByTagName("elements")[0].getElementsByTagName("element");for(var E=0;E<F.length;E++){b(F[E],B)}var y=D[G].getElementsByTagName("settings")[0];if(y&&y.childNodes.length>0){var J=y.getElementsByTagName("setting");for(var O=0;O<J.length;O++){var P=J[O].getAttribute("name");var H=J[O].getAttribute("value");var w=/color$/.test(P)?"color":null;n[B].settings[P]=a.utils.typechecker(H,w)}}var K=D[G].getElementsByTagName("layout")[0];if(K&&K.childNodes.length>0){var L=K.getElementsByTagName("group");for(var v=0;v<L.length;v++){var z=L[v];n[B].layout[z.getAttribute("position")]={elements:[]};for(var N=0;N<z.attributes.length;N++){var C=z.attributes[N];n[B].layout[z.getAttribute("position")][C.name]=C.value}var M=z.getElementsByTagName("*");for(var u=0;u<M.length;u++){var s=M[u];n[B].layout[z.getAttribute("position")].elements.push({type:s.tagName});for(var t=0;t<s.attributes.length;t++){var I=s.attributes[t];n[B].layout[z.getAttribute("position")].elements[u][I.name]=I.value}if(!a.utils.exists(n[B].layout[z.getAttribute("position")].elements[u].name)){n[B].layout[z.getAttribute("position")].elements[u].name=s.tagName}}}}e=false;q()}}function q(){clearInterval(i);if(!r){i=setInterval(function(){p()},100)}}function b(x,w){var v=new Image();var s=x.getAttribute("name");var u=x.getAttribute("src");var z;if(u.indexOf("data:image/png;base64,")===0){z=u}else{var t=a.utils.getAbsolutePath(m);var y=t.substr(0,t.lastIndexOf("/"));z=[y,w,u].join("/")}n[w].elements[s]={height:0,width:0,src:"",ready:false,image:v};v.onload=function(A){g(v,s,w)};v.onerror=function(A){r=true;q();k()};v.src=z}function h(){for(var t in n){var v=n[t];for(var s in v.elements){var w=v.elements[s];var u=w.image;u.onload=null;u.onerror=null;delete w.image;delete v.elements[s]}delete n[t]}}function p(){for(var s in n){if(s!="properties"){for(var t in n[s].elements){if(!n[s].elements[t].ready){return}}}}if(e===false){clearInterval(i);c(n)}}function g(s,u,t){if(n[t]&&n[t].elements[u]){n[t].elements[u].height=s.height;n[t].elements[u].width=s.width;n[t].elements[u].src=s.src;n[t].elements[u].ready=true;q()}else{a.utils.log("Loaded an image for a missing element: "+t+"."+u)}}l()}})(jwplayer);(function(a){a.video=function(k){var b={abort:c,canplay:m,canplaythrough:c,durationchange:c,emptied:c,ended:c,error:h,loadeddata:c,loadedmetadata:c,loadstart:c,pause:c,play:c,playing:c,progress:c,ratechange:c,readystatechange:c,seeked:c,seeking:c,stalled:c,suspend:c,timeupdate:c,volumechange:c,waiting:c};var e;var g;var d;function l(p){e=p;i()}function i(){for(var p in b){e.addEventListener(p,b[p])}}function c(p){console.log("%s %o (%s,%s)",p.type,p,f(),j())}function m(p){g=true;c(p);if(d>0){n(d)}}function h(p){console.log("Error: %o",e.error);c(p)}function f(){if(e.buffered.length>0){return e.buffered.start(0)}else{return 0}}function j(){if(e.buffered.length>0){return Math.ceil(e.buffered.end(e.buffered.length-1))}else{return 0}}var o;this.load=function(p){g=false;d=0;o=p;e.src=o;e.load()};this.stop=function(){e.removeAttribute("src");e.load();e.style.display="none"};this.play=function(){e.style.display="block";e.play()};this.pause=function(){e.pause()};var n=this.seek=function(p){if(g){d=0;e.play();e.currentTime=p}else{d=p}};this.getTag=function(){return k};l(k)}})(jwplayer.html5);(function(a){a.utils={}})(jwplayer.html5);(function(a){a.animations=function(d,j,t,e,b,q){var p,o,l,r,h,k,i,g;var s,w,f,w,c;function m(){k=q?q:a.animations.easing.quint.easeOut;p=d;o=j;if(p.id&&!a.animations.active[p.id]){a.animations.active[p.id]={}}if(isNaN(t)){if(t.indexOf("%")>0){i="%"}else{if(t.indexOf("px")){i="px"}}l=parseFloat(t.replace(i,""));r=parseFloat(e.replace(i,""))}else{i="";l=parseFloat(t);r=parseFloat(e)}h=parseFloat(b);this.id=Math.random()}this.start=function(){if(p.id){if(a.animations.active[p.id][o]&&a.animations.active[p.id][o]!=g){a.animations.active[p.id][o].stop();newFrom=parseFloat(p.style[o].toString().replace(i,""));w=h*(l/newFrom)}a.animations.active[p.id][o]=g}if(c){clearInterval(c)}f=(new Date()).valueOf();n();c=setInterval(n,a.animations.INTERVAL_SPEED)};this.stop=function(){clearInterval(c);if(p.id){a.animations.active[p.id][o]=null}};function n(){w=(new Date()).valueOf();if(w-f>=h){u();return}value=k((w-f),0,1,h);v(value)}function u(){v(1);g.stop()}function v(x){var y=(l+(r-l)*x);p.style[o]=y+i}g=this;m()};a.animations.INTERVAL_SPEED=10;a.animations.easing={};a.animations.easing.quint={easeIn:function(f,e,h,g){return h*(f/=g)*f*f*f*f+e},easeOut:function(f,e,h,g){return h*((f=f/g-1)*f*f*f*f+1)+e},easeInOut:function(f,e,h,g){if((f/=g/2)<1){return h/2*f*f*f*f*f+e}return h/2*((f-=2)*f*f*f*f+2)+e}};a.animations.easing.linear={easeIn:function(f,e,h,g){return h*f/g+e},easeOut:function(f,e,h,g){return h*f/g+e},easeInOut:function(f,e,h,g){return h*f/g+e}};a.animations.active={};a.animations.fadeIn=function(b,d,e){var c=new a.animations(b,"opacity",0,1,d,e);c.start()};a.animations.fadeOut=function(b,d,e){var c=new a.animations(b,"opacity",1,0,d,e);c.start()};a.animations.transform=function(c,h,f,i,g,b,e){var j=new a.animations(c,"left",h,i,b,e);var d=new a.animations(c,"top",f,g,b,e);j.start();d.start()}})(jwplayer.html5.utils)}; 
     1if(typeof jwplayer=="undefined"){jwplayer=function(a){if(jwplayer.api){return jwplayer.api.selectPlayer(a)}};var $jw=jwplayer;jwplayer.version="6.0";jwplayer.vid=document.createElement("video");jwplayer.audio=document.createElement("audio");jwplayer.source=document.createElement("source");(function(c){var b=c.utils=function(){};b.exists=function(h){switch(typeof(h)){case"string":return(h.length>0);break;case"object":return(h!==null);case"undefined":return false}return true};var e;var d={};b.css=function(h,k){if(b.exists(h)){for(var i in k){try{if(typeof k[i]==="undefined"){continue}else{if(typeof k[i]=="number"&&!(i=="zIndex"||i=="opacity")){if(isNaN(k[i])){continue}if(i.match(/color/i)){k[i]="#"+b.strings.pad(k[i].toString(16),6)}else{k[i]=Math.ceil(k[i])+"px"}}}if(k[i]){h.style[i]=k[i]}}catch(j){}}}};b.appendStylesheet=function(h,j){if(!e){e=document.createElement("style");e.type="text/css";document.getElementsByTagName("head")[0].appendChild(e)}if(!d[h]){d[h]={}}for(var i in j){var k=g(i,j[i]);if(b.exists(d[h][i])&&!b.exists(k)){delete d[h][i]}else{d[h][i]=k}}f()};function g(h,i){if(typeof i==="undefined"){return undefined}if(typeof i=="number"){if(isNaN(i)){return undefined}switch(h){case"z-index":case"opacity":return i;break;default:if(h.match(/color/i)){return"#"+b.strings.pad(i.toString(16),6)}else{return Math.ceil(i)+"px"}break}}else{return i}}function f(){if(e){var h="";for(var k in d){var j=d[k];h+=k+"{\n";for(var i in j){h+="  "+i+": "+j[i]+";\n"}h+="}\n"}e.innerHTML=h}}b.clearCss=function(h){for(var i in d){if(i.indexOf(h)>=0){delete d[i]}}f()};b.getAbsolutePath=function(o,n){if(!b.exists(n)){n=document.location.href}if(!b.exists(o)){return undefined}if(a(o)){return o}var p=n.substring(0,n.indexOf("://")+3);var m=n.substring(p.length,n.indexOf("/",p.length+1));var j;if(o.indexOf("/")===0){j=o.split("/")}else{var k=n.split("?")[0];k=k.substring(p.length+m.length+1,k.lastIndexOf("/"));j=k.split("/").concat(o.split("/"))}var h=[];for(var l=0;l<j.length;l++){if(!j[l]||!b.exists(j[l])||j[l]=="."){continue}else{if(j[l]==".."){h.pop()}else{h.push(j[l])}}}return p+m+"/"+h.join("/")};function a(i){if(!b.exists(i)){return}var j=i.indexOf("://");var h=i.indexOf("?");return(j>0&&(h<0||(h>j)))}b.extend=function(){var h=b.extend["arguments"];if(h.length>1){for(var k=1;k<h.length;k++){for(var j in h[k]){h[0][j]=h[k][j]}}return h[0]}return null};b.parseDimension=function(h){if(typeof h=="string"){if(h===""){return 0}else{if(h.lastIndexOf("%")>-1){return h}else{return parseInt(h.replace("px",""),10)}}}return h};b.timeFormat=function(h){if(h>0){str=Math.floor(h/60)<10?"0"+Math.floor(h/60)+":":Math.floor(h/60)+":";str+=Math.floor(h%60)<10?"0"+Math.floor(h%60):Math.floor(h%60);return str}else{return"00:00"}};c.utils.log=function(i,h){if(typeof console!="undefined"&&typeof console.log!="undefined"){if(h){console.log(i,h)}else{console.log(i)}}};c.utils.getBoundingClientRect=function(h){if(typeof h.getBoundingClientRect=="function"){return h.getBoundingClientRect()}else{return{left:h.offsetLeft+document.body.scrollLeft,top:h.offsetTop+document.body.scrollTop,width:h.offsetWidth,height:h.offsetHeight}}}})(jwplayer);(function(a){a.ajax=function(f,e,b){var d;if(window.XMLHttpRequest){d=new XMLHttpRequest()}else{d=new ActiveXObject("Microsoft.XMLHTTP")}d.onreadystatechange=function(){if(d.readyState===4){if(d.status===200){if(e){if(!jwplayer.utils.exists(d.responseXML)){try{if(window.DOMParser){var g=(new DOMParser()).parseFromString(d.responseText,"text/xml");if(g){d=jwplayer.utils.extend({},d,{responseXML:g})}}else{g=new ActiveXObject("Microsoft.XMLDOM");g.async="false";g.loadXML(d.responseText);d=jwplayer.utils.extend({},d,{responseXML:g})}}catch(h){if(b){b(f)}}}e(d)}}else{if(b){b(f)}}}};try{d.open("GET",f,true);d.send(null)}catch(c){if(b){b(f)}}return d}})(jwplayer.utils);(function(a){jwplayer.utils.strings=function(){};jwplayer.utils.strings.trim=function(b){return b.replace(/^\s*/,"").replace(/\s*$/,"")};jwplayer.utils.strings.pad=function(c,d,b){if(!b){b="0"}while(c.length<d){c=b+c}return c};jwplayer.utils.strings.serialize=function(b){if(b==null){return null}else{if(b=="true"){return true}else{if(b=="false"){return false}else{if(isNaN(Number(b))||b.length>5||b.length==0){return b}else{return Number(b)}}}}};jwplayer.utils.strings.seconds=function(d){d=d.replace(",",".");var b=d.split(":");var c=0;if(d.substr(-1)=="s"){c=Number(d.substr(0,d.length-1))}else{if(d.substr(-1)=="m"){c=Number(d.substr(0,d.length-1))*60}else{if(d.substr(-1)=="h"){c=Number(d.substr(0,d.length-1))*3600}else{if(b.length>1){c=Number(b[b.length-1]);c+=Number(b[b.length-2])*60;if(b.length==3){c+=Number(b[b.length-3])*3600}}else{c=Number(d)}}}}return c};jwplayer.utils.strings.xmlAttribute=function(b,c){for(var d=0;d<b.attributes.length;d++){if(b.attributes[d].name&&b.attributes[d].name.toLowerCase()==c.toLowerCase()){return b.attributes[d].value.toString()}}return""};jwplayer.utils.strings.jsonToString=function(f){var h=h||{};if(h&&h.stringify){return h.stringify(f)}var c=typeof(f);if(c!="object"||f===null){if(c=="string"){f='"'+f.replace(/"/g,'\\"')+'"'}else{return String(f)}}else{var g=[],b=(f&&f.constructor==Array);for(var d in f){var e=f[d];switch(typeof(e)){case"string":e='"'+e.replace(/"/g,'\\"')+'"';break;case"object":if(jwplayer.utils.exists(e)){e=jwplayer.utils.strings.jsonToString(e)}break}if(b){if(typeof(e)!="function"){g.push(String(e))}}else{if(typeof(e)!="function"){g.push('"'+d+'":'+String(e))}}}if(b){return"["+String(g)+"]"}else{return"{"+String(g)+"}"}}}})(jwplayer.utils);(function(b){var d=new RegExp(/^(#|0x)[0-9a-fA-F]{3,6}/);jwplayer.utils.typechecker=function(g,f){f=!jwplayer.utils.exists(f)?c(g):f;return e(g,f)};function c(f){var g=["true","false","t","f"];if(g.toString().indexOf(f.toLowerCase().replace(" ",""))>=0){return"boolean"}else{if(d.test(f)){return"color"}else{if(!isNaN(parseInt(f,10))&&parseInt(f,10).toString().length==f.length){return"integer"}else{if(!isNaN(parseFloat(f))&&parseFloat(f).toString().length==f.length){return"float"}}}}return"string"}function e(g,f){if(!jwplayer.utils.exists(f)){return g}switch(f){case"color":if(g.length>0){return a(g)}return null;case"integer":return parseInt(g,10);case"float":return parseFloat(g);case"boolean":if(g.toLowerCase()=="true"){return true}else{if(g=="1"){return true}}return false}return g}function a(f){switch(f.toLowerCase()){case"blue":return parseInt("0000FF",16);case"green":return parseInt("00FF00",16);case"red":return parseInt("FF0000",16);case"cyan":return parseInt("00FFFF",16);case"magenta":return parseInt("FF00FF",16);case"yellow":return parseInt("FFFF00",16);case"black":return parseInt("000000",16);case"white":return parseInt("FFFFFF",16);default:f=f.replace(/(#|0x)?([0-9A-F]{3,6})$/gi,"$2");if(f.length==3){f=f.charAt(0)+f.charAt(0)+f.charAt(1)+f.charAt(1)+f.charAt(2)+f.charAt(2)}return parseInt(f,16)}return parseInt("000000",16)}})(jwplayer.utils);(function(a){a.events={COMPLETE:"COMPLETE",ERROR:"ERROR",API_READY:"jwplayerAPIReady",JWPLAYER_READY:"jwplayerReady",JWPLAYER_FULLSCREEN:"jwplayerFullscreen",JWPLAYER_RESIZE:"jwplayerResize",JWPLAYER_ERROR:"jwplayerError",JWPLAYER_MEDIA_BEFOREPLAY:"jwplayerMediaBeforePlay",JWPLAYER_MEDIA_BEFORECOMPLETE:"jwplayerMediaBeforeComplete",JWPLAYER_COMPONENT_SHOW:"jwplayerComponentShow",JWPLAYER_COMPONENT_HIDE:"jwplayerComponentHide",JWPLAYER_MEDIA_BUFFER:"jwplayerMediaBuffer",JWPLAYER_MEDIA_BUFFER_FULL:"jwplayerMediaBufferFull",JWPLAYER_MEDIA_ERROR:"jwplayerMediaError",JWPLAYER_MEDIA_LOADED:"jwplayerMediaLoaded",JWPLAYER_MEDIA_COMPLETE:"jwplayerMediaComplete",JWPLAYER_MEDIA_SEEK:"jwplayerMediaSeek",JWPLAYER_MEDIA_TIME:"jwplayerMediaTime",JWPLAYER_MEDIA_VOLUME:"jwplayerMediaVolume",JWPLAYER_MEDIA_META:"jwplayerMediaMeta",JWPLAYER_MEDIA_MUTE:"jwplayerMediaMute",JWPLAYER_PLAYER_STATE:"jwplayerPlayerState",state:{BUFFERING:"BUFFERING",IDLE:"IDLE",PAUSED:"PAUSED",PLAYING:"PLAYING",COMPLETED:"COMPLETED"},JWPLAYER_PLAYLIST_LOADED:"jwplayerPlaylistLoaded",JWPLAYER_PLAYLIST_ITEM:"jwplayerPlaylistItem",JWPLAYER_INSTREAM_CLICK:"jwplayerInstreamClicked",JWPLAYER_INSTREAM_DESTROYED:"jwplayerInstreamDestroyed"}})(jwplayer);(function(jwplayer){jwplayer.events.eventdispatcher=function(id,debug){var _id=id,_debug=debug,_listeners,_globallisteners;this.resetEventListeners=function(){_listeners={};_globallisteners=[]};this.resetEventListeners();this.addEventListener=function(type,listener,count){try{if(!jwplayer.utils.exists(_listeners[type])){_listeners[type]=[]}if(typeof(listener)=="string"){eval("listener = "+listener)}_listeners[type].push({listener:listener,count:count})}catch(err){jwplayer.utils.log("error",err)}return false};this.removeEventListener=function(type,listener){if(!_listeners[type]){return}try{for(var listenerIndex=0;listenerIndex<_listeners[type].length;listenerIndex++){if(_listeners[type][listenerIndex].listener.toString()==listener.toString()){_listeners[type].splice(listenerIndex,1);break}}}catch(err){jwplayer.utils.log("error",err)}return false};this.addGlobalListener=function(listener,count){try{if(typeof(listener)=="string"){eval("listener = "+listener)}_globallisteners.push({listener:listener,count:count})}catch(err){jwplayer.utils.log("error",err)}return false};this.removeGlobalListener=function(listener){if(!listener){return}try{for(var globalListenerIndex=0;globalListenerIndex<_globallisteners.length;globalListenerIndex++){if(_globallisteners[globalListenerIndex].listener.toString()==listener.toString()){_globallisteners.splice(globalListenerIndex,1);break}}}catch(err){jwplayer.utils.log("error",err)}return false};this.sendEvent=function(type,data){if(!jwplayer.utils.exists(data)){data={}}jwplayer.utils.extend(data,{id:_id,version:jwplayer.version,type:type});if(_debug){jwplayer.utils.log(type,data)}if(typeof _listeners[type]!="undefined"){for(var listenerIndex=0;listenerIndex<_listeners[type].length;listenerIndex++){try{_listeners[type][listenerIndex].listener(data)}catch(err){jwplayer.utils.log("There was an error while handling a listener: "+err.toString(),_listeners[type][listenerIndex].listener)}if(_listeners[type][listenerIndex]){if(_listeners[type][listenerIndex].count===1){delete _listeners[type][listenerIndex]}else{if(_listeners[type][listenerIndex].count>0){_listeners[type][listenerIndex].count=_listeners[type][listenerIndex].count-1}}}}}for(var globalListenerIndex=0;globalListenerIndex<_globallisteners.length;globalListenerIndex++){try{_globallisteners[globalListenerIndex].listener(data)}catch(err){jwplayer.utils.log("There was an error while handling a listener: "+err.toString(),_globallisteners[globalListenerIndex].listener)}if(_globallisteners[globalListenerIndex]){if(_globallisteners[globalListenerIndex].count===1){delete _globallisteners[globalListenerIndex]}else{if(_globallisteners[globalListenerIndex].count>0){_globallisteners[globalListenerIndex].count=_globallisteners[globalListenerIndex].count-1}}}}}}})(jwplayer);(function(a){a.html5={}})(jwplayer);(function(h){var i=jwplayer.utils,g=i.appendStylesheet,b="button",m="text",d="divider",n="slider",e="relative",f="absolute",a="none",l="block",p="inline",k="inline-block",c="left",r="right",j="100%",o="width .25s linear 0s, left .25s linear 0s, opacity .25s ease 0s";CB_CLASS=".jwcontrolbar";h.controlbar=function(y,ah){var w,x={backgroundcolor:"",margin:10,font:"Arial,sans-serif",fontsize:10,fontcolor:parseInt("000000",16),fontstyle:"normal",fontweight:"bold",buttoncolor:parseInt("ffffff",16),position:"OVER",idlehide:false,hideplaylistcontrols:false,forcenextprev:false,layout:{left:{position:"left",elements:[{name:"play",type:b},{name:"divider",type:d},{name:"prev",type:b},{name:"divider",type:d},{name:"next",type:b},{name:"divider",type:d},{name:"elapsed",type:m}]},center:{position:"center",elements:[{name:"time",type:n}]},right:{position:"right",elements:[{name:"duration",type:m},{name:"blank",type:b},{name:"divider",type:d},{name:"mute",type:b},{name:"volume",type:n},{name:"divider",type:d},{name:"fullscreen",type:b}]}}},K,ap,ab,an,ae,ay,O={play:"pause",mute:"unmute",fullscreen:"normalscreen"},ao={play:false,mute:false,fullscreen:false},v={play:T,mute:F,fullscreen:Q,next:u,prev:W},z={time:N,volume:at};function ar(){ab={};w=y;ah=i.extend({},ah);ae=w.id+"_controlbar";ay=0;an=G();an.id=ae;an.className="jwcontrolbar";window.addEventListener("mousemove",ax,false);window.addEventListener("mouseup",ax,false);(new h.skinloader(ah.skin,function(aA){w.skin=aA;K=i.extend({},x,w.skin.controlbar.settings,w.settings.controlbar);ap=(aA.controlbar.layout.left||aA.controlbar.layout.right||aA.controlbar.layout.center)?aA.controlbar.layout:x.layout;M();aj();s()},function(aA){i.log(aA)}))}function s(){w.addEventListener(jwplayer.events.JWPLAYER_MEDIA_TIME,az);w.addEventListener(jwplayer.events.JWPLAYER_PLAYER_STATE,B);w.addEventListener(jwplayer.events.JWPLAYER_MEDIA_MUTE,au);w.addEventListener(jwplayer.events.JWPLAYER_MEDIA_VOLUME,A);w.addEventListener(jwplayer.events.JWPLAYER_MEDIA_BUFFER,D)}function az(aA){ay=aA.duration;if(ab.elapsed){ab.elapsed.innerHTML=i.timeFormat(aA.position)}if(ab.duration){ab.duration.innerHTML=i.timeFormat(aA.duration)}if(aA.duration>0){am(aA.position/aA.duration)}else{am(0)}}function B(aA){switch(aA.newstate){case jwplayer.events.state.PLAYING:case jwplayer.events.state.BUFFERING:if(ab.timeSliderThumb){ab.timeSliderThumb.style.opacity=1}if(ab.timeRail){ab.timeRail.className="jwrail jwsmooth"}J("play",true);break;case jwplayer.events.state.PAUSED:if(!Y){J("play",false)}break;case jwplayer.events.state.IDLE:case jwplayer.events.state.COMPLETED:J("play",false);if(ab.timeSliderThumb){ab.timeSliderThumb.style.opacity=0}aq(0);az({position:0,duration:0});if(ab.timeRail){ab.timeRail.className="jwrail"}break}}function au(aA){J("mute",aA.mute)}function A(aA){t(aA.volume/100)}function D(aA){aq(aA.bufferPercent/100)}function M(){i.clearCss("#"+ae);g("#"+ae,{height:S("background").height,bottom:K.position=="OVER"?K.margin:0,left:K.position=="OVER"?K.margin:0,right:K.position=="OVER"?K.margin:0});g(ai(".jwtext"),{font:K.fontsize+"px/"+S("background").height+"px "+K.font,color:K.fontcolor,"font-weight":K.fontweight,"font-style":K.fontstyle,"text-align":"center",padding:"0 5px"})}function ai(aA){return"#"+ae+" "+aA}function G(){return document.createElement("span")}function aj(){var aC=ac("capLeft");var aB=ac("capRight");var aA=ac("background",{position:f,left:S("capLeft").width,right:S("capRight").width,"background-repeat":"repeat-x"},true);an.style.opacity=0;if(aA){an.appendChild(aA)}if(aC){an.appendChild(aC)}ak();if(aB){an.appendChild(aB)}setTimeout(function(){X();h.utils.animations.fadeIn(an,250)},1000)}function H(aA){switch(aA.type){case d:return V(aA);break;case m:return ad(aA.name);break;case b:if(aA.name!="blank"){return U(aA.name)}break;case n:return I(aA.name);break}}function ac(aC,aF,aB,aH){var aE=G();aE.className="jw"+aC;var aA=aH?" left center":" center";var aD=S(aC);aE.innerHTML="&nbsp;";if(!aD||aD.src==""){return}var aG;if(aB){aG={background:"url('"+aD.src+"') repeat-x "+aA}}else{aG={background:"url('"+aD.src+"') no-repeat"+aA,width:aD.width}}g(ai(".jw"+aC),i.extend(aG,aF));ab[aC]=aE;return aE}function U(aC){if(!S(aC+"Button").src){return null}var aD=document.createElement("button");aD.className="jw"+aC;aD.addEventListener("click",Z(aC),false);var aE=S(aC+"Button");var aB=S(aC+"ButtonOver");aD.innerHTML="&nbsp;";L(ai(".jw"+aC),aE,aB);var aA=O[aC];if(aA){L(ai(".jw"+aC+".jwtoggle"),S(aA+"Button"),S(aA+"ButtonOver"))}ab[aC]=aD;return aD}function L(aA,aB,aC){if(!aB.src){return}g(aA,{width:aB.width,background:"url("+aB.src+") center no-repeat"});if(aC.src){g(aA+":hover",{background:"url("+aC.src+") center no-repeat"})}}function Z(aA){return function(){if(v[aA]){v[aA]()}}}function T(){if(ao.play){w.jwPause()}else{w.jwPlay()}}function F(){w.jwSetMute()}function at(aA){if(aA<0.1){aA=0}if(aA>0.9){aA=1}w.jwSetVolume(aA*100)}function N(aA){if(!Y){w.jwPlay()}w.jwSeek(aA*ay)}function Q(){J("fullscreen")}function u(){w.jwPlaylistNext()}function W(){w.jwPlaylistNext()}function J(aA,aB){if(!i.exists(aB)){aB=!ao[aA]}if(ab[aA]){ab[aA].className="jw"+aA+(aB?" jwtoggle":"")}ao[aA]=aB}function E(aA){return ae+"_"+aA}function ad(aA,aE){var aC=G();aC.id=E(aA);aC.className="jwtext jw"+aA;var aB={};var aD=S(aA+"Background");if(aD.src){aB.background="url("+aD.src+") no-repeat center";aB["background-size"]="100% "+S("background").height+"px"}g(ai(".jw"+aA),aB);aC.innerHTML="00:00";ab[aA]=aC;return aC}function V(aB){if(aB.width){var aA=G();aA.className="jwblankDivider";g(aA,{width:parseInt(aB.width)});return aA}else{if(aB.element){return ac(aB.element)}else{return ac(aB.name)}}}function I(aA){var aD=G();aD.className="jwslider jw"+aA;var aC=ac(aA+"SliderCapLeft");var aB=ac(aA+"SliderCapRight");if(aB){aB.className+=" jwcapRight"}var aE=af(aA);if(aC){aD.appendChild(aC)}aD.appendChild(aE);if(aC){aD.appendChild(aB)}g(ai(".jw"+aA+" .jwrail"),{left:S(aA+"SliderCapLeft").width,right:S(aA+"SliderCapRight").width,});ab[aA]=aD;if(aA=="time"){aw(aD);am(0);aq(0)}else{if(aA=="volume"){al(aD)}}return aD}function af(aC){var aF=G();aF.className="jwrail jwsmooth";var aA=["Rail","Buffer","Progress"];for(var aE=0;aE<aA.length;aE++){var aD=ac(aC+"Slider"+aA[aE],null,true,(aC=="volume"));if(aD){aD.className+=" jwstretch";aF.appendChild(aD)}}var aB=ac(aC+"SliderThumb");if(aB){aB.className+=" jwthumb";aB.style.opacity=0;aF.appendChild(aB)}aF.addEventListener("mousedown",C(aC),false);ab[aC+"Rail"]=aF;return aF}var Y;function C(aA){return(function(aB){if(aB.button!=0){return}ab[aA+"Rail"].className="jwrail";if(aA=="time"){if(w.jwGetState()!=jwplayer.events.state.IDLE){w.jwPause();Y=aA}}else{Y=aA}})}var ag=0;function ax(aA){if(!Y||aA.button!=0){return}var aE=ab[Y].getElementsByClassName("jwrail")[0],aF=i.getBoundingClientRect(aE),aD=(aA.clientX-aF.left)/aF.width;if(aA.type=="mouseup"){var aB=Y;ab[aB+"Rail"].className="jwrail jwsmooth";Y=null;z[aB](aD)}else{if(Y=="time"){am(aD)}else{t(aD)}var aC=(new Date()).getTime();if(aC-ag>500){ag=aC;z[Y](aD)}}}function aw(aA){if(ab.timeSliderThumb){g(ai(".jwtimeSliderThumb"),{"margin-left":(S("timeSliderThumb").width/-2)})}aq(0);am(0)}function al(aC){var aB=S("volumeSliderCapLeft").width,aA=S("volumeSliderCapRight").width,aD=S("volumeSliderRail").width;g(ai(".jwvolume"),{width:(aB+aD+aA)})}var P={};function ak(){av("left");av("center");av("right");an.appendChild(P.left);an.appendChild(P.center);an.appendChild(P.right);g(ai(".jwright"),{right:S("capRight").width})}function av(aB){var aA=G();aA.className="jwgroup jw"+aB;P[aB]=aA;if(ap[aB]){R(ap[aB],P[aB])}}function R(aD,aA){if(aD&&aD.elements.length>0){for(var aC=0;aC<aD.elements.length;aC++){var aB=H(aD.elements[aC]);if(aB){aA.appendChild(aB)}}}}var X=this.resize=function(aB,aA){g(ai(".jwgroup.jwcenter"),{left:Math.round(i.parseDimension(P.left.offsetWidth)+S("capLeft").width),right:Math.round(i.parseDimension(P.right.offsetWidth)+S("capRight").width)})};this.getDisplayElement=function(){return an};var aq=this.setBuffer=function(aA){aA=Math.min(Math.max(0,aA),1);ab.timeSliderBuffer.style.width=aA*i.getBoundingClientRect(ab.timeSliderRail).width+"px"};function aa(aC,aE,aF){if(!ab[aC]){return}aE=Math.min(Math.max(0,aE),1);var aB=ab[aC+"SliderProgress"];var aA=ab[aC+"SliderThumb"];var aD=aE*i.getBoundingClientRect(ab[aC+"SliderRail"]).width+"px";if(aB){aB.style.width=aD}if(aA){aA.style.left=aD}}function t(aA){aa("volume",aA,true)}function am(aA){aa("time",aA)}this.getSkin=function(){return w.skin};function S(aA){if(w.skin.controlbar.elements[aA]){return w.skin.controlbar.elements[aA]}else{return{width:0,height:0,src:"",image:undefined,ready:false}}}ar()};function q(){g(CB_CLASS,{position:f,overflow:"hidden"});g(CB_CLASS+" span",{height:j,"-webkit-user-select":a,"-webkit-user-drag":a,"user-select":a,"user-drag":a});g(CB_CLASS+" .jwgroup",{display:p});g(CB_CLASS+" span, "+CB_CLASS+" .jwgroup button,"+CB_CLASS+" .jwleft",{position:e,"float":c});g(CB_CLASS+" .jwright",{position:f});g(CB_CLASS+" .jwcenter",{position:f});g(CB_CLASS+" button",{display:k,height:j,border:a,cursor:"pointer","-webkit-transition":"background-image .25s","-moz-transition":"background-image .25s","-o-transition":"background-image .25s"});g(CB_CLASS+" .jwcapRight",{right:0,position:f});g(CB_CLASS+" .jwtime,"+CB_CLASS+" .jwgroup span.jwstretch",{position:f,height:j,width:j,left:0});g(CB_CLASS+" .jwrail,"+CB_CLASS+" .jwthumb",{position:f,height:j,cursor:"pointer"});g(CB_CLASS+" .jwtime .jwsmooth span",{"-webkit-transition":o,"-moz-transition":o,"-o-transition":o});g(CB_CLASS+" .jwdivider+.jwdivider",{display:a});g(CB_CLASS+" .jwtext",{padding:"0 5px","text-align":"center"})}q()})(jwplayer.html5);(function(a){var b=jwplayer.utils;a.controller=function(i,l){var j=i,h=l,f=i.video,e="console",c=new jwplayer.events.eventdispatcher(j.id,e);b.extend(this,c);function k(){j.addGlobalListener(g)}function g(m){c.sendEvent(m.type,m)}var d;this.load=function(m){if(f.getTag().canPlayType("video/mp4")){d="http://playertest.longtailvideo.com/bunny.mp4"}else{if(f.getTag().canPlayType("video/webm")){d="http://playertest.longtailvideo.com/bunny.webm"}else{d="http://playertest.longtailvideo.com/bunny.ogv"}}};this.play=function(){if(j.state==jwplayer.events.state.IDLE){f.load(d)}f.play()};this.stop=function(){f.stop()};this.pause=function(){if(j.state==jwplayer.events.state.PLAYING||j.state==jwplayer.events.state.BUFFERING){f.pause()}};this.seek=function(m){f.seek(m)};this.volume=function(m){f.volume(m)};this.mute=function(m){if(!b.exists(m)){m=!j.mute}f.mute(m)};this.prev=function(){};this.next=function(){};this.item=function(m){};this.fullscreen=function(m){};k()}})(jwplayer.html5);(function(a){a.html5.defaultskin=function(){this.text='<?xml version="1.0" ?><skin author="LongTail Video" name="Five" version="1.1"><components><component name="controlbar"><settings><setting name="margin" value="20"/><setting name="fontsize" value="11"/><setting name="fontcolor" value="0x000000"/></settings><layout><group position="left"><button name="play"/><divider name="divider"/><button name="prev"/><divider name="divider"/><button name="next"/><divider name="divider"/><text name="elapsed"/></group><group position="center"><slider name="time"/></group><group position="right"><text name="duration"/><divider name="divider"/><button name="blank"/><divider name="divider"/><button name="mute"/><slider name="volume"/><divider name="divider"/><button name="fullscreen"/></group></layout><elements><element name="background" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAIAAABvFaqvAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAElJREFUOI3t1LERACAMQlFgGvcfxNIhHMK4gsUvUviOmgtNsiAZkBSEKxKEnCYkkQrJn/YwbUNiSDDYRZaQRDaShv+oX9GBZEIuK+8hXVLs+/YAAAAASUVORK5CYII="/><element name="blankButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAYCAYAAAAyJzegAAAAFElEQVQYV2P8//8/AzpgHBUc7oIAGZdH0RjKN8EAAAAASUVORK5CYII="/><element name="capLeft" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAYAAAA7zJfaAAAAQElEQVQIWz3LsRGAMADDQJ0XB5bMINABZ9GENGrszxhjT2WLSqxEJG2JQrTMdV2q5LpOAvyRaVmsi7WdeZ/7+AAaOTq7BVrfOQAAAABJRU5ErkJggg=="/><element name="capRight" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAYAAAA7zJfaAAAAQElEQVQIWz3LsRGAMADDQJ0XB5bMINABZ9GENGrszxhjT2WLSqxEJG2JQrTMdV2q5LpOAvyRaVmsi7WdeZ/7+AAaOTq7BVrfOQAAAABJRU5ErkJggg=="/><element name="divider" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAIAAAC0rgCNAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADhJREFUCB0FwcENgEAAw7Aq+893g8APUILNOQcbFRktVGqUVFRkWNz3xTa2sUaLNUosKlRUvvf5AdbWOTtzmzyWAAAAAElFTkSuQmCC"/><element name="playButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAYCAYAAAAVibZIAAAANUlEQVR42u2RsQkAAAjD/NTTPaW6dXLrINJA1kBpGPMAjDWmOgp1HFQXx+b1KOefO4oxY57R73YnVYCQUCQAAAAASUVORK5CYII="/><element name="pauseButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAYCAYAAAAVibZIAAAAIUlEQVQ4jWNgGAWjYOiD/0gYG3/U0FFDB4Oho2AUDAYAAEwiL9HrpdMVAAAAAElFTkSuQmCC"/><element name="prevButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAYCAYAAAAVibZIAAAAQklEQVQ4y2NgGAWjYOiD/1AMA/JAfB5NjCJD/YH4PRaLyDa0H4lNNUP/DxlD59PCUBCIp3ZEwYA+NZLUKBgFgwEAAN+HLX9sB8u8AAAAAElFTkSuQmCC"/><element name="nextButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAYCAYAAAAVibZIAAAAQElEQVQ4y2NgGAWjYOiD/0B8Hojl0cT+U2ooCL8HYn9qGwrD/bQw9P+QMXQ+tSMqnpoRBUpS+tRMUqNgFAwGAADxZy1/mHvFnAAAAABJRU5ErkJggg=="/><element name="timeSliderRail" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAOElEQVRIDe3BwQkAIRADwAhhw/nU/kWwUK+KPITMABFh19Y+F0acY8CJvX9wYpXgRElwolSIiMf9ZWEDhtwurFsAAAAASUVORK5CYII="/><element name="timeSliderBuffer" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAN0lEQVRIDe3BwQkAMQwDMBcc55mRe9zi7RR+FCwBEWG39vcfGHFm4MTuhhMlwYlVBSdKhYh43AW/LQMKm1spzwAAAABJRU5ErkJggg=="/><element name="timeSliderProgress" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAIElEQVRIiWNgGAWjYBTQBfynMR61YCRYMApGwSigMQAAiVWPcbq6UkIAAAAASUVORK5CYII="/><element name="timeSliderThumb" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAYCAYAAAA/OUfnAAAAO0lEQVQYlWP4//8/Awwz0JgDBP/BeN6Cxf/hnI2btiI4u/fsQ3AOHjqK4Jw4eQbBOX/hEoKDYjSd/AMA4cS4mfLsorgAAAAASUVORK5CYII="/><element name="muteButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAYCAYAAADKx8xXAAAAJklEQVQ4y2NgGAUjDcwH4v/kaPxPikZkxcNVI9mBQ5XoGAWDFwAAsKAXKQQmfbUAAAAASUVORK5CYII="/><element name="unmuteButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAYCAYAAADKx8xXAAAAMklEQVQ4y2NgGAWDHPyntub5xBr6Hwv/Pzk2/yfVG/8psRFE25Oq8T+tQnsIaB4FVAcAi2YVysVY52AAAAAASUVORK5CYII="/><element name="volumeSliderRail" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYAgMAAACdGdVrAAAACVBMVEUAAACmpqampqbBXAu8AAAAAnRSTlMAgJsrThgAAAArSURBVAhbY2AgErBAyA4I2QEhOyBkB4TsYOhAoaCCUCUwDTDtMMNgRuMHAFB5FoGH5T0UAAAAAElFTkSuQmCC"/><element name="volumeSliderProgress" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYAgMAAACdGdVrAAAACVBMVEUAAAAAAAAAAACDY+nAAAAAAnRSTlMAgJsrThgAAAArSURBVAhbY2AgErBAyA4I2QEhOyBkB4TsYOhAoaCCUCUwDTDtMMNgRuMHAFB5FoGH5T0UAAAAAElFTkSuQmCC"/><element name="volumeSliderCapRight" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAYCAYAAAAyJzegAAAAFElEQVQYV2P8//8/AzpgHBUc7oIAGZdH0RjKN8EAAAAASUVORK5CYII="/><element name="fullscreenButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAQklEQVRIiWNgGAWjYMiD/0iYFDmSLbDHImdPLQtgBpEiR7Zl2NijAA5oEkT/0Whi5UiyAJ8BVMsHNMtoo2AUDAIAAGdcIN3IDNXoAAAAAElFTkSuQmCC"/><element name="normalscreenButton" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAP0lEQVRIx2NgGAWjYMiD/1RSQ5QB/wmIUWzJfzx8qhj+n4DYCAY0DyJ7PBbYU8sHMEvwiZFtODXUjIJRMJgBACpWIN2ZxdPTAAAAAElFTkSuQmCC"/></elements></component><component name="display"><elements><element name="background" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyAQMAAAAk8RryAAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlOZpuml+rYAAAASSURBVBhXY2AYJuA/GBwY6jQAyDyoK8QcL4QAAAAASUVORK5CYII="/><element name="playIcon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAiUlEQVR42u3XSw2AMBREURwgAQlIQAISKgUpSEFKJeCg5b0E0kWBTVcD9ySTsL0Jn9IBAAAA+K2UUrBlW/Rr5ZDoIeeuoFkxJD9ss03aIXXQqB9SttoG7ZA6qNcOKdttiwcJh9RB+iFl4SshkRBuLR72+9cvH0SOKI2HRo7x/Fi1/uoCAAAAwLsD8ki99IlO2dQAAAAASUVORK5CYII="/><element name="muteIcon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAAVUlEQVR42u3WMQrAIAxAUW/g/SdvGmvpoOBeSHgPsjj5QTANAACARCJilIhYM0tEvJM+Ik3Id9E957kQIb+F3OdCPC0hPkQriqWx9hp/x/QGAABQyAPLB22VGrpLDgAAAABJRU5ErkJggg=="/><element name="errorIcon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAAA/0lEQVR42u2U0QmEMBAF7cASLMESUoIlpARLSCkpwRJSgiWkhOvAXD4WsgRkyaG5DbyB+Yvg8KITAAAAAAAYk+u61mwk15EjPtlEfihmqIiZR1Qx80ghjgdUuiHXGHSVsoag0x6x8DUoyjD5KovmEJ9NTDMRPIT0mtdIUkjlonuNohO+Ha99DTmkuGgKCTcvebAzx82ZoCWC3/3aIMWSRucaxcjORSFY4xpFdjYJGp1rFGcyCYZ/RVh6AUnfcNZ2zih3/mGj1jVCdiNDwyrq1rA/xMdeEXvDVdnYc1vDc3uPkDObXrlaxbNHSOohQhr/WOeLEWfWTgAAAAAAADzNF9sHJ7PJ57MlAAAAAElFTkSuQmCC"/><element name="bufferIcon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAYAAAAeP4ixAAACBklEQVR42u3Zv0sCYRzH8USTzOsHHEWGkC1HgaDgkktGDjUYtDQ01RDSljQ1BLU02+rk1NTm2NLq4Nx/0L/h9fnCd3j4cnZe1/U8xiO8h3uurufF0/3COd/3/0UWYiEWYiEWYiGJQ+J8xuPxKhXjEMZANinjIZhkGuVRNioE4wVURo4JkHm0xKWmhRAc1bh1EyCUw5BcBIjHiApKa4CErko6DEJwuRo6IRKzyJD8FJAyI3Zp2zRImiBcRhlfo5RtlxCcE3CcDNpGrhYIT2IhAJKilO0VRmzJ32fAMTpBTS0QMfGwlcuKMRftE0DJ0wCJdcOsCkBdXP3Mh9CEFUBTPS9mDZJBG6io4aqVzMdCokCw9H3kT6j/C/9iDdSeUMNC7DkyyxAs/Rk6Qss8FPWRZgdVtUH4DjxEn1zxh+/zj1wHlf4MQhNGrwqA6sY40U8JonRJwEQh+AO3AvCG6gHv4U7IY4krxkroWoAOkoQMGfCBrgIm+YBGqPENpIJ66CJg3x66Y0gnSUidAEEnNr9jjLiWMn5DiWP0OC/oAsCgkq43xBdGDMQr7YASP/vEkHvdl1+JOCcEV5sC4hGEOzTlPuKgd0b0xD4JkRcOgnRRTjdErkYhAsQVq6IdUuPJtmk7BCL3t/h88cx91pKQkI/pkDx6pmYTIjEoxiHsN1YWYiEWYiEWknhflZ5IErA5nr8AAAAASUVORK5CYII="/></elements></component><component name="dock"><settings><setting name="fontcolor" value="0xffffff"/></settings><elements><element name="button" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyAQMAAAAk8RryAAAABlBMVEUAAAAAAAClZ7nPAAAAAnRSTlOZpuml+rYAAAASSURBVBhXY2AYJuA/GBwY6jQAyDyoK8QcL4QAAAAASUVORK5CYII="/></elements></component><component name="playlist"><settings><setting name="backgroundcolor" value="0xe8e8e8"/></settings><elements><element name="item" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADwAAAA8CAIAAAC1nk4lAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAHBJREFUaN7t2MENwCAMBEEe9N8wSKYC/D8YV7CyJoRkVtVImxkZPQInMxoP0XiIxkM0HsGbjjSNBx544IEHHnjggUe/6UQeey0PIh7XTftGxKPj4eXCtLsHHh+ZxkO0Iw8PR55Ni8ZD9Hu/EAoP0dc5RRg9qeRjVF8AAAAASUVORK5CYII="/><element name="sliderCapTop" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAHCAYAAADnCQYGAAAAFUlEQVQokWP8//8/A7UB46ihI9hQAKt6FPPXhVGHAAAAAElFTkSuQmCC"/><element name="sliderRail" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAUCAYAAABiS3YzAAAAKElEQVQ4y2P4//8/Az68bNmy/+iYkB6GUUNHDR01dNTQUUNHDaXcUABUDOKhcxnsSwAAAABJRU5ErkJggg=="/><element name="sliderThumb" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAUCAYAAABiS3YzAAAAJUlEQVQ4T2P4//8/Ay4MBP9xYbz6Rg0dNXTU0FFDRw0dNZRyQwHH4NBa7GJsXAAAAABJRU5ErkJggg=="/><element name="sliderCapBottom" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABUAAAAHCAYAAADnCQYGAAAAFUlEQVQokWP8//8/A7UB46ihI9hQAKt6FPPXhVGHAAAAAElFTkSuQmCC"/></elements></component></components></skin>';this.xml=null;if(window.DOMParser){parser=new DOMParser();this.xml=parser.parseFromString(this.text,"text/xml")}else{this.xml=new ActiveXObject("Microsoft.XMLDOM");this.xml.async="false";this.xml.loadXML(this.text)}return this}})(jwplayer);(function(a){a.player=function(b){var f,g,e,c=this;function d(){f={id:"player",video:new a.video(document.createElement("video")),settings:b,volume:0,state:jwplayer.events.state.IDLE,mute:false};jwplayer.utils.extend(f,new jwplayer.events.eventdispatcher());f.video.addGlobalListener(function(h){switch(h.type){case jwplayer.events.JWPLAYER_MEDIA_MUTE:if(f.mute==h.mute){return}f.mute=h.mute;break;case jwplayer.events.JWPLAYER_MEDIA_VOLUME:if(f.volume==h.volume){return}f.volume=h.volume;break;case jwplayer.events.JWPLAYER_PLAYER_STATE:if(f.state==h.newstate){return}f.state=h.newstate}f.sendEvent(h.type,h)});c.id=f.id;c.settings=f.settings;g={};e=new a.controller(f,g);c.addEventListener=e.addEventListener;c.removeEventListener=e.removeEventListener;g.container=document.getElementById(c.id),g.controlbar=new a.controlbar(c,f.settings);jwplayer.utils.appendStylesheet("#"+c.id+" video",{width:"100%",height:"100%",background:"#000",opacity:0,"-webkit-transition":"opacity .15s ease"});g.container.appendChild(f.video.getTag());g.container.appendChild(g.controlbar.getDisplayElement());e.load()}this.jwPlay=function(){e.play()};this.jwPause=function(){e.pause()};this.jwStop=function(){e.stop()};this.jwSeek=function(h){e.seek(h)};this.jwSetVolume=function(h){e.volume(h)};this.jwSetMute=function(h){e.mute(h)};this.jwLoad=function(h){e.load(h)};this.jwPlaylistNext=function(){e.next()};this.jwPlaylistPrev=function(){e.prev()};this.jwPlaylistItem=function(h){e.item(h)};this.jwFullscreen=function(h){e.fullscreen(h)};this.jwGetState=function(){return f.state};this.jwGetVolume=function(){return f.volume};this.jwGetMute=function(){return f.mute};this.jwGetFullscreen=function(){return false};d()}})(jwplayer.html5);(function(a){a.html5.skin=function(){var b={};var c=false;this.load=function(d,e){new a.html5.skinloader(d,function(f){c=true;b=f;e()},function(){new a.html5.skinloader("",function(f){c=true;b=f;e()})})};this.getSkinElement=function(d,e){if(c){try{return b[d].elements[e]}catch(f){a.utils.log("No such skin component / element: ",[d,e])}}return null};this.getComponentSettings=function(d){if(c&&b&&b[d]){return b[d].settings}return null};this.getComponentLayout=function(d){if(c){var e=b[d].layout;if(e&&(e.left||e.right||e.center)){return b[d].layout}}return null}}})(jwplayer);(function(a){a.html5.skinloader=function(f,o,j){var n={};var c=o;var k=j;var e=true;var i;var m=f;var r=false;function l(){if(typeof m!="string"||m===""){d(a.html5.defaultskin().xml)}else{a.utils.ajax(a.utils.getAbsolutePath(m),function(s){try{if(a.utils.exists(s.responseXML)){d(s.responseXML);return}}catch(t){h()}d(a.html5.defaultskin().xml)},function(s){d(a.html5.defaultskin().xml)})}}function d(x){var D=x.getElementsByTagName("component");if(D.length===0){return}for(var G=0;G<D.length;G++){var B=D[G].getAttribute("name");var A={settings:{},elements:{},layout:{}};n[B]=A;var F=D[G].getElementsByTagName("elements")[0].getElementsByTagName("element");for(var E=0;E<F.length;E++){b(F[E],B)}var y=D[G].getElementsByTagName("settings")[0];if(y&&y.childNodes.length>0){var J=y.getElementsByTagName("setting");for(var O=0;O<J.length;O++){var P=J[O].getAttribute("name");var H=J[O].getAttribute("value");var w=/color$/.test(P)?"color":null;n[B].settings[P]=a.utils.typechecker(H,w)}}var K=D[G].getElementsByTagName("layout")[0];if(K&&K.childNodes.length>0){var L=K.getElementsByTagName("group");for(var v=0;v<L.length;v++){var z=L[v];n[B].layout[z.getAttribute("position")]={elements:[]};for(var N=0;N<z.attributes.length;N++){var C=z.attributes[N];n[B].layout[z.getAttribute("position")][C.name]=C.value}var M=z.getElementsByTagName("*");for(var u=0;u<M.length;u++){var s=M[u];n[B].layout[z.getAttribute("position")].elements.push({type:s.tagName});for(var t=0;t<s.attributes.length;t++){var I=s.attributes[t];n[B].layout[z.getAttribute("position")].elements[u][I.name]=I.value}if(!a.utils.exists(n[B].layout[z.getAttribute("position")].elements[u].name)){n[B].layout[z.getAttribute("position")].elements[u].name=s.tagName}}}}e=false;q()}}function q(){clearInterval(i);if(!r){i=setInterval(function(){p()},100)}}function b(x,w){var v=new Image();var s=x.getAttribute("name");var u=x.getAttribute("src");var z;if(u.indexOf("data:image/png;base64,")===0){z=u}else{var t=a.utils.getAbsolutePath(m);var y=t.substr(0,t.lastIndexOf("/"));z=[y,w,u].join("/")}n[w].elements[s]={height:0,width:0,src:"",ready:false,image:v};v.onload=function(A){g(v,s,w)};v.onerror=function(A){r=true;q();k()};v.src=z}function h(){for(var t in n){var v=n[t];for(var s in v.elements){var w=v.elements[s];var u=w.image;u.onload=null;u.onerror=null;delete w.image;delete v.elements[s]}delete n[t]}}function p(){for(var s in n){if(s!="properties"){for(var t in n[s].elements){if(!n[s].elements[t].ready){return}}}}if(e===false){clearInterval(i);c(n)}}function g(s,u,t){if(n[t]&&n[t].elements[u]){n[t].elements[u].height=s.height;n[t].elements[u].width=s.width;n[t].elements[u].src=s.src;n[t].elements[u].ready=true;q()}else{a.utils.log("Loaded an image for a missing element: "+t+"."+u)}}l()}})(jwplayer);(function(a){var b=jwplayer.utils;a.video=function(w){var q={abort:n,canplay:B,canplaythrough:n,durationchange:d,emptied:n,ended:n,error:t,loadeddata:n,loadedmetadata:n,loadstart:n,pause:i,play:i,playing:n,progress:n,ratechange:n,readystatechange:n,seeked:n,seeking:n,stalled:n,suspend:n,timeupdate:g,volumechange:y,waiting:n},m,r,p,z=jwplayer.events.state.IDLE,l=0,h=-1,s=-1,j=new jwplayer.events.eventdispatcher();b.extend(this,j);function o(D){m=D;C()}function C(){for(var D in q){m.addEventListener(D,q[D],false)}}function v(D,E){j.sendEvent(D,E)}function n(D){}function d(D){_duration=m.duration;g()}function g(D){if(z==jwplayer.events.state.PLAYING){v(jwplayer.events.JWPLAYER_MEDIA_TIME,{position:m.currentTime,duration:_duration});if(m.currentTime>=_duration){x()}}}function B(D){r=true;n(D);if(p>0){u(p)}}function i(D){if(m.paused){A(jwplayer.events.state.PAUSED)}else{A(jwplayer.events.state.PLAYING)}}function t(D){console.log("Error: %o",m.error);n(D)}this.load=function(D){r=false;p=0;_duration=0;m.src=D;m.load();h=setInterval(e,100)};var k=this.stop=function(){m.removeAttribute("src");m.load();m.style.opacity=0;clearInterval(h);A(jwplayer.events.state.IDLE)};this.play=function(){m.style.opacity=1;m.play()};this.pause=function(){m.pause()};var u=this.seek=function(D){if(r){p=0;m.currentTime=D}else{p=D}};var f=this.volume=function(D){if(m.muted){m.muted=false}m.volume=D/100};function y(D){v(jwplayer.events.JWPLAYER_MEDIA_VOLUME,{volume:Math.round(m.volume*100)});v(jwplayer.events.JWPLAYER_MEDIA_MUTE,{mute:m.muted})}this.mute=function(D){if(!b.exists(D)){D=!m.mute}if(D){l=m.volume*100;f(0);m.muted=true}else{f(l)}};function A(D){if(D==jwplayer.events.state.PAUSED&&z==jwplayer.events.state.IDLE){return}if(z!=D){var E=z;z=D;v(jwplayer.events.JWPLAYER_PLAYER_STATE,{oldstate:E,newstate:D})}}function e(){var D=c();if(D!=s){s=D;v(jwplayer.events.JWPLAYER_MEDIA_BUFFER,{bufferPercent:Math.round(s*100)})}if(D>=1){clearInterval(h)}}function c(){if(m.buffered.length==0||m.duration==0){return 0}else{return m.buffered.end(m.buffered.length-1)/m.duration}}function x(){k();v(jwplayer.events.JWPLAYER_MEDIA_COMPLETE)}this.getTag=function(){return w};o(w)}})(jwplayer.html5);(function(a){a.utils={}})(jwplayer.html5);(function(a){a.animations=function(d,j,t,e,b,q){var p,o,l,r,h,k,i,g;var s,w,f,w,c;function m(){k=q?q:a.animations.easing.quint.easeOut;p=d;o=j;if(p.id&&!a.animations.active[p.id]){a.animations.active[p.id]={}}if(isNaN(t)){if(t.indexOf("%")>0){i="%"}else{if(t.indexOf("px")){i="px"}}l=parseFloat(t.replace(i,""));r=parseFloat(e.replace(i,""))}else{i="";l=parseFloat(t);r=parseFloat(e)}h=parseFloat(b);this.id=Math.random()}this.start=function(){if(p.id){if(a.animations.active[p.id][o]&&a.animations.active[p.id][o]!=g){a.animations.active[p.id][o].stop();newFrom=parseFloat(p.style[o].toString().replace(i,""));w=h*(l/newFrom)}a.animations.active[p.id][o]=g}if(c){clearInterval(c)}f=(new Date()).valueOf();n();c=setInterval(n,a.animations.INTERVAL_SPEED)};this.stop=function(){clearInterval(c);if(p.id){a.animations.active[p.id][o]=null}};function n(){w=(new Date()).valueOf();if(w-f>=h){u();return}value=k((w-f),0,1,h);v(value)}function u(){v(1);g.stop()}function v(x){var y=(l+(r-l)*x);p.style[o]=y+i}g=this;m()};a.animations.INTERVAL_SPEED=10;a.animations.easing={};a.animations.easing.quint={easeIn:function(f,e,h,g){return h*(f/=g)*f*f*f*f+e},easeOut:function(f,e,h,g){return h*((f=f/g-1)*f*f*f*f+1)+e},easeInOut:function(f,e,h,g){if((f/=g/2)<1){return h/2*f*f*f*f*f+e}return h/2*((f-=2)*f*f*f*f+2)+e}};a.animations.easing.linear={easeIn:function(f,e,h,g){return h*f/g+e},easeOut:function(f,e,h,g){return h*f/g+e},easeInOut:function(f,e,h,g){return h*f/g+e}};a.animations.active={};a.animations.fadeIn=function(b,d,e){var c=new a.animations(b,"opacity",0,1,d,e);c.start()};a.animations.fadeOut=function(b,d,e){var c=new a.animations(b,"opacity",1,0,d,e);c.start()};a.animations.transform=function(c,h,f,i,g,b,e){var j=new a.animations(c,"left",h,i,b,e);var d=new a.animations(c,"top",f,g,b,e);j.start();d.start()}})(jwplayer.html5.utils)}; 
  • branches/jw6/src/js/html5/jwplayer.html5.controlbar.js

    r2172 r2173  
    2626                JW_CSS_RIGHT = "right", 
    2727                JW_CSS_100PCT = "100%", 
     28                JW_CSS_SMOOTH_EASE = "width .25s linear 0s, left .25s linear 0s, opacity .25s ease 0s" 
    2829                 
    2930                CB_CLASS = '.jwcontrolbar'; 
     
    3132        /** HTML5 Controlbar class **/ 
    3233        html5.controlbar = function(api, config) { 
    33                 var _api; 
    34  
    35                 var _defaults = { 
    36                         backgroundcolor : "", 
    37                         margin : 10, 
    38                         font : "Arial,sans-serif", 
    39                         fontsize : 10, 
    40                         fontcolor : parseInt("000000", 16), 
    41                         fontstyle : "normal", 
    42                         fontweight : "bold", 
    43                         buttoncolor : parseInt("ffffff", 16), 
    44                         // position : html5.view.positions.BOTTOM, 
    45                         position: "OVER", 
    46                         idlehide : false, 
    47                         hideplaylistcontrols : false, 
    48                         forcenextprev : false, 
    49                         layout : { 
    50                                 "left" : { 
    51                                         "position" : "left", 
    52                                         "elements" : [ { 
    53                                                 "name" : "play", 
    54                                                 "type" : CB_BUTTON 
    55                                         }, { 
    56                                                 "name" : "divider", 
    57                                                 "type" : CB_DIVIDER 
    58                                         }, { 
    59                                                 "name" : "prev", 
    60                                                 "type" : CB_BUTTON 
    61                                         }, { 
    62                                                 "name" : "divider", 
    63                                                 "type" : CB_DIVIDER 
    64                                         }, { 
    65                                                 "name" : "next", 
    66                                                 "type" : CB_BUTTON 
    67                                         }, { 
    68                                                 "name" : "divider", 
    69                                                 "type" : CB_DIVIDER 
    70                                         }, { 
    71                                                 "name" : "elapsed", 
    72                                                 "type" : CB_TEXT 
    73                                         } ] 
    74                                 }, 
    75                                 "center" : { 
    76                                         "position" : "center", 
    77                                         "elements" : [ { 
    78                                                 "name" : "time", 
    79                                                 "type" : CB_SLIDER 
    80                                         } ] 
    81                                 }, 
    82                                 "right" : { 
    83                                         "position" : "right", 
    84                                         "elements" : [ { 
    85                                                 "name" : "duration", 
    86                                                 "type" : CB_TEXT 
    87                                         }, { 
    88                                                 "name" : "blank", 
    89                                                 "type" : CB_BUTTON 
    90                                         }, { 
    91                                                 "name" : "divider", 
    92                                                 "type" : CB_DIVIDER 
    93                                         }, { 
    94                                                 "name" : "mute", 
    95                                                 "type" : CB_BUTTON 
    96                                         }, { 
    97                                                 "name" : "volume", 
    98                                                 "type" : CB_SLIDER 
    99                                         }, { 
    100                                                 "name" : "divider", 
    101                                                 "type" : CB_DIVIDER 
    102                                         }, { 
    103                                                 "name" : "fullscreen", 
    104                                                 "type" : CB_BUTTON 
    105                                         } ] 
    106                                 } 
    107                         } 
    108                 }; 
    109                  
    110                 var _settings, _layout, _elements; 
    111                  
    112                 var _controlbar, _id; 
    113                  
    114                 var _toggles = { 
    115                         play: "pause", 
    116                         mute: "unmute", 
    117                         fullscreen: "normalscreen" 
    118                 } 
    119                  
    120                 var _toggleStates = { 
    121                         play: false, 
    122                         mute: false, 
    123                         fullscreen: false 
    124                 } 
    125                  
    126                 var _buttonMapping = { 
    127                         play: _play, 
    128                         mute: _mute, 
    129                         fullscreen: _fullscreen 
    130                 }; 
     34                var _api, 
     35 
     36                        _defaults = { 
     37                                backgroundcolor : "", 
     38                                margin : 10, 
     39                                font : "Arial,sans-serif", 
     40                                fontsize : 10, 
     41                                fontcolor : parseInt("000000", 16), 
     42                                fontstyle : "normal", 
     43                                fontweight : "bold", 
     44                                buttoncolor : parseInt("ffffff", 16), 
     45                                // position : html5.view.positions.BOTTOM, 
     46                                position: "OVER", 
     47                                idlehide : false, 
     48                                hideplaylistcontrols : false, 
     49                                forcenextprev : false, 
     50                                layout : { 
     51                                        left: { 
     52                                                position: "left", 
     53                                                elements: [ { 
     54                                                        name: "play", 
     55                                                        type: CB_BUTTON 
     56                                                }, { 
     57                                                        name: "divider", 
     58                                                        type: CB_DIVIDER 
     59                                                }, { 
     60                                                        name: "prev", 
     61                                                        type: CB_BUTTON 
     62                                                }, { 
     63                                                        name: "divider", 
     64                                                        type: CB_DIVIDER 
     65                                                }, { 
     66                                                        name: "next", 
     67                                                        type: CB_BUTTON 
     68                                                }, { 
     69                                                        name: "divider", 
     70                                                        type: CB_DIVIDER 
     71                                                }, { 
     72                                                        name: "elapsed", 
     73                                                        type: CB_TEXT 
     74                                                } ] 
     75                                        }, 
     76                                        center: { 
     77                                                position: "center", 
     78                                                elements: [ { 
     79                                                        name: "time", 
     80                                                        type: CB_SLIDER 
     81                                                } ] 
     82                                        }, 
     83                                        right: { 
     84                                                position: "right", 
     85                                                elements: [ { 
     86                                                        name: "duration", 
     87                                                        type: CB_TEXT 
     88                                                }, { 
     89                                                        name: "blank", 
     90                                                        type: CB_BUTTON 
     91                                                }, { 
     92                                                        name: "divider", 
     93                                                        type: CB_DIVIDER 
     94                                                }, { 
     95                                                        name: "mute", 
     96                                                        type: CB_BUTTON 
     97                                                }, { 
     98                                                        name: "volume", 
     99                                                        type: CB_SLIDER 
     100                                                }, { 
     101                                                        name: "divider", 
     102                                                        type: CB_DIVIDER 
     103                                                }, { 
     104                                                        name: "fullscreen", 
     105                                                        type: CB_BUTTON 
     106                                                } ] 
     107                                        } 
     108                                } 
     109                        }, 
     110                 
     111                        _settings,  
     112                        _layout,  
     113                        _elements,  
     114                        _controlbar,  
     115                        _id, 
     116                        _duration, 
     117                         
     118                        _toggles = { 
     119                                play: "pause", 
     120                                mute: "unmute", 
     121                                fullscreen: "normalscreen" 
     122                        }, 
     123                         
     124                        _toggleStates = { 
     125                                play: false, 
     126                                mute: false, 
     127                                fullscreen: false 
     128                        }, 
     129                         
     130                        _buttonMapping = { 
     131                                play: _play, 
     132                                mute: _mute, 
     133                                fullscreen: _fullscreen, 
     134                                next: _next, 
     135                                prev: _prev 
     136                        }, 
     137                         
     138                        _sliderMapping = { 
     139                                time: _seek, 
     140                                volume: _volume 
     141                        } 
     142                 
     143                 
    131144 
    132145                function _init() { 
     
    135148                        _api = api; 
    136149                         
     150 
    137151                        config = _utils.extend({}, config); 
    138152                        _id = _api.id + "_controlbar"; 
     153                        _duration = 0; 
    139154 
    140155                        _controlbar = _createSpan(); 
    141156                        _controlbar.id = _id; 
    142157                        _controlbar.className = "jwcontrolbar"; 
     158 
     159                        // Slider listeners 
     160                        window.addEventListener('mousemove', _sliderMouseEvent, false); 
     161                        window.addEventListener('mouseup', _sliderMouseEvent, false); 
    143162 
    144163                        (new html5.skinloader(config.skin, function(skin) { 
     
    148167                                _createStyles(); 
    149168                                _buildControlbar(); 
    150                         }, function(err) { console.log(err); })); 
    151                          
    152                          
    153                 } 
     169                                _addEventListeners(); 
     170                        }, function(err) { _utils.log(err); })); 
     171                } 
     172                 
     173                function _addEventListeners() { 
     174                        _api.addEventListener(jwplayer.events.JWPLAYER_MEDIA_TIME, _timeUpdated); 
     175                        _api.addEventListener(jwplayer.events.JWPLAYER_PLAYER_STATE, _stateHandler); 
     176                        _api.addEventListener(jwplayer.events.JWPLAYER_MEDIA_MUTE, _muteHandler); 
     177                        _api.addEventListener(jwplayer.events.JWPLAYER_MEDIA_VOLUME, _volumeHandler); 
     178                        _api.addEventListener(jwplayer.events.JWPLAYER_MEDIA_BUFFER, _bufferHandler); 
     179                } 
     180                 
     181                function _timeUpdated(evt) { 
     182                        _duration = evt.duration; 
     183                         
     184                        if (_elements.elapsed) { 
     185                                _elements.elapsed.innerHTML = _utils.timeFormat(evt.position); 
     186                        } 
     187                        if (_elements.duration) { 
     188                                _elements.duration.innerHTML = _utils.timeFormat(evt.duration); 
     189                        } 
     190                        if (evt.duration > 0) { 
     191                                _setProgress(evt.position / evt.duration); 
     192                        } else { 
     193                                _setProgress(0); 
     194                        } 
     195                } 
     196                 
     197                function _stateHandler(evt) { 
     198                        switch (evt.newstate) { 
     199                        case jwplayer.events.state.PLAYING: 
     200                        case jwplayer.events.state.BUFFERING: 
     201                                if (_elements['timeSliderThumb']) { 
     202                                        _elements['timeSliderThumb'].style.opacity = 1; 
     203                                } 
     204                                if (_elements["timeRail"]) { 
     205                                        _elements["timeRail"].className = "jwrail jwsmooth"; 
     206                                } 
     207                                _toggleButton("play", true); 
     208                                break; 
     209                        case jwplayer.events.state.PAUSED: 
     210                                if (!_dragging) { 
     211                                        _toggleButton("play", false); 
     212                                } 
     213                                break; 
     214                        case jwplayer.events.state.IDLE: 
     215                        case jwplayer.events.state.COMPLETED: 
     216                                _toggleButton("play", false); 
     217                                if (_elements['timeSliderThumb']) { 
     218                                        _elements['timeSliderThumb'].style.opacity = 0; 
     219                                } 
     220                                _setBuffer(0); 
     221                                _timeUpdated({ position: 0, duration: 0}); 
     222                                if (_elements["timeRail"]) { 
     223                                        _elements["timeRail"].className = "jwrail"; 
     224                                } 
     225                                break; 
     226                        } 
     227                } 
     228                 
     229                function _muteHandler(evt) { 
     230                        _toggleButton("mute", evt.mute); 
     231                } 
     232 
     233                function _volumeHandler(evt) { 
     234                        _setVolume(evt.volume / 100); 
     235                } 
     236 
     237                function _bufferHandler(evt) { 
     238                        _setBuffer(evt.bufferPercent / 100); 
     239                } 
     240 
    154241 
    155242                /** 
     
    166253                        }); 
    167254                         
    168                         _style(_internalSelector(".text"), { 
     255                        _style(_internalSelector(".jwtext"), { 
    169256                                font: _settings.fontsize + "px/" + _getSkinElement("background").height + "px " + _settings.font, 
    170257                                color: _settings.fontcolor, 
     
    192279                                left: _getSkinElement('capLeft').width, 
    193280                                right: _getSkinElement('capRight').width, 
    194                                 'backgroundRepeat': "repeat-x" 
     281                                'background-repeat': "repeat-x" 
    195282                        }, true); 
    196283 
     
    229316                        var element = _createSpan(); 
    230317                        //element.id = _createElementId(name); 
    231                         element.className = name; 
    232                          
    233                         var center = nocenter ? "" : "center"; 
     318                        element.className = 'jw'+name; 
     319                         
     320                        var center = nocenter ? " left center" : " center"; 
    234321 
    235322                        var skinElem = _getSkinElement(name); 
     
    243330                        if (stretch) { 
    244331                                newStyle = { 
    245                                         background: "url('" + skinElem.src + "') "+center+" repeat-x" 
     332                                        background: "url('" + skinElem.src + "') repeat-x " + center 
    246333                                }; 
    247334                        } else { 
    248335                                newStyle = { 
    249                                         background: "url('" + skinElem.src + "') "+center+" no-repeat", 
     336                                        background: "url('" + skinElem.src + "') no-repeat" + center, 
    250337                                        width: skinElem.width 
    251338                                }; 
    252339                        } 
    253340                         
    254                         _style(_internalSelector('.'+name), _utils.extend(newStyle, style)); 
     341                        _style(_internalSelector('.jw'+name), _utils.extend(newStyle, style)); 
    255342                        _elements[name] = element; 
    256343                        return element; 
     
    258345 
    259346                function _buildButton(name) { 
     347                        if (!_getSkinElement(name + "Button").src) { 
     348                                return null; 
     349                        } 
     350                         
    260351                        var element = document.createElement("button"); 
    261352                        //element.id = _createElementId(name); 
    262                         element.className = name; 
    263                         element.addEventListener("click", (function(name) { return function() { _buttonClickHandler(name) } })(name)); 
     353                        element.className = 'jw'+name; 
     354                        element.addEventListener("click", _buttonClickHandler(name), false); 
    264355 
    265356                        var outSkin = _getSkinElement(name + "Button"); 
     
    267358                         
    268359                        element.innerHTML = "&nbsp;"; 
    269                         if (!_getSkinElement(name + "Button").src) { 
    270                                 return element; 
    271                         } 
    272                          
    273                         _buttonStyle(_internalSelector('.'+name), outSkin, overSkin); 
     360                         
     361                        _buttonStyle(_internalSelector('.jw'+name), outSkin, overSkin); 
    274362                        var toggle = _toggles[name]; 
    275363                        if (toggle) { 
    276                                 _buttonStyle(_internalSelector('.'+name+'.toggle'), _getSkinElement(toggle+"Button"), _getSkinElement(toggle+"ButtonOver")); 
     364                                _buttonStyle(_internalSelector('.jw'+name+'.jwtoggle'), _getSkinElement(toggle+"Button"), _getSkinElement(toggle+"ButtonOver")); 
    277365                        } 
    278366 
     
    300388                 
    301389                function _buttonClickHandler(name) { 
    302                         if (_buttonMapping[name]) { 
    303                                 _buttonMapping[name](); 
     390                        return function() { 
     391                                if (_buttonMapping[name]) { 
     392                                        _buttonMapping[name](); 
     393                                } 
    304394                        } 
    305395                } 
     
    312402                                _api.jwPlay(); 
    313403                        } 
    314                         _toggleButton("play"); 
    315404                } 
    316405                 
    317406                function _mute() { 
    318                         _toggleButton("mute"); 
     407                        _api.jwSetMute(); 
     408                } 
     409                 
     410                function _volume(pct) { 
     411                        if (pct < 0.1) pct = 0; 
     412                        if (pct > 0.9) pct = 1; 
     413                        _api.jwSetVolume(pct * 100) 
     414                } 
     415                 
     416                function _seek(pct) { 
     417                        if (!_dragging) { 
     418                                _api.jwPlay(); 
     419                        } 
     420                        _api.jwSeek(pct * _duration); 
    319421                } 
    320422                 
     
    322424                        _toggleButton("fullscreen"); 
    323425                } 
    324                  
    325                 function _toggleButton(name) { 
    326                         _elements[name].className = name + (_toggleStates[name] ? "" : " toggle"); 
    327                         _toggleStates[name] ^= true; 
     426 
     427                function _next() { 
     428                        _api.jwPlaylistNext(); 
     429                } 
     430 
     431                function _prev() { 
     432                        _api.jwPlaylistNext(); 
     433                } 
     434 
     435                function _toggleButton(name, state) { 
     436                        if (!_utils.exists(state)) { 
     437                                state = !_toggleStates[name]; 
     438                        } 
     439                        if (_elements[name]) { 
     440                                _elements[name].className = 'jw' + name + (state ? " jwtoggle" : ""); 
     441                        } 
     442                        _toggleStates[name] = state; 
    328443                } 
    329444                 
    330445                function _createElementId(name) { 
    331                         //return (_id + "_" + name + Math.round(Math.random()*10000000)); 
    332446                        return _id + "_" + name; 
    333447                } 
     
    336450                        var element = _createSpan(); 
    337451                        element.id = _createElementId(name);  
    338                         element.className = "text " + name; 
     452                        element.className = "jwtext jw" + name; 
    339453                         
    340454                        var css = {}; 
     
    346460                        } 
    347461 
    348                         _style(_internalSelector('.'+name), css); 
     462                        _style(_internalSelector('.jw'+name), css); 
    349463                        element.innerHTML = "00:00"; 
    350464                        _elements[name] = element; 
     
    355469                        if (divider.width) { 
    356470                                var element = _createSpan(); 
    357                                 element.className = "blankDivider"; 
     471                                element.className = "jwblankDivider"; 
    358472                                _style(element, { 
    359473                                        width: parseInt(divider.width) 
     
    369483                function _buildSlider(name) { 
    370484                        var slider = _createSpan(); 
    371                         //slider.id = _createElementId(name); 
    372                         slider.className = "slider " + name; 
    373  
    374                         var rail = _createSpan(); 
    375                         rail.className = "rail"; 
    376  
    377                         var railElements = ['Rail', 'Buffer', 'Progress']; 
    378  
    379                         for (var i=0; i<railElements.length; i++) { 
    380                                 var element = _buildImage(name + "Slider" + railElements[i], null, true, (name=="volume")); 
    381                                 if (element) { 
    382                                         element.className += " stretch"; 
    383                                         rail.appendChild(element); 
    384                                 } 
    385                         } 
    386                          
    387                         var thumb = _buildImage(name + "SliderThumb"); 
    388                         if (thumb) { 
    389                                 thumb.className += " thumb"; 
    390                                 rail.appendChild(thumb); 
    391                         } 
     485                        slider.className = "jwslider jw" + name; 
     486 
    392487 
    393488                        var capLeft = _buildImage(name + "SliderCapLeft"); 
    394489                        var capRight = _buildImage(name + "SliderCapRight"); 
    395                         if (capRight) capRight.className += " capRight"; 
    396  
     490                        if (capRight) capRight.className += " jwcapRight"; 
     491 
     492                        var rail = _buildSliderRail(name); 
     493                         
    397494                        if (capLeft) slider.appendChild(capLeft); 
    398495                        slider.appendChild(rail); 
    399496                        if (capLeft) slider.appendChild(capRight); 
    400497 
    401                         _style(_internalSelector("." + name + " .rail"), { 
     498                        _style(_internalSelector(".jw" + name + " .jwrail"), { 
    402499                                left: _getSkinElement(name+"SliderCapLeft").width, 
    403500                                right: _getSkinElement(name+"SliderCapRight").width, 
    404501                        }); 
     502 
     503                        _elements[name] = slider; 
    405504 
    406505                        if (name == "time") { 
     
    412511                        } 
    413512 
    414                         _elements[name] = slider; 
    415                          
    416                 return slider; 
    417                 } 
     513                         
     514                        return slider; 
     515                } 
     516                 
     517                function _buildSliderRail(name) { 
     518                        var rail = _createSpan(); 
     519                        rail.className = "jwrail jwsmooth"; 
     520 
     521                        var railElements = ['Rail', 'Buffer', 'Progress']; 
     522 
     523                        for (var i=0; i<railElements.length; i++) { 
     524                                var element = _buildImage(name + "Slider" + railElements[i], null, true, (name=="volume")); 
     525                                if (element) { 
     526                                        element.className += " jwstretch"; 
     527                                        rail.appendChild(element); 
     528                                } 
     529                        } 
     530                         
     531                        var thumb = _buildImage(name + "SliderThumb"); 
     532                        if (thumb) { 
     533                                thumb.className += " jwthumb"; 
     534                                thumb.style.opacity = 0; 
     535                                rail.appendChild(thumb); 
     536                        } 
     537                         
     538                        rail.addEventListener('mousedown', _sliderMouseDown(name), false); 
     539                         
     540                        _elements[name+'Rail'] = rail; 
     541                         
     542                        return rail; 
     543                } 
     544                 
     545                var _dragging; 
     546                 
     547                function _sliderMouseDown(name) { 
     548                        return (function(evt) { 
     549                                if (evt.button != 0) 
     550                                        return; 
     551                                 
     552                                _elements[name+'Rail'].className = "jwrail"; 
     553                                 
     554                                if (name == "time") { 
     555                                        if (_api.jwGetState() != jwplayer.events.state.IDLE) { 
     556                                                _api.jwPause(); 
     557                                                _dragging = name; 
     558                                        } 
     559                                } else { 
     560                                        _dragging = name; 
     561                                } 
     562                        }); 
     563                } 
     564                 
     565                var _lastSeekTime = 0; 
     566                 
     567                function _sliderMouseEvent(evt) { 
     568                        if (!_dragging || evt.button != 0) { 
     569                                return; 
     570                        } 
     571                         
     572                        var rail = _elements[_dragging].getElementsByClassName('jwrail')[0], 
     573                                railRect = _utils.getBoundingClientRect(rail), 
     574                                pct = (evt.clientX - railRect.left) / railRect.width; 
     575                         
     576                        if (evt.type == 'mouseup') { 
     577                                var name = _dragging; 
     578                                _elements[name+'Rail'].className = "jwrail jwsmooth"; 
     579                                _dragging = null; 
     580                                _sliderMapping[name](pct); 
     581                        } else { 
     582                                if (_dragging == "time") { 
     583                                        _setProgress(pct); 
     584                                } else { 
     585                                        _setVolume(pct); 
     586                                } 
     587                                var currentTime = (new Date()).getTime(); 
     588                                if (currentTime - _lastSeekTime > 500) { 
     589                                        _lastSeekTime = currentTime; 
     590                                        _sliderMapping[_dragging](pct); 
     591                                } 
     592                        } 
     593                } 
     594 
    418595         
    419596                function _styleTimeSlider(slider) { 
    420597                        if (_elements['timeSliderThumb']) { 
    421                                 _style(_internalSelector(".timeSliderThumb"), { 
     598                                _style(_internalSelector(".jwtimeSliderThumb"), { 
    422599                                        'margin-left': (_getSkinElement("timeSliderThumb").width/-2) 
    423600                                }); 
     
    434611                                railWidth = _getSkinElement("volumeSliderRail").width; 
    435612                         
    436                         _style(_internalSelector(".volume"), { 
     613                        _style(_internalSelector(".jwvolume"), { 
    437614                                width: (capLeftWidth + railWidth + capRightWidth) 
    438615                        }); 
     
    449626                        _controlbar.appendChild(_groups.right); 
    450627                         
    451                         _style(_internalSelector(".right"), { 
     628                        _style(_internalSelector(".jwright"), { 
    452629                                right: _getSkinElement("capRight").width 
    453630                        }); 
     
    457634                function _buildGroup(pos) { 
    458635                        var elem = _createSpan(); 
    459                         elem.className = "group " + pos; 
     636                        elem.className = "jwgroup jw" + pos; 
    460637                        _groups[pos] = elem; 
    461638                        if (_layout[pos]) { 
     
    476653 
    477654                var _resize = this.resize = function(width, height) { 
    478                         _style(_internalSelector('.group.center'), { 
    479                                 left: _utils.parseDimension(_groups.left.offsetWidth) + _getSkinElement("capLeft").width, 
    480                                 right: _utils.parseDimension(_groups.right.offsetWidth) + _getSkinElement("capRight").width 
     655                        _style(_internalSelector('.jwgroup.jwcenter'), { 
     656                                left: Math.round(_utils.parseDimension(_groups.left.offsetWidth) + _getSkinElement("capLeft").width), 
     657                                right: Math.round(_utils.parseDimension(_groups.right.offsetWidth) + _getSkinElement("capRight").width) 
    481658                        }); 
    482659                } 
     
    488665                var _setBuffer = this.setBuffer = function(pct) { 
    489666                        pct = Math.min(Math.max(0, pct), 1); 
    490                         _elements['timeSliderBuffer'].style.width = 100 * pct + "%"; 
     667                        _elements['timeSliderBuffer'].style.width = pct * _utils.getBoundingClientRect(_elements['timeSliderRail']).width + "px"; 
    491668                } 
    492669 
    493670                function _sliderPercent(name, pct, fixedWidth) { 
     671                        if (!_elements[name]) return; 
     672 
    494673                        pct = Math.min(Math.max(0, pct), 1); 
    495674                         
    496675                        var progress = _elements[name+'SliderProgress']; 
    497676                        var thumb = _elements[name+'SliderThumb']; 
    498                          
     677                        var width = pct * _utils.getBoundingClientRect(_elements[name+'SliderRail']).width + "px"; 
     678                 
    499679                        if (progress) { 
    500                                 progress.style.width = 100 * pct + "%"; 
     680                                progress.style.width = width;  
    501681                        } 
    502682                        if (thumb) { 
    503                                 thumb.style.left = pct * _utils.parseDimension(_elements[name+'SliderRail'].clientWidth) + "px"; 
    504                                 //thumb.style.opacity = 0.5; //(pct <= 0 || pct >= 1) ? 0 : 1; 
    505                         } 
    506                 } 
    507                  
    508                 var _setVolume = this.setVolume = function(pct) { 
     683                                thumb.style.left = width; 
     684                        } 
     685                } 
     686                 
     687                function _setVolume (pct) { 
    509688                        _sliderPercent('volume', pct, true); 
    510689                } 
    511690 
    512                 var _setProgress = this.setProgress = function(pct) { 
     691                function _setProgress(pct) { 
    513692                        _sliderPercent('time', pct); 
    514693                } 
     
    550729                        'user-drag': JW_CSS_NONE 
    551730                }); 
    552             _style(CB_CLASS+' .group', { 
     731            _style(CB_CLASS+' .jwgroup', { 
    553732                display: JW_CSS_INLINE 
    554733            }); 
    555             _style(CB_CLASS+' span, '+CB_CLASS+' .group button,'+CB_CLASS+' .left', { 
     734            _style(CB_CLASS+' span, '+CB_CLASS+' .jwgroup button,'+CB_CLASS+' .jwleft', { 
    556735                position: JW_CSS_RELATIVE, 
    557736                        'float': JW_CSS_LEFT 
    558737            }); 
    559                 _style(CB_CLASS+' .right', { 
    560                         position: JW_CSS_RELATIVE, 
    561                         'float': JW_CSS_RIGHT 
     738                _style(CB_CLASS+' .jwright', { 
     739                        position: JW_CSS_ABSOLUTE 
    562740                }); 
    563             _style(CB_CLASS+' .center', { 
    564                 position: JW_CSS_ABSOLUTE, 
    565                         'float': JW_CSS_LEFT 
     741            _style(CB_CLASS+' .jwcenter', { 
     742                position: JW_CSS_ABSOLUTE 
    566743            }); 
    567744            _style(CB_CLASS+' button', { 
     
    570747                border: JW_CSS_NONE, 
    571748                cursor: 'pointer', 
    572                 '-webkit-transition': 'background .5s', 
    573                 '-moz-transition': 'background .5s', 
    574                 '-o-transition': 'background 1s' 
     749                '-webkit-transition': 'background-image .25s', 
     750                '-moz-transition': 'background-image .25s', 
     751                '-o-transition': 'background-image .25s' 
    575752            }); 
    576             _style(CB_CLASS+' button:hover', { 
    577                 '-webkit-transition': 'background 0s', 
    578                 '-moz-transition': 'background 0s', 
    579                 '-o-transition': 'background 0s' 
    580             }); 
    581             _style(CB_CLASS+' .capRight', {  
     753            _style(CB_CLASS+' .jwcapRight', {  
    582754                        right: 0, 
    583755                        position: JW_CSS_ABSOLUTE 
    584756                }); 
    585             _style(CB_CLASS+' .time,' + CB_CLASS + ' .group span.stretch', { 
     757            _style(CB_CLASS+' .jwtime,' + CB_CLASS + ' .jwgroup span.jwstretch', { 
    586758                position: JW_CSS_ABSOLUTE, 
    587759                height: JW_CSS_100PCT, 
     
    589761                left: 0 
    590762            }); 
    591             _style(CB_CLASS+' .rail,' + CB_CLASS + ' .thumb', { 
     763            _style(CB_CLASS+' .jwrail,' + CB_CLASS + ' .jwthumb', { 
    592764                position: JW_CSS_ABSOLUTE, 
    593765                height: JW_CSS_100PCT, 
    594766                cursor: 'pointer' 
    595767            }); 
    596             _style(CB_CLASS + ' .timeSliderThumb', { 
    597                 '-webkit-transition': 'left .5s linear 0s, opacity .5s ease .5s', 
    598                 '-moz-transition': 'left .5s linear 0s, opacity .5s ease .5s' 
    599                 //-o-transition: 'left .5s linear 0s, opacity .5s ease .5s' -- this produces console errors in Opera 
    600             });              
    601             _style(CB_CLASS + ' .timeSliderProgress,' + CB_CLASS + ' .timeSliderBuffer', { 
    602                 '-webkit-transition': 'width .5s linear', 
    603                 '-moz-transition': 'width .5s linear', 
    604                 '-o-transition': 'width .5s linear' 
     768            _style(CB_CLASS + ' .jwtime .jwsmooth span', { 
     769                '-webkit-transition': JW_CSS_SMOOTH_EASE, 
     770                '-moz-transition': JW_CSS_SMOOTH_EASE, 
     771                '-o-transition': JW_CSS_SMOOTH_EASE 
    605772            }); 
    606             _style(CB_CLASS + ' .volume', { 
    607                 display: JW_CSS_INLINE_BLOCK 
    608             }); 
    609             _style(CB_CLASS + ' .divider+.divider', { 
     773            _style(CB_CLASS + ' .jwdivider+.jwdivider', { 
    610774                display: JW_CSS_NONE 
    611775            }); 
    612             _style(CB_CLASS + ' .text', { 
     776            _style(CB_CLASS + ' .jwtext', { 
    613777                        padding: '0 5px', 
    614                         textAlign: 'center' 
     778                        'text-align': 'center' 
    615779                }); 
    616780 
     
    618782         
    619783        _generalStyles(); 
     784         
    620785})(jwplayer.html5); 
  • branches/jw6/src/js/html5/jwplayer.html5.player.js

    r2172 r2173  
    1212                function _init() { 
    1313                        _model = { 
     14                                id: "player", 
    1415                                video: new html5.video(document.createElement("video")), 
    15                                 settings: config 
    16                         }; 
    17                  
    18                         _api.id = "player"; 
    19                         _api.settings = _model.settings; 
    20  
    21                         _view = { 
    22                                 container: document.getElementById(_api.id), 
    23                                 controlbar: new html5.controlbar(_api, _model.settings) 
     16                                settings: config, 
     17                                volume: 0, 
     18                                state: jwplayer.events.state.IDLE, 
     19                                mute: false 
    2420                        }; 
    2521                         
     22                        jwplayer.utils.extend(_model, new jwplayer.events.eventdispatcher()); 
     23                        _model.video.addGlobalListener(function(evt) { 
     24                                switch (evt.type) { 
     25                                case jwplayer.events.JWPLAYER_MEDIA_MUTE: 
     26                                        if (_model.mute == evt.mute) return; 
     27                                        _model.mute = evt.mute; 
     28                                        break; 
     29                                case jwplayer.events.JWPLAYER_MEDIA_VOLUME: 
     30                                        if (_model.volume == evt.volume) return; 
     31                                        _model.volume = evt.volume; 
     32                                        break; 
     33                                case jwplayer.events.JWPLAYER_PLAYER_STATE: 
     34                                        if (_model.state == evt.newstate) return; 
     35                                        _model.state = evt.newstate; 
     36                                } 
     37                                _model.sendEvent(evt.type, evt); 
     38                        }); 
     39                 
     40                        _api.id = _model.id; 
     41                        _api.settings = _model.settings; 
     42                         
     43                        _view = {}; 
     44                         
    2645                        _controller = new html5.controller(_model, _view); 
     46                        _api.addEventListener = _controller.addEventListener; 
     47                        _api.removeEventListener = _controller.removeEventListener; 
     48                         
     49                        _view.container = document.getElementById(_api.id), 
     50                        _view.controlbar = new html5.controlbar(_api, _model.settings) 
     51 
    2752                 
    2853                        jwplayer.utils.appendStylesheet("#"+_api.id+" video", { 
     
    3055                                height: "100%", 
    3156                                background: "#000", 
    32                                 display: "none" 
     57                                opacity: 0, 
     58                                '-webkit-transition': 'opacity .15s ease' 
    3359                        }); 
    3460                         
     
    3662                        _view.container.appendChild(_view.controlbar.getDisplayElement()); 
    3763                         
     64                        _controller.load(); 
    3865                } 
    3966                 
     
    4168                this.jwPause = function(){ _controller.pause() }; 
    4269                this.jwStop = function(){ _controller.stop() }; 
     70                this.jwSeek = function(pos){ _controller.seek(pos) }; 
     71                this.jwSetVolume = function(vol){ _controller.volume(vol) }; 
     72                this.jwSetMute = function(state){ _controller.mute(state) }; 
     73                this.jwLoad = function(item) { _controller.load(item); } 
     74                this.jwPlaylistNext = function() { _controller.next(); } 
     75                this.jwPlaylistPrev = function() { _controller.prev(); } 
     76                this.jwPlaylistItem = function(item) { _controller.item(item); } 
     77                this.jwFullscreen = function(state) { _controller.fullscreen(state); } 
     78                 
     79                this.jwGetState = function(){ return _model.state }; 
     80                this.jwGetVolume = function(){ return _model.volume }; 
     81                this.jwGetMute = function(){ return _model.mute }; 
     82                this.jwGetFullscreen = function(){ return false }; 
     83 
     84 
     85                 
    4386                 
    4487                _init(); 
  • branches/jw6/src/js/html5/jwplayer.html5.video.js

    r2172 r2173  
    66 */ 
    77(function(jwplayerhtml5) { 
    8          
    9   /** HTML5 video class * */ 
    10   jwplayerhtml5.video = function(videotag) { 
    11            
    12           var _mediaEvents = { 
    13                   "abort": _videoEventHandler, 
    14                   "canplay": _canPlayHandler, 
    15                   "canplaythrough": _videoEventHandler, 
    16                   "durationchange": _videoEventHandler, 
    17                   "emptied": _videoEventHandler, 
    18                   "ended": _videoEventHandler, 
    19                   "error": _errorHandler, 
    20                   "loadeddata": _videoEventHandler, 
    21                   "loadedmetadata": _videoEventHandler, 
    22                   "loadstart": _videoEventHandler, 
    23                   "pause": _videoEventHandler, 
    24                   "play": _videoEventHandler, 
    25                   "playing": _videoEventHandler, 
    26                   "progress": _videoEventHandler, 
    27                   "ratechange": _videoEventHandler, 
    28                   "readystatechange": _videoEventHandler, 
    29                   "seeked": _videoEventHandler, 
    30                   "seeking": _videoEventHandler, 
    31                   "stalled": _videoEventHandler, 
    32                   "suspend": _videoEventHandler, 
    33                   "timeupdate": _videoEventHandler, 
    34                   "volumechange": _videoEventHandler, 
    35                   "waiting": _videoEventHandler 
    36           }; 
    37            
    38           // Reference to the video tag 
    39           var _video; 
    40           // Whether seeking is ready yet 
    41           var _canSeek; 
    42           // If we should seek on canplay 
    43           var _delayedSeek; 
    44            
    45           // Constructor 
    46           function _init(videotag) { 
    47                 _video = videotag; 
    48                 _setupListeners(); 
    49           } 
    50            
    51           function _setupListeners() { 
    52                   for (var evt in _mediaEvents) { 
    53                           _video.addEventListener(evt, _mediaEvents[evt]); 
    54                   } 
    55           } 
    56            
    57           function _videoEventHandler(evt) { 
    58                   console.log("%s %o (%s,%s)", evt.type, evt, _bufferedStart(), _bufferedEnd()); 
    59           } 
    60  
    61           function _canPlayHandler(evt) { 
    62                   _canSeek = true; 
    63                   _videoEventHandler(evt); 
    64                   if (_delayedSeek > 0) { 
    65                           _seek(_delayedSeek); 
    66                   } 
    67           } 
    68            
    69           function _errorHandler(evt) { 
    70                   console.log("Error: %o", _video.error); 
    71                   _videoEventHandler(evt); 
    72           } 
    73  
    74           function _bufferedStart() { 
    75                  if (_video.buffered.length > 0) 
    76                          return _video.buffered.start(0); 
    77                  else 
    78                          return 0; 
    79           } 
    80            
    81           function _bufferedEnd() { 
    82                   if (_video.buffered.length > 0) 
    83                          return Math.ceil(_video.buffered.end(_video.buffered.length-1)); 
    84                   else 
    85                          return 0; 
    86           } 
    87  
    88           var _file; 
    89            
    90           this.load = function(videoURL) { 
    91                   _canSeek = false; 
    92                   _delayedSeek = 0; 
    93                   _file = videoURL; 
    94                   _video.src = _file; 
    95                   _video.load(); 
    96                   //_video.pause(); 
    97           } 
    98            
    99           this.stop = function() { 
    100                   //_video.src = ""; 
    101                   _video.removeAttribute("src"); 
    102                   _video.load(); 
    103                   _video.style.display = "none"; 
    104           } 
    105            
    106           this.play = function() { 
    107                   _video.style.display = "block"; 
    108                   _video.play(); 
    109           } 
    110  
    111           this.pause = function() { 
    112                   _video.pause(); 
    113           } 
    114  
    115           var _seek = this.seek = function(pos) { 
    116                   if (_canSeek) { 
    117                           _delayedSeek = 0; 
    118                           _video.play(); 
    119                           _video.currentTime = pos; 
    120                   } else { 
    121                           _delayedSeek = pos; 
    122                   } 
    123           } 
    124  
    125           // Provide access to video tag 
    126           // TODO: remove 
    127           this.getTag = function() { 
    128                   return videotag; 
    129           } 
    130            
    131           // Call constructor 
    132           _init(videotag); 
    133            
    134   } 
    135    
     8 
     9        var _utils = jwplayer.utils; 
     10 
     11        /** HTML5 video class * */ 
     12        jwplayerhtml5.video = function(videotag) { 
     13 
     14                var _mediaEvents = { 
     15                        "abort" : _generalHandler, 
     16                        "canplay" : _canPlayHandler, 
     17                        "canplaythrough" : _generalHandler, 
     18                        "durationchange" : _durationUpdateHandler, 
     19                        "emptied" : _generalHandler, 
     20                        "ended" : _generalHandler, 
     21                        "error" : _errorHandler, 
     22                        "loadeddata" : _generalHandler, 
     23                        "loadedmetadata" : _generalHandler, 
     24                        "loadstart" : _generalHandler, 
     25                        "pause" : _playHandler, 
     26                        "play" : _playHandler, 
     27                        "playing" : _generalHandler, 
     28                        "progress" : _generalHandler, 
     29                        "ratechange" : _generalHandler, 
     30                        "readystatechange" : _generalHandler, 
     31                        "seeked" : _generalHandler, 
     32                        "seeking" : _generalHandler, 
     33                        "stalled" : _generalHandler, 
     34                        "suspend" : _generalHandler, 
     35                        "timeupdate" : _timeUpdateHandler, 
     36                        "volumechange" : _volumeHandler, 
     37                        "waiting" : _generalHandler 
     38                }, 
     39 
     40                // Reference to the video tag 
     41                _video, 
     42                // Whether seeking is ready yet 
     43                _canSeek, 
     44                // If we should seek on canplay 
     45                _delayedSeek, 
     46                // Current media state 
     47                _state = jwplayer.events.state.IDLE, 
     48                // Save the volume state before muting 
     49                _lastVolume = 0, 
     50                // Using setInterval to check buffered ranges 
     51                _bufferInterval = -1, 
     52                // Last sent buffer amount 
     53                _bufferPercent = -1, 
     54                // Event dispatcher 
     55                _eventDispatcher = new jwplayer.events.eventdispatcher(); 
     56 
     57                _utils.extend(this, _eventDispatcher); 
     58 
     59                // Constructor 
     60                function _init(videotag) { 
     61                        _video = videotag; 
     62                        _setupListeners(); 
     63                } 
     64 
     65                function _setupListeners() { 
     66                        for (var evt in _mediaEvents) { 
     67                                _video.addEventListener(evt, _mediaEvents[evt], false); 
     68                        } 
     69                } 
     70 
     71                function _sendEvent(type, data) { 
     72                        _eventDispatcher.sendEvent(type, data); 
     73                } 
     74 
     75                 
     76                function _generalHandler(evt) { 
     77                        //console.log("%s %o (%s,%s)", evt.type, evt); 
     78                } 
     79 
     80                function _durationUpdateHandler(evt) { 
     81                        _duration = _video.duration; 
     82                        _timeUpdateHandler(); 
     83                } 
     84 
     85                function _timeUpdateHandler(evt) { 
     86                        if (_state == jwplayer.events.state.PLAYING) { 
     87                                _sendEvent(jwplayer.events.JWPLAYER_MEDIA_TIME, { 
     88                                        position : _video.currentTime, 
     89                                        duration : _duration 
     90                                }); 
     91                                if (_video.currentTime >= _duration) { 
     92                                        _complete(); 
     93                                } 
     94                        } 
     95                } 
     96 
     97                function _canPlayHandler(evt) { 
     98                        _canSeek = true; 
     99                        _generalHandler(evt); 
     100                        if (_delayedSeek > 0) { 
     101                                _seek(_delayedSeek); 
     102                        } 
     103                } 
     104 
     105                function _playHandler(evt) { 
     106                        if (_video.paused) { 
     107                                _setState(jwplayer.events.state.PAUSED); 
     108                        } else { 
     109                                _setState(jwplayer.events.state.PLAYING); 
     110                        } 
     111                } 
     112 
     113                function _errorHandler(evt) { 
     114                        console.log("Error: %o", _video.error); 
     115                        _generalHandler(evt); 
     116                } 
     117 
     118                this.load = function(videoURL) { 
     119                        _canSeek = false; 
     120                        _delayedSeek = 0; 
     121                        _duration = 0; 
     122                        _video.src = videoURL; 
     123                        _video.load(); 
     124                         
     125                        _bufferInterval = setInterval(_sendBufferUpdate, 100); 
     126                        // _video.pause(); 
     127                } 
     128 
     129                var _stop = this.stop = function() { 
     130                        // _video.src = ""; 
     131                        _video.removeAttribute("src"); 
     132                        _video.load(); 
     133                        _video.style.opacity = 0; 
     134                        clearInterval(_bufferInterval); 
     135                        _setState(jwplayer.events.state.IDLE); 
     136                } 
     137 
     138                this.play = function() { 
     139                        _video.style.opacity = 1; 
     140                        _video.play(); 
     141                } 
     142 
     143                this.pause = function() { 
     144                        _video.pause(); 
     145                } 
     146 
     147                var _seek = this.seek = function(pos) { 
     148                        if (_canSeek) { 
     149                                _delayedSeek = 0; 
     150                                // _video.play(); 
     151                                _video.currentTime = pos; 
     152                        } else { 
     153                                _delayedSeek = pos; 
     154                        } 
     155                } 
     156 
     157                var _volume = this.volume = function(vol) { 
     158                        if (_video.muted) _video.muted = false; 
     159                        _video.volume = vol / 100; 
     160 
     161                } 
     162                 
     163                function _volumeHandler(evt) { 
     164                        _sendEvent(jwplayer.events.JWPLAYER_MEDIA_VOLUME, { 
     165                                volume: Math.round(_video.volume * 100) 
     166                        }); 
     167                        _sendEvent(jwplayer.events.JWPLAYER_MEDIA_MUTE, { 
     168                                mute: _video.muted 
     169                        }); 
     170                } 
     171                 
     172                this.mute = function(state) { 
     173                        if (!_utils.exists(state)) state = !_video.mute; 
     174                        if (state) { 
     175                                _lastVolume = _video.volume * 100; 
     176                                _volume(0); 
     177                                _video.muted = true; 
     178                        } else { 
     179                                _volume(_lastVolume); 
     180                        } 
     181                } 
     182 
     183                /** Set the current player state * */ 
     184                function _setState(newstate) { 
     185                        // Handles a FF 3.5 issue 
     186                        if (newstate == jwplayer.events.state.PAUSED && _state == jwplayer.events.state.IDLE) { 
     187                                return; 
     188                        } 
     189 
     190                        if (_state != newstate) { 
     191                                var oldstate = _state; 
     192                                _state = newstate; 
     193                                _sendEvent(jwplayer.events.JWPLAYER_PLAYER_STATE, { 
     194                                        oldstate : oldstate, 
     195                                        newstate : newstate 
     196                                }); 
     197                        } 
     198                } 
     199                 
     200                function _sendBufferUpdate() { 
     201                        var newBuffer = _getBuffer(); 
     202                        if (newBuffer != _bufferPercent) { 
     203                                _bufferPercent = newBuffer; 
     204                                _sendEvent(jwplayer.events.JWPLAYER_MEDIA_BUFFER, { 
     205                                        bufferPercent: Math.round(_bufferPercent * 100) 
     206                                }); 
     207                        } 
     208                        if (newBuffer >= 1) { 
     209                                clearInterval(_bufferInterval); 
     210                        } 
     211                } 
     212                 
     213                function _getBuffer() { 
     214                        if (_video.buffered.length == 0 || _video.duration == 0) 
     215                                return 0; 
     216                        else 
     217                                return _video.buffered.end(_video.buffered.length-1) / _video.duration; 
     218                } 
     219                 
     220 
     221                function _complete() { 
     222                        _stop(); 
     223                        _sendEvent(jwplayer.events.JWPLAYER_MEDIA_COMPLETE); 
     224                } 
     225                 
     226                // Provide access to video tag 
     227                // TODO: remove 
     228                this.getTag = function() { 
     229                        return videotag; 
     230                } 
     231 
     232                // Call constructor 
     233                _init(videotag); 
     234 
     235        } 
     236 
    136237})(jwplayer.html5); 
  • branches/jw6/src/js/utils/jwplayer.utils.js

    r2171 r2173  
    212212        } 
    213213 
    214  
     214        /** Format the elapsed / remaining text. **/ 
     215        utils.timeFormat = function(sec) { 
     216                if (sec > 0) { 
     217                        str = Math.floor(sec / 60) < 10 ? "0" + Math.floor(sec / 60) + ":" : Math.floor(sec / 60) + ":"; 
     218                        str += Math.floor(sec % 60) < 10 ? "0" + Math.floor(sec % 60) : Math.floor(sec % 60); 
     219                        return str; 
     220                } else { 
     221                        return "00:00"; 
     222                } 
     223        } 
     224 
     225        /** Logger * */ 
     226        jwplayer.utils.log = function(msg, obj) { 
     227                if (typeof console != "undefined" && typeof console.log != "undefined") { 
     228                        if (obj) { 
     229                                console.log(msg, obj); 
     230                        } else { 
     231                                console.log(msg); 
     232                        } 
     233                } 
     234        }; 
     235 
     236        /** Replacement for getBoundingClientRect, which isn't supported in iOS 3.1.2 **/ 
     237        jwplayer.utils.getBoundingClientRect = function(element) { 
     238                if (typeof element.getBoundingClientRect == "function") { 
     239                        return element.getBoundingClientRect(); 
     240                } else { 
     241                        return {  
     242                                left: element.offsetLeft + document.body.scrollLeft,  
     243                                top: element.offsetTop + document.body.scrollTop,  
     244                                width: element.offsetWidth,  
     245                                height: element.offsetHeight 
     246                        }; 
     247                } 
     248        } 
     249         
    215250})(jwplayer); 
Note: See TracChangeset for help on using the changeset viewer.