Easy Video Player - Version 1.1.7

Version Description

  • Updated the player to version 7.2.1.
  • Easy Video Player is now compatible with WordPress 4.9.
Download this release

Release Info

Developer naa986
Plugin Icon 128x128 Easy Video Player
Version 1.1.7
Comparing to
See all releases

Code changes from version 1.1.6 to 1.1.7

easy-video-player.php CHANGED
@@ -1,10 +1,10 @@
1
  <?php
2
  /*
3
  Plugin Name: Easy Video Player
4
- Version: 1.1.6
5
- Plugin URI: http://noorsplugin.com/wordpress-video-plugin/
6
  Author: naa986
7
- Author URI: http://noorsplugin.com/
8
  Description: Easily embed videos into your WordPress blog
9
  Text Domain: easy-video-player
10
  Domain Path: /languages
@@ -17,7 +17,8 @@ if (!class_exists('EASY_VIDEO_PLAYER')) {
17
 
18
  class EASY_VIDEO_PLAYER {
19
 
20
- var $plugin_version = '1.1.6';
 
21
 
22
  function __construct() {
23
  define('EASY_VIDEO_PLAYER_VERSION', $this->plugin_version);
@@ -69,7 +70,7 @@ if (!class_exists('EASY_VIDEO_PLAYER')) {
69
  }
70
 
71
  function easy_video_player_options_page() {
72
- $url = "http://noorsplugin.com/wordpress-video-plugin/";
73
  $link_text = sprintf(wp_kses(__('For detailed documentation please visit the plugin homepage <a target="_blank" href="%s">here</a>.', 'easy-video-player'), array('a' => array('href' => array(), 'target' => array()))), esc_url($url));
74
  ?>
75
  <div class="wrap">
1
  <?php
2
  /*
3
  Plugin Name: Easy Video Player
4
+ Version: 1.1.7
5
+ Plugin URI: https://noorsplugin.com/wordpress-video-plugin/
6
  Author: naa986
7
+ Author URI: https://noorsplugin.com/
8
  Description: Easily embed videos into your WordPress blog
9
  Text Domain: easy-video-player
10
  Domain Path: /languages
17
 
18
  class EASY_VIDEO_PLAYER {
19
 
20
+ var $plugin_version = '1.1.7';
21
+ var $flowplayer_version = '7.2.1';
22
 
23
  function __construct() {
24
  define('EASY_VIDEO_PLAYER_VERSION', $this->plugin_version);
70
  }
71
 
72
  function easy_video_player_options_page() {
73
+ $url = "https://noorsplugin.com/wordpress-video-plugin/";
74
  $link_text = sprintf(wp_kses(__('For detailed documentation please visit the plugin homepage <a target="_blank" href="%s">here</a>.', 'easy-video-player'), array('a' => array('href' => array(), 'target' => array()))), esc_url($url));
75
  ?>
76
  <div class="wrap">
lib/flowplayer.js CHANGED
@@ -1,6 +1,6 @@
1
  /*!
2
 
3
- Flowplayer v7.0.2 (Tuesday, 07. February 2017 10:39PM) | flowplayer.org/license
4
 
5
  */
6
  /*! (C) WebReflection Mit Style License */
@@ -74,7 +74,7 @@ common.createElement = function(tag, attributes, innerHTML) {
74
  common.attr(el, key, attributes[key]);
75
  }
76
  }
77
- el.innerHTML = innerHTML || '';
78
  return el;
79
  } catch (e) {
80
  if (!$) throw e;
@@ -298,7 +298,7 @@ common.matches = function(elem, selector) {
298
 
299
  })(window.CSSStyleDeclaration.prototype);
300
 
301
- },{"class-list":33,"computed-style":34,"punycode":41}],2:[function(_dereq_,module,exports){
302
  'use strict';
303
  var common = _dereq_('../common');
304
 
@@ -723,412 +723,573 @@ function isAbsolute(url) {
723
  return /^https?:/.test(url);
724
  }
725
 
726
- },{"../common":1,"../flowplayer":28,"./embed":2,"bean":31,"extend-object":36}],4:[function(_dereq_,module,exports){
727
  'use strict';
728
- var flowplayer = _dereq_('../flowplayer'),
729
- bean = _dereq_('bean'),
730
- extend = _dereq_('extend-object'),
731
- common = _dereq_('../common');
732
- var VIDEO = document.createElement('video');
733
-
734
- // HTML5 --> Flowplayer event
735
- var EVENTS = {
736
 
737
- // fired
738
- ended: 'finish',
739
- pause: 'pause',
740
- play: 'resume',
741
- //progress: 'buffer',
742
- timeupdate: 'progress',
743
- volumechange: 'volume',
744
- ratechange: 'speed',
745
- //seeking: 'beforeseek',
746
- seeked: 'seek',
747
- // abort: 'resume',
748
-
749
- // not fired
750
- loadeddata: 'ready',
751
- // loadedmetadata: 0,
752
- // canplay: 0,
753
-
754
- // error events
755
- // load: 0,
756
- // emptied: 0,
757
- // empty: 0,
758
- error: 'error',
759
- dataunavailable: 'error',
760
- webkitendfullscreen: !flowplayer.support.inlineVideo && 'unload'
761
 
762
- };
763
-
764
- function round(val, per) {
765
- per = per || 100;
766
- return Math.round(val * per) / per;
767
- }
768
-
769
- function getType(type) {
770
- return /mpegurl/i.test(type) ? "application/x-mpegurl" : type;
771
- }
772
 
773
  function canPlay(type) {
774
- if (!/^(video|application)/i.test(type))
775
- type = getType(type);
776
- return !!VIDEO.canPlayType(type).replace("no", '');
777
  }
778
 
779
- function findFromSourcesByType(sources, type) {
780
- var arr = sources.filter(function(s) {
781
- return s.type === type;
782
- });
783
- return arr.length ? arr[0] : null;
784
- }
785
-
786
- var videoTagCache;
787
- var createVideoTag = function(video, autoplay, preload, useCache) {
788
- if (typeof autoplay === 'undefined') autoplay = true;
789
- if (typeof preload === 'undefined') preload = 'none';
790
- if (typeof useCache === 'undefined') useCache = true;
791
- if (useCache && videoTagCache) {
792
- videoTagCache.type = getType(video.type);
793
- videoTagCache.src = video.src;
794
- common.find('track', videoTagCache).forEach(common.removeNode);
795
- videoTagCache.removeAttribute('crossorigin');
796
- return videoTagCache;
797
- }
798
- var el = document.createElement('video');
799
- el.src = video.src;
800
- el.type = getType(video.type);
801
- el.className = 'fp-engine';
802
- if (flowplayer.support.autoplay) el.autoplay = autoplay ? 'autoplay' : false;
803
- if (flowplayer.support.dataload) el.preload = preload;
804
- el.setAttribute('webkit-playsinline', 'true');
805
- el.setAttribute('playsinline', 'true');
806
- if (useCache) videoTagCache = el;
807
- return el;
808
- };
809
-
810
  var engine;
811
 
812
  engine = function(player, root) {
813
 
814
- var api = common.findDirect('video', root)[0] || common.find('.fp-player > video', root)[0],
815
- support = flowplayer.support,
816
- conf = player.conf,
817
- self,
818
- timer,
819
- lastBuffer,
820
- volumeLevel;
821
- /*jshint -W093 */
822
- return self = {
823
- engineName: engine.engineName,
824
 
825
- pick: function(sources) {
826
- var source = (function() {
827
- if (support.video) {
828
- if (conf.videoTypePreference) {
829
- var mp4source = findFromSourcesByType(sources, conf.videoTypePreference);
830
- if (mp4source) return mp4source;
831
- }
832
 
833
- for (var i = 0; i < sources.length; i++) {
834
- if (canPlay(sources[i].type)) return sources[i];
835
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
836
  }
837
- })();
838
- if (!source) return;
839
- if (typeof source.src === 'string') source.src = common.createAbsoluteUrl(source.src);
840
- return source;
841
- },
842
 
843
- load: function(video) {
844
- var container = common.find('.fp-player', root)[0], reload = false, created = false;
845
- if (conf.splash && !api) {
846
- api = createVideoTag(video);
847
- common.prepend(container, api);
848
- created = true;
849
- } else if (!api) {
850
- api = createVideoTag(video, !!video.autoplay || !!conf.autoplay, conf.clip.preload || true, false);
851
- common.prepend(container, api);
852
- created = true;
853
- } else {
854
- common.addClass(api, 'fp-engine');
855
- common.find('source,track', api).forEach(common.removeNode);
856
- if (!player.conf.nativesubtitles) common.attr(api, 'crossorigin', false);
857
- reload = api.src === video.src;
858
- }
859
- if (!support.inlineVideo) {
860
- common.css(api, {
861
- position: 'absolute',
862
- top: '-9999em'
863
- });
864
- }
865
- //TODO subtitles support
866
 
867
- // IE does not fire delegated timeupdate events
868
- bean.off(api, 'timeupdate', common.noop);
869
- bean.on(api, 'timeupdate', common.noop);
 
 
 
 
870
 
871
- common.prop(api, 'loop', false);
872
- player.off('.loophack');
873
- if (video.loop || conf.loop) {
874
- if (/mpegurl/i.test(video.type)) {
875
- player.on('finish.loophack', function() { player.resume(); });
876
- }
877
- else common.prop(api, 'loop', true);
878
- }
879
 
880
- if (typeof volumeLevel !== 'undefined') {
881
- api.volume = volumeLevel;
882
- }
 
 
883
 
884
- if (player.video.src && video.src != player.video.src || video.index) common.attr(api, 'autoplay', 'autoplay');
885
- api.src = video.src;
886
- api.type = video.type;
 
 
887
 
888
- self._listeners = listen(api, common.find("source", api).concat(api), video) || self._listeners;
889
 
890
- if (reload || (created && !conf.splash)) api.load();
891
- if (support.iOS.iPad && support.iOS.chrome) api.load();
892
- if (api.paused && (video.autoplay || conf.autoplay || conf.splash)) api.play();
893
- },
894
 
895
- pause: function() {
896
- api.pause();
897
- },
898
 
899
- resume: function() {
900
- api.play();
901
- },
902
 
903
- speed: function(val) {
904
- api.playbackRate = val;
905
- },
906
 
907
- seek: function(time) {
908
- try {
909
- var pausedState = player.paused;
910
- api.currentTime = time;
911
- if (pausedState) api.pause();
912
- } catch (ignored) {}
913
- },
914
 
915
- volume: function(level) {
916
- volumeLevel = level;
917
- if (api) {
918
- api.volume = level;
919
- }
920
- },
921
 
922
- unload: function() {
923
- common.find('video.fp-engine', root).forEach(function (videoTag) {
924
- common.attr(videoTag, 'src', '');
925
- common.removeNode(videoTag);
926
- });
927
- if (!support.cachedVideoTag) videoTagCache = null;
928
- timer = clearInterval(timer);
929
- var instanceId = root.getAttribute('data-flowplayer-instance-id');
930
- delete api.listeners[instanceId];
931
- api = 0;
932
- if (self._listeners) Object.keys(self._listeners).forEach(function(typ) {
933
- self._listeners[typ].forEach(function(l) {
934
- root.removeEventListener(typ, l, true);
935
- });
936
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
937
  }
 
 
 
938
 
939
- };
940
 
941
- function listen(api, sources, video) {
942
- // listen only once
943
- var instanceId = root.getAttribute('data-flowplayer-instance-id');
 
944
 
945
- if (api.listeners && api.listeners.hasOwnProperty(instanceId)) {
946
- api.listeners[instanceId] = video;
947
- return;
 
 
948
  }
949
- (api.listeners || (api.listeners = {}))[instanceId] = video;
950
 
951
- bean.on(sources, 'error', function(e) {
952
- try {
953
- if (canPlay(e.target.getAttribute('type'))) {
954
- player.trigger("error", [player, { code: 4, video: extend(video, {src: api.src, url: api.src}) }]);
955
- }
956
- } catch (er) {
957
- // Most likely: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
958
- }
959
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
960
 
961
- player.on('shutdown', function() {
962
- bean.off(sources);
963
- bean.off(api, '.dvrhack');
964
- player.off('.loophack');
965
- });
966
 
967
- var eventListeners = {};
968
- //Special event handling for HLS metadata events
 
 
 
969
 
970
- var listenMetadata = function(track) {
971
- if (track.kind !== 'metadata') return;
972
- track.mode = 'hidden';
973
- track.addEventListener('cuechange', function() {
974
- player.trigger('metadata', [player, track.activeCues[0].value]);
975
- }, false);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
976
  };
 
 
 
 
 
 
977
 
978
- if (api && api.textTracks.length) Array.prototype.forEach.call(api.textTracks, listenMetadata);
979
- if (typeof api.textTracks.addEventListener === 'function') api.textTracks.addEventListener('addtrack', function(tev) {
980
- listenMetadata(tev.track);
981
- }, false);
982
- if (player.conf.dvr || player.dvr || video.dvr) {
983
- bean.on(api, 'progress.dvrhack', function() {
984
- if (!api.seekable.length) return;
985
- player.video.duration = api.seekable.end(null);
986
- player.video.seekOffset = api.seekable.start(null);
987
- player.trigger('dvrwindow', [player, {
988
- start: api.seekable.start(null),
989
- end: api.seekable.end(null)
990
- }]);
991
- if (api.currentTime >= api.seekable.start(null)) return;
992
- api.currentTime = api.seekable.start(null);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
993
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
994
  }
 
995
 
996
- Object.keys(EVENTS).forEach(function(type) {
997
- var flow = EVENTS[type];
998
- if (!flow) return;
999
- var l = function(e) {
1000
- video = api.listeners[instanceId];
1001
- if (!e.target || !common.hasClass(e.target, 'fp-engine')) return;
1002
 
1003
- if (conf.debug && !/progress/.test(flow)) console.log(type, "->", flow, e);
 
1004
 
1005
- var triggerEvent = function() {
1006
- player.trigger(flow, [player, arg]);
1007
- };
 
 
 
 
1008
 
1009
- // no events if player not ready
1010
- if (!player.ready && !/ready|error/.test(flow) || !flow || !common.find('video', root).length) {
1011
- if (flow === 'resume') player.one('ready', function() { setTimeout(function() { triggerEvent(); }) });
1012
- return;
1013
- }
1014
- var arg;
 
 
 
 
 
 
 
 
 
 
 
1015
 
1016
- if (flow === 'unload') { //Call player unload
1017
- player.unload();
1018
- return;
1019
- }
 
 
 
1020
 
1021
- switch (flow) {
1022
 
1023
- case "ready":
 
 
1024
 
1025
- arg = extend(video, {
1026
- duration: api.duration < Number.MAX_VALUE ? api.duration : 0,
1027
- width: api.videoWidth,
1028
- height: api.videoHeight,
1029
- url: api.currentSrc,
1030
- src: api.currentSrc
1031
- });
1032
 
1033
- try {
1034
- arg.seekable = /mpegurl/i.test(video ? (video.type || '') : '') && api.duration || api.seekable && api.seekable.end(null) || player.live;
 
 
1035
 
1036
- } catch (ignored) {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1037
 
1038
- // buffer
1039
- timer = timer || setInterval(function() {
1040
 
1041
- try {
1042
- arg.buffer = api.buffered.end(null);
1043
 
1044
- } catch (ignored) {}
 
1045
 
1046
- if (arg.buffer) {
1047
- if (round(arg.buffer, 1000) < round(arg.duration, 1000) && !arg.buffered && arg.buffer !== lastBuffer) {
1048
- player.trigger("buffer", [player, arg.buffer]);
1049
- lastBuffer = arg.buffer;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1050
 
1051
- } else if (!arg.buffered && arg.buffer !== lastBuffer) {
1052
- arg.buffered = true;
1053
- player.trigger("buffer", [player, arg.buffer]).trigger("buffered", e);
1054
- lastBuffer = arg.buffer;
1055
- clearInterval(timer);
1056
- timer = 0;
1057
- }
1058
- }
1059
 
1060
- }, 250);
1061
-
1062
- if (!player.live && !arg.duration && !support.hlsDuration && type === "loadeddata") {
1063
- var durationChanged = function() {
1064
- arg.duration = api.duration;
1065
- try {
1066
- arg.seekable = api.seekable && api.seekable.end(null);
1067
-
1068
- } catch (ignored) {}
1069
- triggerEvent();
1070
- api.removeEventListener('durationchange', durationChanged);
1071
- common.toggleClass(root, 'is-live', false);
1072
- };
1073
- api.addEventListener('durationchange', durationChanged);
1074
-
1075
- // Ugly hack to handle broken Android devices
1076
- var timeUpdated = function() {
1077
- if (!player.ready && !api.duration) { // No duration even though the video already plays
1078
- arg.duration = 0;
1079
- common.addClass(root, 'is-live'); // Make UI believe it's live
1080
- triggerEvent();
1081
- }
1082
- api.removeEventListener('timeupdate', timeUpdated);
1083
- };
1084
- api.addEventListener('timeupdate', timeUpdated);
1085
- return;
1086
- }
1087
 
1088
- break;
 
 
 
1089
 
1090
- case "progress": case "seek":
 
1091
 
1092
- if (api.currentTime > 0 || player.live) {
1093
- arg = Math.max(api.currentTime, 0);
1094
 
1095
- } else if (flow == 'progress') {
1096
- return;
1097
- }
1098
- break;
1099
 
 
1100
 
1101
- case "speed":
1102
- arg = round(api.playbackRate);
1103
- break;
 
1104
 
1105
- case "volume":
1106
- arg = round(api.volume);
1107
- break;
1108
 
1109
- case "error":
1110
- try {
1111
- arg = (e.srcElement || e.originalTarget).error;
1112
- arg.video = extend(video, {src: api.src, url: api.src});
1113
- } catch (er) {
1114
- // Most likely https://bugzilla.mozilla.org/show_bug.cgi?id=208427
1115
- return;
1116
- }
1117
- }
1118
 
1119
- triggerEvent();
 
 
 
 
1120
 
 
1121
 
1122
- };
1123
- root.addEventListener(type, l, true);
1124
- if (!eventListeners[type]) eventListeners[type] = [];
1125
- eventListeners[type].push(l);
1126
 
1127
- });
1128
- return eventListeners;
 
 
 
1129
 
1130
- }
 
 
1131
 
 
 
 
 
 
 
 
1132
  };
1133
 
1134
 
@@ -1140,7 +1301,7 @@ engine.engineName = 'html5';
1140
 
1141
  flowplayer.engines.push(engine);
1142
 
1143
- },{"../common":1,"../flowplayer":28,"bean":31,"extend-object":36}],5:[function(_dereq_,module,exports){
1144
  'use strict';
1145
  var flowplayer = _dereq_('../flowplayer')
1146
  , common = _dereq_('../common')
@@ -1179,7 +1340,7 @@ flowplayer(function(api, root) {
1179
 
1180
  });
1181
 
1182
- },{"../common":1,"../flowplayer":28,"bean":31}],6:[function(_dereq_,module,exports){
1183
  'use strict';
1184
  /* global _gat */
1185
  var flowplayer = _dereq_('../flowplayer'),
@@ -1254,7 +1415,7 @@ flowplayer(function(player, root) {
1254
 
1255
  });
1256
 
1257
- },{"../flowplayer":28,"./resolve":19,"bean":31,"scriptjs":42}],7:[function(_dereq_,module,exports){
1258
  /* global chrome */
1259
  /* eslint-disable no-console */
1260
 
@@ -1267,6 +1428,7 @@ var flowplayer = _dereq_('../flowplayer')
1267
 
1268
 
1269
  flowplayer(function(api, root) {
 
1270
  scriptjs('https://www.gstatic.com/cv/js/sender/v1/cast_sender.js');
1271
  window['__onGCastApiAvailable'] = function(loaded) {
1272
  if (!loaded) return;
@@ -1388,7 +1550,7 @@ flowplayer(function(api, root) {
1388
 
1389
  });
1390
 
1391
- },{"../common":1,"../flowplayer":28,"bean":31,"scriptjs":42}],8:[function(_dereq_,module,exports){
1392
  'use strict';
1393
  var flowplayer = _dereq_('../flowplayer'),
1394
  common = _dereq_('../common'),
@@ -1508,7 +1670,7 @@ flowplayer(function(player, root) {
1508
 
1509
  });
1510
 
1511
- },{"../common":1,"../flowplayer":28,"bean":31}],9:[function(_dereq_,module,exports){
1512
  'use strict';
1513
  var flowplayer = _dereq_('../flowplayer'),
1514
  bean = _dereq_('bean'),
@@ -1554,7 +1716,7 @@ flowplayer(function(player, root) {
1554
 
1555
  });
1556
 
1557
- },{"../common":1,"../flowplayer":28,"./util/clipboard":27,"bean":31}],10:[function(_dereq_,module,exports){
1558
  'use strict';
1559
  /**
1560
  * Mimimal jQuery-like event emitter implementation
@@ -1662,7 +1824,7 @@ module.exports.EVENTS = [
1662
  'shutdown'
1663
  ];
1664
 
1665
- },{}],11:[function(_dereq_,module,exports){
1666
  'use strict';
1667
 
1668
  var flowplayer = _dereq_('../flowplayer')
@@ -1705,7 +1867,7 @@ flowplayer(function(api, root) {
1705
  });
1706
  });
1707
 
1708
- },{"../common":1,"../flowplayer":28,"bean":31}],12:[function(_dereq_,module,exports){
1709
  'use strict';
1710
  var flowplayer = _dereq_('../flowplayer'),
1711
  bean = _dereq_('bean'),
@@ -1724,7 +1886,7 @@ bean.on(document, "fullscreenchange.ffscr webkitfullscreenchange.ffscr mozfullsc
1724
  if (!FULL_PLAYER && (!el.parentNode || !el.parentNode.getAttribute('data-flowplayer-instance-id'))) return;
1725
  var player = FULL_PLAYER || flowplayer(el.parentNode);
1726
  if (el && !FULL_PLAYER) {
1727
- FULL_PLAYER = player.trigger(FS_ENTER, [el]);
1728
  } else {
1729
  FULL_PLAYER.trigger(FS_EXIT, [FULL_PLAYER]);
1730
  FULL_PLAYER = null;
@@ -1764,11 +1926,7 @@ flowplayer(function(player, root) {
1764
  if (flag) {
1765
  ['requestFullScreen', 'webkitRequestFullScreen', 'mozRequestFullScreen', 'msRequestFullscreen'].forEach(function(fName) {
1766
  if (typeof wrapper[fName] === 'function') {
1767
- wrapper[fName](Element.ALLOW_KEYBOARD_INPUT);
1768
- if (IS_SAFARI && !document.webkitCurrentFullScreenElement && !document.mozFullScreenElement) { // Element.ALLOW_KEYBOARD_INPUT not allowed
1769
- wrapper[fName]();
1770
- }
1771
- return false;
1772
  }
1773
  });
1774
 
@@ -1776,7 +1934,6 @@ flowplayer(function(player, root) {
1776
  ['exitFullscreen', 'webkitCancelFullScreen', 'mozCancelFullScreen', 'msExitFullscreen'].forEach(function(fName) {
1777
  if (typeof document[fName] === 'function') {
1778
  document[fName]();
1779
- return false;
1780
  }
1781
  });
1782
  }
@@ -1827,7 +1984,7 @@ flowplayer(function(player, root) {
1827
 
1828
  });
1829
 
1830
- },{"../common":1,"../flowplayer":28,"bean":31}],13:[function(_dereq_,module,exports){
1831
  'use strict';
1832
  var flowplayer = _dereq_('../flowplayer'),
1833
  bean = _dereq_('bean'),
@@ -1899,33 +2056,6 @@ flowplayer(function(api, root) {
1899
  if (focused) focusedRoot = root;
1900
  });
1901
 
1902
- var speedhelp = flowplayer.support.video && api.conf.engine !== "flash" &&
1903
- !!document.createElement('video').playbackRate ?
1904
- '<p><em>shift</em> + <em>&#8592;</em><em>&#8594;</em>slower / faster</p>' : '';
1905
-
1906
- // TODO: add to player-layout.html
1907
- root.appendChild(common.createElement('div', { className: 'fp-help' }, '\
1908
- <a class="fp-close"></a>\
1909
- <div class="fp-help-section fp-help-basics">\
1910
- <p><em>space</em>play / pause</p>\
1911
- <p><em>q</em>unload | stop</p>\
1912
- <p><em>f</em>fullscreen</p>' + speedhelp + '\
1913
- </div>\
1914
- <div class="fp-help-section">\
1915
- <p><em>&#8593;</em><em>&#8595;</em>volume</p>\
1916
- <p><em>m</em>mute</p>\
1917
- </div>\
1918
- <div class="fp-help-section">\
1919
- <p><em>&#8592;</em><em>&#8594;</em>seek</p>\
1920
- <p><em>&nbsp;. </em>seek to previous\
1921
- </p><p><em>1</em><em>2</em>&hellip; <em>6</em> seek to 10%, 20% &hellip; 60% </p>\
1922
- </div>\
1923
- '));
1924
-
1925
- bean.on(root, 'click', '.fp-close', function() {
1926
- common.toggleClass(root, IS_HELP);
1927
- });
1928
-
1929
  api.bind('shutdown', function() {
1930
  if (focusedRoot == root) focusedRoot = null;
1931
  });
@@ -1933,7 +2063,7 @@ flowplayer(function(api, root) {
1933
  });
1934
 
1935
 
1936
- },{"../common":1,"../flowplayer":28,"bean":31}],14:[function(_dereq_,module,exports){
1937
  var flowplayer = _dereq_('../flowplayer')
1938
  , common = _dereq_('../common')
1939
  , bean = _dereq_('bean');
@@ -1955,7 +2085,7 @@ flowplayer(function(api, root) {
1955
  top: common.offset(triggerElement).top + common.height(triggerElement)
1956
  };
1957
  }
1958
- if (!coordinates) return;
1959
  coordinates.rightFallbackOffset = coordinates.rightFallbackOffset || 0;
1960
  var top = coordinates.top - common.offset(ui).top
1961
  , left = coordinates.left - common.offset(ui).left
@@ -1969,10 +2099,13 @@ flowplayer(function(api, root) {
1969
 
1970
  api.hideMenu = function(menu) {
1971
  common.toggleClass(menu, 'fp-active', false);
 
 
 
1972
  };
1973
  });
1974
 
1975
- },{"../common":1,"../flowplayer":28,"bean":31}],15:[function(_dereq_,module,exports){
1976
  var flowplayer = _dereq_('../flowplayer')
1977
  , common = _dereq_('../common')
1978
  , bean = _dereq_('bean');
@@ -2019,27 +2152,30 @@ flowplayer(function(api, root) {
2019
  }
2020
  });
2021
 
2022
- },{"../common":1,"../flowplayer":28,"bean":31}],16:[function(_dereq_,module,exports){
2023
  'use strict';
2024
  var flowplayer = _dereq_('../flowplayer'),
2025
  isIeMobile = /IEMobile/.test(window.navigator.userAgent),
2026
  common = _dereq_('../common'),
2027
  bean = _dereq_('bean'),
2028
  format = _dereq_('./ui').format,
 
2029
  UA = window.navigator.userAgent;
2030
- if (flowplayer.support.touch || isIeMobile) {
2031
 
2032
  flowplayer(function(player, root) {
2033
- var isAndroid = /Android/.test(UA) && !/Firefox/.test(UA) && !/Opera/.test(UA),
 
2034
  isSilk = /Silk/.test(UA),
2035
- androidVer = isAndroid ? parseFloat(/Android\ (\d\.\d)/.exec(UA)[1], 10) : 0;
2036
 
2037
  // custom load for android
2038
  if (isAndroid && !isIeMobile) {
2039
- if (!/Chrome/.test(UA) && androidVer < 4) {
2040
  var originalLoad = player.load;
2041
  player.load = function() {
2042
  var ret = originalLoad.apply(player, arguments);
 
2043
  player.trigger('ready', [player, player.video]);
2044
  return ret;
2045
  };
@@ -2051,16 +2187,16 @@ if (flowplayer.support.touch || isIeMobile) {
2051
  api.trigger('progress', [api, currentTime]);
2052
  }, 1000);
2053
  };
2054
- player.bind('ready pause unload', function() {
2055
  if (timer) {
2056
  clearInterval(timer);
2057
  timer = null;
2058
  }
2059
  });
2060
- player.bind('ready', function() {
2061
  currentTime = 0;
2062
  });
2063
- player.bind('resume', function(ev, api) {
2064
  if (!api.live) return;
2065
  if (currentTime) { return resumeTimer(api); }
2066
  player.one('progress', function(ev, api, t) {
@@ -2072,14 +2208,16 @@ if (flowplayer.support.touch || isIeMobile) {
2072
  }
2073
 
2074
  // hide volume
2075
- if (!flowplayer.support.volume) {
 
2076
  common.addClass(root, 'no-volume');
2077
  }
 
 
 
2078
  common.addClass(root, 'is-touch');
2079
  if (player.sliders && player.sliders.timeline) player.sliders.timeline.disableAnimation();
2080
 
2081
- if (!flowplayer.support.inlineVideo || player.conf.native_fullscreen) player.conf.nativesubtitles = true;
2082
-
2083
  // fake mouseover effect with click
2084
  var hasMoved = false;
2085
  bean.on(root, 'touchmove', function() {
@@ -2091,6 +2229,9 @@ if (flowplayer.support.touch || isIeMobile) {
2091
  return;
2092
  }
2093
 
 
 
 
2094
  if (player.playing && !common.hasClass(root, 'is-mouseover')) {
2095
  common.addClass(root, 'is-mouseover');
2096
  common.removeClass(root, 'is-mouseout');
@@ -2102,7 +2243,7 @@ if (flowplayer.support.touch || isIeMobile) {
2102
  if (!player.playing && !player.splash && common.hasClass(root, 'is-mouseout') && !common.hasClass(root, 'is-mouseover')) {
2103
  setTimeout(function() {
2104
  if (!player.disabled && !player.playing && !player.splash) {
2105
- player.resume();
2106
  }
2107
  }, 400);
2108
  }
@@ -2111,7 +2252,7 @@ if (flowplayer.support.touch || isIeMobile) {
2111
  });
2112
 
2113
  // native fullscreen
2114
- if (!flowplayer.support.fullscreen && player.conf.native_fullscreen && typeof document.createElement('video').webkitEnterFullScreen === 'function') {
2115
  var oldFullscreen = player.fullscreen;
2116
  player.fullscreen = function() {
2117
  var video = common.find('video.fp-engine', root)[0];
@@ -2139,12 +2280,13 @@ if (flowplayer.support.touch || isIeMobile) {
2139
 
2140
  // Android browser gives video.duration == 1 until second 'timeupdate' event
2141
  if (isAndroid || isSilk) player.bind("ready", function() {
2142
-
2143
  var video = common.find('video.fp-engine', root)[0];
2144
- bean.one(video, 'canplay', function() {
2145
- video.play();
2146
- });
2147
- video.play();
 
 
2148
 
2149
  player.bind("progress.dur", function() {
2150
  if (player.live || player.conf.live) return;
@@ -2164,7 +2306,7 @@ if (flowplayer.support.touch || isIeMobile) {
2164
  }
2165
 
2166
 
2167
- },{"../common":1,"../flowplayer":28,"./ui":24,"bean":31}],17:[function(_dereq_,module,exports){
2168
  'use strict';
2169
  var flowplayer = _dereq_('../flowplayer'),
2170
  extend = _dereq_('extend-object'),
@@ -2204,8 +2346,8 @@ flowplayer(function(player, root) {
2204
  if (typeof i === 'number' && !player.conf.playlist[i]) return player;
2205
  else if (typeof i != 'number') return player.load.apply(null, arguments);
2206
  var arg = extend({index: i}, player.conf.playlist[i]);
2207
- if (i === player.video.index) return player.load(arg, function() { player.resume(); });
2208
  player.off('beforeresume.fromfirst'); // Don't start from beginning if clip explicitely chosen
 
2209
  player.load(arg, function() {
2210
  player.video.index = i;
2211
  });
@@ -2232,15 +2374,16 @@ flowplayer(function(player, root) {
2232
  return player;
2233
  };
2234
 
2235
- player.setPlaylist = function(items) {
2236
  player.conf.playlist = items;
2237
- delete player.video.index;
2238
  generatePlaylist();
2239
  return player;
2240
  };
2241
 
2242
  player.addPlaylistItem = function(item) {
2243
- return player.setPlaylist(player.conf.playlist.concat([item]));
 
2244
  };
2245
 
2246
  player.removePlaylistItem = function(idx) {
@@ -2251,33 +2394,33 @@ flowplayer(function(player, root) {
2251
  bean.on(root, 'click', '.fp-next', player.next);
2252
  bean.on(root, 'click', '.fp-prev', player.prev);
2253
 
2254
- if (conf.advance) {
2255
- player.off("finish.pl").on("finish.pl", function(e, player) {
2256
- // clip looping
2257
- if (player.video.loop) return player.seek(0, function() { player.resume(); });
2258
- // next clip is found or loop
2259
- var next = player.video.index >= 0 ? player.video.index + 1 : undefined;
2260
- if (next < player.conf.playlist.length || conf.loop) {
2261
- next = next === player.conf.playlist.length ? 0 : next;
2262
- common.removeClass(root, 'is-finished');
2263
- setTimeout(function() { // Let other finish callbacks fire first
2264
- player.play(next);
2265
- });
 
2266
 
2267
- // stop to last clip, play button starts from 1:st clip
2268
- } else {
2269
 
2270
- // If we have multiple items in playlist, start from first
2271
- if (player.conf.playlist.length > 1) {
2272
- player.one("beforeresume.fromfirst", function(ev) {
2273
- ev.preventDefault();
2274
- player.play(0);
2275
- });
2276
- player.one('seek', function() { player.off('beforeresume.fromfirst'); });
2277
- }
2278
  }
2279
- });
2280
- }
2281
 
2282
  function generatePlaylist() {
2283
  var plEl = common.find('.fp-playlist', root)[0]
@@ -2315,6 +2458,7 @@ flowplayer(function(player, root) {
2315
  var href = item.sources[0].src;
2316
  plEl.appendChild(common.createElement('a', {
2317
  href: href,
 
2318
  'data-index': i
2319
  }));
2320
  });
@@ -2400,7 +2544,7 @@ flowplayer(function(player, root) {
2400
 
2401
  });
2402
 
2403
- },{"../common":1,"../flowplayer":28,"./resolve":19,"bean":31,"extend-object":36}],18:[function(_dereq_,module,exports){
2404
  var flowplayer = _dereq_('../flowplayer')
2405
  , common = _dereq_('../common')
2406
  , bean = _dereq_('bean');
@@ -2465,7 +2609,7 @@ flowplayer(function(api, root) {
2465
 
2466
  });
2467
 
2468
- },{"../common":1,"../flowplayer":28,"bean":31}],19:[function(_dereq_,module,exports){
2469
  'use strict';
2470
  var TYPE_RE = /\.(\w{3,4})(\?.*)?$/i,
2471
  extend = _dereq_('extend-object');
@@ -2532,7 +2676,7 @@ module.exports = function URLResolver() {
2532
 
2533
  module.exports.TYPE_RE = TYPE_RE;
2534
 
2535
- },{"extend-object":36}],20:[function(_dereq_,module,exports){
2536
  'use strict';
2537
 
2538
  var flowplayer = _dereq_('../flowplayer')
@@ -2551,9 +2695,11 @@ flowplayer(function(api, root) {
2551
  if (directEmbed && c.embed && c.embed.iframe) return c.embed.iframe;
2552
  if (typeof api.conf.share === 'string') return api.conf.share;
2553
  var title = encodeURIComponent(api.video.title || (common.find('title')[0] || {}).innerHTML || 'Flowplayer video')
2554
- , conf = encodeURIComponent(btoa(JSON.stringify(extend({}, api.conf, api.extensions))))
 
 
2555
  , redirect = encodeURIComponent(window.location.toString())
2556
- , baseUrl = directEmbed ? 'https://flowplayer.org/e/' : 'https://flowplayer.org/s/';
2557
  return baseUrl + '?t=' + title + '&c=' + conf + '&r=' + redirect;
2558
  };
2559
 
@@ -2570,54 +2716,27 @@ flowplayer(function(api, root) {
2570
  });
2571
  });
2572
 
2573
- },{"../common":1,"../flowplayer":28,"bean":31,"extend-object":36}],21:[function(_dereq_,module,exports){
2574
  'use strict';
2575
  var flowplayer = _dereq_('../flowplayer'),
2576
  common = _dereq_('../common'),
2577
- bean = _dereq_('bean');
2578
-
2579
- flowplayer.defaults.subtitleParser = function(txt) {
2580
- var TIMECODE_RE = /^(([0-9]{2}:){1,2}[0-9]{2}[,.][0-9]{3}) --\> (([0-9]{2}:){1,2}[0-9]{2}[,.][0-9]{3})(.*)/;
2581
-
2582
- function seconds(timecode) {
2583
- var els = timecode.split(':');
2584
- if (els.length == 2) els.unshift(0);
2585
- return els[0] * 60 * 60 + els[1] * 60 + parseFloat(els[2].replace(',','.'));
2586
- }
2587
-
2588
- var entries = [];
2589
- for (var i = 0, lines = txt.split("\n"), len = lines.length, entry = {}, title, timecode, text; i < len; i++) {
2590
- timecode = TIMECODE_RE.exec(lines[i]);
2591
-
2592
- if (timecode) {
2593
-
2594
- // title
2595
- title = lines[i - 1];
2596
 
2597
- // text
2598
- text = "<p>" + lines[++i] + "</p><br/>";
2599
- while (typeof lines[++i] === 'string' && lines[i].trim() && i < lines.length) text += "<p>" + lines[i] + "</p><br/>";
2600
-
2601
- // entry
2602
- entry = {
2603
- title: title,
2604
- startTime: seconds(timecode[1]),
2605
- endTime: seconds(timecode[3]),
2606
- text: text
2607
- };
2608
- entries.push(entry);
2609
- }
2610
- }
2611
- return entries;
2612
- };
2613
 
2614
  flowplayer(function(p, root) {
2615
  var currentPoint, wrap,
2616
  subtitleControl, subtitleMenu;
2617
 
 
 
 
 
2618
  var createSubtitleControl = function() {
2619
- subtitleControl = common.createElement('strong', { className: 'fp-cc' }, 'CC');
2620
- subtitleMenu = common.createElement('div', {className: 'fp-menu fp-subtitle-menu'}, '<strong>Closed Captions</strong>');
 
2621
  subtitleMenu.appendChild(common.createElement('a', {'data-subtitle-index': -1}, 'No subtitles'));
2622
  (p.video.subtitles || []).forEach(function(st, i) {
2623
  var srcLang = st.srclang || 'en',
@@ -2631,8 +2750,8 @@ flowplayer(function(p, root) {
2631
  };
2632
 
2633
  bean.on(root, 'click', '.fp-cc', function() {
2634
- //TODO fix
2635
- common.toggleClass(subtitleMenu, 'fp-active');
2636
  });
2637
 
2638
  bean.on(root, 'click', '.fp-subtitle-menu [data-subtitle-index]', function(ev) {
@@ -2643,41 +2762,14 @@ flowplayer(function(p, root) {
2643
  });
2644
 
2645
  var createUIElements = function() {
2646
- wrap = common.find('.fp-subtitle', root)[0];
2647
  wrap = wrap || common.appendTo(common.createElement('div', {'class': 'fp-captions'}), common.find('.fp-player', root)[0]);
2648
  Array.prototype.forEach.call(wrap.children, common.removeNode);
2649
- common.find('.fp-subtitle-menu', root).forEach(common.removeNode);
2650
  createSubtitleControl();
2651
  };
2652
 
2653
 
2654
  p.on('ready', function(ev, player, video) {
2655
- var conf = player.conf;
2656
- if (flowplayer.support.subtitles && conf.nativesubtitles && player.engine.engineName == 'html5') {
2657
- var setMode = function(mode) {
2658
- var tracks = common.find('video', root)[0].textTracks;
2659
- if (!tracks.length) return;
2660
- tracks[0].mode = mode;
2661
- };
2662
- if (!video.subtitles || !video.subtitles.length) return;
2663
- var videoTag = common.find('video.fp-engine', root)[0];
2664
- if (video.subtitles.some(function(st) { return !common.isSameDomain(st.src); })) common.attr(videoTag, 'crossorigin', 'anonymous');
2665
- if (typeof videoTag.textTracks.addEventListener === 'function') videoTag.textTracks.addEventListener('addtrack', function() {
2666
- setMode('disabled');
2667
- setMode('showing');
2668
- });
2669
- video.subtitles.forEach(function(st) {
2670
- videoTag.appendChild(common.createElement('track', {
2671
- kind: 'subtitles',
2672
- srclang: st.srclang || 'en',
2673
- label: st.label || 'en',
2674
- src: st.src,
2675
- 'default': st['default']
2676
- }));
2677
- });
2678
- return;
2679
- }
2680
-
2681
  player.subtitles = [];
2682
 
2683
  createUIElements();
@@ -2712,22 +2804,37 @@ flowplayer(function(p, root) {
2712
  common.removeClass(wrap, 'fp-shown');
2713
  currentPoint = null;
2714
  }
2715
- (p.cuepoints || []).forEach(function(cue) {
2716
  var entry = cue.subtitle;
2717
  //Trigger cuepoint if start time before seek position and end time nonexistent or in the future
2718
- if (entry && currentPoint != cue.index) {
2719
  if (time >= cue.time && (!entry.endTime || time <= entry.endTime)) p.trigger("cuepoint", [p, cue]);
2720
  } // Also handle cuepoints that act as the removal trigger
2721
- else if (cue.subtitleEnd && time >= cue.time && cue.index == currentPoint + 1) p.trigger("cuepoint", [p, cue]);
 
 
2722
  });
2723
 
2724
  });
2725
 
 
 
 
 
2726
  var setActiveSubtitleClass = function(idx) {
2727
  common.toggleClass(common.find('a.fp-selected', subtitleMenu)[0], 'fp-selected');
2728
  common.toggleClass(common.find('a[data-subtitle-index="' + idx + '"]', subtitleMenu)[0], 'fp-selected');
2729
  };
2730
 
 
 
 
 
 
 
 
 
 
2731
  p.disableSubtitles = function() {
2732
  p.subtitles = [];
2733
  (p.cuepoints || []).forEach(function(c) {
@@ -2735,6 +2842,9 @@ flowplayer(function(p, root) {
2735
  });
2736
  if (wrap) Array.prototype.forEach.call(wrap.children, common.removeNode);
2737
  setActiveSubtitleClass(-1);
 
 
 
2738
  return p;
2739
  };
2740
 
@@ -2747,6 +2857,11 @@ flowplayer(function(p, root) {
2747
  var url = st.src;
2748
  if (!url) return;
2749
  setActiveSubtitleClass(i);
 
 
 
 
 
2750
  common.xhrGet(url, function(txt) {
2751
  var entries = p.conf.subtitleParser(txt);
2752
  entries.forEach(function(entry) {
@@ -2756,9 +2871,10 @@ flowplayer(function(p, root) {
2756
  p.addCuepoint({ time: entry.endTime, subtitleEnd: entry.title, visible: false });
2757
 
2758
  // initial cuepoint
2759
- if (entry.startTime === 0 && !p.video.time) {
2760
- p.trigger("cuepoint", [p, cue]);
2761
  }
 
2762
  });
2763
  }, function() {
2764
  p.trigger("error", {code: 8, url: url });
@@ -2769,7 +2885,43 @@ flowplayer(function(p, root) {
2769
  });
2770
 
2771
 
2772
- },{"../common":1,"../flowplayer":28,"bean":31}],22:[function(_dereq_,module,exports){
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2773
  'use strict';
2774
  /* global ActiveXObject */
2775
  var flowplayer = _dereq_('../flowplayer'),
@@ -2806,6 +2958,8 @@ var flowplayer = _dereq_('../flowplayer'),
2806
  b[match[1]] = true;
2807
  b.version = match[2] || "0";
2808
  }
 
 
2809
 
2810
  var video = createVideoTag(),
2811
  UA = navigator.userAgent,
@@ -2813,25 +2967,33 @@ var flowplayer = _dereq_('../flowplayer'),
2813
  IS_IPAD = /iPad|MeeGo/.test(UA) && !/CriOS/.test(UA),
2814
  IS_IPAD_CHROME = /iPad/.test(UA) && /CriOS/.test(UA),
2815
  IS_IPHONE = /iP(hone|od)/i.test(UA) && !/iPad/.test(UA) && !/IEMobile/i.test(UA),
2816
- IS_ANDROID = /Android/.test(UA) && !/Firefox/.test(UA),
2817
- IS_ANDROID_FIREFOX = /Android/.test(UA) && /Firefox/.test(UA),
 
2818
  IS_SILK = /Silk/.test(UA),
2819
  IS_WP = /IEMobile/.test(UA),
2820
  WP_VER = IS_WP ? parseFloat(/Windows\ Phone\ (\d+\.\d+)/.exec(UA)[1], 10) : 0,
2821
  IE_MOBILE_VER = IS_WP ? parseFloat(/IEMobile\/(\d+\.\d+)/.exec(UA)[1], 10) : 0,
2822
  IOS_VER = IS_IPAD || IS_IPHONE ? parseIOSVersion(UA) : 0,
2823
- ANDROID_VER = IS_ANDROID ? parseFloat(/Android\ (\d\.\d)/.exec(UA)[1], 10) : 0,
2824
- s = extend(flowplayer.support, {
2825
 
 
 
 
 
 
 
 
2826
  browser: b,
2827
- iOS: {
2828
- iPhone: IS_IPHONE,
2829
- iPad: IS_IPAD || IS_IPAD_CHROME,
2830
- version: IOS_VER,
2831
- chrome: IS_IPAD_CHROME
2832
- },
 
2833
  subtitles: !!video.addTextTrack,
2834
- fullscreen: typeof document.webkitCancelFullScreen == 'function' && !/Mac OS X 10_5.+Version\/5\.0\.\d Safari/.test(UA) ||
2835
  document.mozFullScreenEnabled ||
2836
  typeof document.exitFullscreen == 'function' ||
2837
  typeof document.msExitFullscreen == 'function',
@@ -2843,12 +3005,20 @@ var flowplayer = _dereq_('../flowplayer'),
2843
  zeropreload: !IS_IE && !IS_ANDROID, // IE supports only preload=metadata
2844
  volume: !IS_IPAD && !IS_IPHONE && !IS_SILK && !IS_IPAD_CHROME,
2845
  cachedVideoTag: !IS_IPAD && !IS_IPHONE && !IS_IPAD_CHROME && !IS_WP,
2846
- firstframe: !IS_IPHONE && !IS_IPAD && !IS_ANDROID && !IS_SILK && !IS_IPAD_CHROME && !IS_WP && !IS_ANDROID_FIREFOX,
 
 
 
 
2847
  inlineVideo: (!IS_IPHONE || IOS_VER >= 10) && (!IS_WP || (WP_VER >= 8.1 && IE_MOBILE_VER >= 11)) && (!IS_ANDROID || ANDROID_VER >= 3),
2848
  hlsDuration: !IS_ANDROID && (!b.safari || IS_IPAD || IS_IPHONE || IS_IPAD_CHROME),
2849
- seekable: !IS_IPAD && !IS_IPAD_CHROME
 
2850
  });
2851
  s.autoplay = s.firstframe;
 
 
 
2852
  // flashVideo
2853
  try {
2854
  var plugin = navigator.plugins["Shockwave Flash"],
@@ -2884,7 +3054,7 @@ var flowplayer = _dereq_('../flowplayer'),
2884
  })();
2885
 
2886
 
2887
- },{"../flowplayer":28,"extend-object":36}],23:[function(_dereq_,module,exports){
2888
  'use strict';
2889
 
2890
  var flowplayer = _dereq_('../flowplayer')
@@ -2929,7 +3099,7 @@ flowplayer(function(api, root) {
2929
  });
2930
  });
2931
 
2932
- },{"../common":1,"../flowplayer":28,"bean":31}],24:[function(_dereq_,module,exports){
2933
  (function (Buffer){
2934
  'use strict';
2935
  var flowplayer = _dereq_('../flowplayer'),
@@ -3029,7 +3199,6 @@ flowplayer(function(api, root) {
3029
  <a class="fp-icon fp-playbtn"></a>\
3030
  <span class="fp-elapsed">00:00</span>\
3031
  <div class="fp-timeline fp-bar">\
3032
- <div class="fp-buffer"></div>\
3033
  <span class="fp-timestamp"></span>\
3034
  <div class="fp-progress fp-color"></div>\
3035
  </div>\
@@ -3062,8 +3231,7 @@ flowplayer(function(api, root) {
3062
  }
3063
 
3064
  // widgets
3065
- var buffer = find("buffer"),
3066
- waiting = find('waiting'),
3067
  elapsed = find("elapsed"),
3068
  ratio = find("ratio"),
3069
  speedFlash = find('speed-flash'),
@@ -3156,13 +3324,32 @@ flowplayer(function(api, root) {
3156
  common.addClass(play, 'fp-visible');
3157
 
3158
  // buffer
3159
- }).on("buffer", function() {
3160
  var video = api.video,
3161
- max = video.buffer / video.duration;
3162
 
3163
  if (!video.seekable && support.seekable) timelineApi.max(api.conf.live ? Infinity : max);
3164
- if (max < 1) common.css(buffer, "width", (max * 100) + "%");
3165
- else common.css(buffer, 'width', '100%');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3166
  }).on("speed", function(e, api, val) {
3167
  if (api.video.time) {
3168
  common.text(speedFlash, val + "x");
@@ -3183,7 +3370,6 @@ flowplayer(function(api, root) {
3183
  }
3184
 
3185
  }).on("buffered", function() {
3186
- common.css(buffer, 'width', '100%');
3187
  timelineApi.max(1);
3188
 
3189
  // progress
@@ -3242,10 +3428,14 @@ flowplayer(function(api, root) {
3242
  common.removeClass(root, 'is-seeking');
3243
  common.addClass(root, 'is-error');
3244
  if (error) {
3245
- error.message = conf.errors[error.code];
3246
  api.error = true;
3247
 
3248
- var dismiss = api.message((api.engine && api.engine.engineName || 'html5') + ": " + error.message);
 
 
 
 
 
3249
  //common.find('p', el)[0].innerHTML = error.url || video.url || video.src || conf.errorUrls[error.code];
3250
  common.removeClass(root, 'is-mouseover');
3251
  api.one('load progress', function() { dismiss(); });
@@ -3253,6 +3443,17 @@ flowplayer(function(api, root) {
3253
 
3254
 
3255
  // hover
 
 
 
 
 
 
 
 
 
 
 
3256
  });
3257
  //Interaction events
3258
  bean.on(root, "mouseenter mouseleave", function(e) {
@@ -3310,7 +3511,9 @@ flowplayer(function(api, root) {
3310
  var x = ev.pageX || ev.clientX,
3311
  delta = x - common.offset(timeline).left,
3312
  percentage = delta / common.width(timeline),
3313
- seconds = (api.rtl ? 1 - percentage : percentage) * api.video.duration;
 
 
3314
  if (percentage < 0) return;
3315
  common.html(timelineTooltip, format(seconds));
3316
  var left = (delta - common.width(timelineTooltip) / 2);
@@ -3364,7 +3567,7 @@ flowplayer(function(api, root) {
3364
  common.addClass(root, "is-poster");
3365
  common.addClass(play, 'fp-visible');
3366
  api.poster = true;
3367
- api.one(conf.autoplay ? "progress seek" : "resume seek", function() {
3368
  common.removeClass(root, "is-poster");
3369
  common.removeClass(play, 'fp-visible');
3370
  api.poster = false;
@@ -3413,18 +3616,31 @@ flowplayer(function(api, root) {
3413
 
3414
  hover(noToggle);
3415
 
 
 
3416
  api.on('shutdown', function() {
3417
  bean.off(timeline);
3418
  bean.off(volumeSlider);
 
3419
  });
3420
 
 
 
 
 
 
 
 
 
 
 
3421
  });
3422
 
3423
 
3424
  module.exports.format = format;
3425
 
3426
  }).call(this,_dereq_("buffer").Buffer)
3427
- },{"../common":1,"../flowplayer":28,"./ui/bar-slider":25,"./ui/slider":26,"bean":31,"buffer":32}],25:[function(_dereq_,module,exports){
3428
  var bean = _dereq_('bean')
3429
  , common = _dereq_('../../common');
3430
 
@@ -3494,7 +3710,7 @@ function slider(root, opts) {
3494
 
3495
  module.exports = slider;
3496
 
3497
- },{"../../common":1,"bean":31}],26:[function(_dereq_,module,exports){
3498
  'use strict';
3499
  // skip IE policies
3500
  // document.ondragstart = function () { return false; };
@@ -3645,7 +3861,7 @@ var slider = function(root, rtl) {
3645
 
3646
  module.exports = slider;
3647
 
3648
- },{"../../common":1,"bean":31}],27:[function(_dereq_,module,exports){
3649
 
3650
 
3651
  var clipboard = module.exports = function(text, successCallback, errorCallback) {
@@ -3669,7 +3885,7 @@ function doCopy(text) {
3669
  if (!success) throw new Error('Unsuccessfull');
3670
  }
3671
 
3672
- },{}],28:[function(_dereq_,module,exports){
3673
  'use strict';
3674
  var extend = _dereq_('extend-object'),
3675
  isFunction = _dereq_('is-function'),
@@ -3729,10 +3945,14 @@ var flowplayer = module.exports = function(fn, opts, callback) {
3729
 
3730
  extend(flowplayer, {
3731
 
3732
- version: '7.0.2',
3733
 
3734
  engines: [],
3735
 
 
 
 
 
3736
  extensions: [],
3737
 
3738
  conf: {},
@@ -3776,8 +3996,8 @@ extend(flowplayer, {
3776
  live: false,
3777
  livePositionOffset: 120,
3778
 
3779
- swf: "//releases.flowplayer.org/7.0.2/flowplayer.swf",
3780
- swfHls: "//releases.flowplayer.org/7.0.2/flowplayerhls.swf",
3781
 
3782
  speeds: [0.25, 0.5, 1, 1.5, 2],
3783
 
@@ -3811,7 +4031,9 @@ extend(flowplayer, {
3811
  ],
3812
  playlist: [],
3813
 
3814
- hlsFix: isSafari && safariVersion < 8
 
 
3815
 
3816
  },
3817
  // Expose utilities for plugins
@@ -3850,6 +4072,7 @@ if (typeof window.jQuery !== 'undefined') {
3850
  if (val !== undefined && ['autoplay', 'poster'].indexOf(key) !== -1) conf[key] = val ? val : true;
3851
  else if (val !== undefined) clip[key] = val ? val : true;
3852
  });
 
3853
  clip.subtitles = videoTag.find('track').map(function() {
3854
  var tr = $(this);
3855
  return {
@@ -3944,6 +4167,10 @@ function initializePlayer(element, opts, callback) {
3944
  } catch (e) { /* */ }
3945
  api.hijacked = false;
3946
  },
 
 
 
 
3947
  load: function(video, callback) {
3948
 
3949
  if (api.error || api.loading) return;
@@ -3982,6 +4209,7 @@ function initializePlayer(element, opts, callback) {
3982
  if (video.src) {
3983
  var e = api.trigger('load', [api, video, engine], true);
3984
  if (!e.defaultPrevented) {
 
3985
  engine.load(video);
3986
 
3987
  // callback
@@ -4038,6 +4266,7 @@ function initializePlayer(element, opts, callback) {
4038
  time = api.video.time + (time ? delta : -delta);
4039
  time = Math.min(Math.max(time, 0), api.video.duration - 0.1);
4040
  }
 
4041
  if (api.hijacked) return api.hijacked.seek(time, callback) | api;
4042
  if (api.ready) {
4043
  lastSeekPosition = time;
@@ -4074,8 +4303,11 @@ function initializePlayer(element, opts, callback) {
4074
  storage.muted = api.muted = flag;
4075
  storage.volume = !isNaN(storage.volume) ? storage.volume : conf.volume; // make sure storage has volume
4076
  }
4077
- api.volume(flag ? 0 : storage.volume, true);
4078
- api.trigger("mute", [api, flag]);
 
 
 
4079
  return api;
4080
  },
4081
 
@@ -4109,9 +4341,13 @@ function initializePlayer(element, opts, callback) {
4109
  stop: function() {
4110
  if (api.ready) {
4111
  api.pause();
4112
- api.seek(0, function() {
 
 
 
 
4113
  api.trigger("stop", [api]);
4114
- });
4115
  }
4116
  return api;
4117
  },
@@ -4197,11 +4433,13 @@ function initializePlayer(element, opts, callback) {
4197
 
4198
 
4199
  api.on('boot', function() {
 
4200
 
4201
  // splash
4202
- if (conf.splash || common.hasClass(root, "is-splash") || !flowplayer.support.firstframe) {
 
4203
  api.forcedSplash = !conf.splash && !common.hasClass(root, "is-splash");
4204
- api.splash = conf.autoplay = true;
4205
  if (!conf.splash) conf.splash = true;
4206
  common.addClass(root, "is-splash");
4207
  }
@@ -4289,8 +4527,8 @@ function initializePlayer(element, opts, callback) {
4289
 
4290
  }).on("progress", function(e, api, time) {
4291
  api.video.time = time;
4292
- }).on('buffer', function(e, api, buffer) {
4293
- api.video.buffer = buffer;
4294
  }).on("speed", function(e, api, val) {
4295
  api.currentSpeed = val;
4296
 
@@ -4332,7 +4570,7 @@ function initializePlayer(element, opts, callback) {
4332
  return api;
4333
  }
4334
 
4335
- },{"./common":1,"./ext/events":10,"./ext/resolve":19,"./ext/ui/bar-slider":25,"./ext/ui/slider":26,"bean":31,"extend-object":36,"is-function":39}],29:[function(_dereq_,module,exports){
4336
  /* eslint-disable no-unused-vars */
4337
 
4338
  //Flowplayer with extensions
@@ -4347,6 +4585,7 @@ _dereq_('./ext/support');
4347
 
4348
  //Engines
4349
  _dereq_('./engine/embed');
 
4350
  _dereq_('./engine/html5');
4351
  _dereq_('./engine/flash');
4352
 
@@ -4371,10 +4610,10 @@ _dereq_('./ext/menu');
4371
  _dereq_('./ext/fullscreen');
4372
 
4373
  _dereq_('./ext/mobile');
4374
- flowplayer(function(e,o){function a(e){var o=document.createElement("a");return o.href=e,t.hostname(o.hostname)}var l=function(e,o){var a=e.className.split(" ");a.indexOf(o)===-1&&(e.className+=" "+o)},n=function(e){return"none"!==window.getComputedStyle(e).display},r=e.conf,t=flowplayer.common,i=t.createElement,p=r.swf.indexOf("flowplayer.org")&&r.e&&o.getAttribute("data-origin"),s=p?a(p):t.hostname(),d=(document,r.key);if("file:"==location.protocol&&(s="localhost"),e.load.ed=1,r.hostname=s,r.origin=p||location.href,p&&l(o,"is-embedded"),"string"==typeof d&&(d=d.split(/,\s*/)),d&&"function"==typeof key_check&&key_check(d,s)){if(r.logo){var f=t.find(".fp-player",o)[0],c=i("a",{className:"fp-logo"});p&&(c.href=p),r.embed&&r.embed.popup&&(c.target="_blank");var h=i("img",{src:r.logo});c.appendChild(h),(f||o).appendChild(c)}}else{var c=i("a",{href:"https://flowplayer.org/hello"});o.appendChild(c);var y=i("div",{className:"fp-context-menu fp-menu"},'<strong>&copy; 2017 Flowplayer</strong><a href="https://flowplayer.org/hello">About Flowplayer</a><a href="https://flowplayer.org/license">GPL based license</a>'),g=window.location.href.indexOf("localhost"),f=t.find(".fp-player",o)[0];7!==g&&(f||o).appendChild(y),e.on("pause resume finish unload ready",function(e,a){var l=-1;if(a.video.src)for(var r=[["org","flowplayer","drive"],["org","flowplayer","my"],["org","flowplayer","cdn"]],t=0;t<r.length&&(l=a.video.src.indexOf("://"+r[t].reverse().join(".")),l===-1);t++);if(/pause|resume/.test(e.type)&&"flash"!=a.engine.engineName&&4!=l&&5!=l){var i={display:"block",position:"absolute",left:"16px",bottom:"70px",zIndex:99999,width:"100px",height:"20px",backgroundImage:"url("+[".png","logo","/",".net",".cloudfront","d32wqyuo10o653","//"].reverse().join("")+")"};for(var p in i)i.hasOwnProperty(p)&&(c.style[p]=i[p]);a.load.ed=n(c)&&(7===g||y.parentNode==o||y.parentNode==f),a.load.ed||a.pause()}else c.style.display="none"})}});
4375
 
4376
 
4377
- },{"./engine/embed":2,"./engine/flash":3,"./engine/html5":4,"./ext/airplay":5,"./ext/analytics":6,"./ext/chromecast":7,"./ext/cuepoint":8,"./ext/embed":9,"./ext/facebook":11,"./ext/fullscreen":12,"./ext/keyboard":13,"./ext/menu":14,"./ext/message":15,"./ext/mobile":16,"./ext/playlist":17,"./ext/qsel":18,"./ext/share":20,"./ext/subtitle":21,"./ext/support":22,"./ext/twitter":23,"./ext/ui":24,"./flowplayer":28,"es5-shim":35}],30:[function(_dereq_,module,exports){
4378
  'use strict'
4379
 
4380
  exports.byteLength = byteLength
@@ -4410,22 +4649,22 @@ function placeHoldersCount (b64) {
4410
 
4411
  function byteLength (b64) {
4412
  // base64 is 4/3 + up to two characters of the original data
4413
- return b64.length * 3 / 4 - placeHoldersCount(b64)
4414
  }
4415
 
4416
  function toByteArray (b64) {
4417
- var i, j, l, tmp, placeHolders, arr
4418
  var len = b64.length
4419
  placeHolders = placeHoldersCount(b64)
4420
 
4421
- arr = new Arr(len * 3 / 4 - placeHolders)
4422
 
4423
  // if there are placeholders, only get up to the last complete 4 chars
4424
  l = placeHolders > 0 ? len - 4 : len
4425
 
4426
  var L = 0
4427
 
4428
- for (i = 0, j = 0; i < l; i += 4, j += 3) {
4429
  tmp = (revLookup[b64.charCodeAt(i)] << 18) | (revLookup[b64.charCodeAt(i + 1)] << 12) | (revLookup[b64.charCodeAt(i + 2)] << 6) | revLookup[b64.charCodeAt(i + 3)]
4430
  arr[L++] = (tmp >> 16) & 0xFF
4431
  arr[L++] = (tmp >> 8) & 0xFF
@@ -4490,7 +4729,7 @@ function fromByteArray (uint8) {
4490
  return parts.join('')
4491
  }
4492
 
4493
- },{}],31:[function(_dereq_,module,exports){
4494
  /*!
4495
  * Bean - copyright (c) Jacob Thornton 2011-2012
4496
  * https://github.com/fat/bean
@@ -5233,7 +5472,7 @@ function fromByteArray (uint8) {
5233
  return bean
5234
  });
5235
 
5236
- },{}],32:[function(_dereq_,module,exports){
5237
  (function (global){
5238
  /*!
5239
  * The buffer module from node.js, for the browser.
@@ -7026,7 +7265,7 @@ function isnan (val) {
7026
  }
7027
 
7028
  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
7029
- },{"base64-js":30,"ieee754":37,"isarray":40}],33:[function(_dereq_,module,exports){
7030
  // contains, add, remove, toggle
7031
  var indexof = _dereq_('indexof')
7032
 
@@ -7127,7 +7366,7 @@ function isTruthy(value) {
7127
  return !!value
7128
  }
7129
 
7130
- },{"indexof":38}],34:[function(_dereq_,module,exports){
7131
  // DEV: We don't use var but favor parameters since these play nicer with minification
7132
  function computedStyle(el, prop, getComputedStyle, style) {
7133
  getComputedStyle = window.getComputedStyle;
@@ -7156,7 +7395,7 @@ function computedStyle(el, prop, getComputedStyle, style) {
7156
 
7157
  module.exports = computedStyle;
7158
 
7159
- },{}],35:[function(_dereq_,module,exports){
7160
  /*!
7161
  * https://github.com/es-shims/es5-shim
7162
  * @license es5-shim Copyright 2009-2015 by contributors, MIT License
@@ -9223,7 +9462,7 @@ module.exports = computedStyle;
9223
  }
9224
  }));
9225
 
9226
- },{}],36:[function(_dereq_,module,exports){
9227
  var arr = [];
9228
  var each = arr.forEach;
9229
  var slice = arr.slice;
@@ -9240,7 +9479,7 @@ module.exports = function(obj) {
9240
  return obj;
9241
  };
9242
 
9243
- },{}],37:[function(_dereq_,module,exports){
9244
  exports.read = function (buffer, offset, isLE, mLen, nBytes) {
9245
  var e, m
9246
  var eLen = nBytes * 8 - mLen - 1
@@ -9326,7 +9565,7 @@ exports.write = function (buffer, value, offset, isLE, mLen, nBytes) {
9326
  buffer[offset + i - d] |= s * 128
9327
  }
9328
 
9329
- },{}],38:[function(_dereq_,module,exports){
9330
 
9331
  var indexOf = [].indexOf;
9332
 
@@ -9337,7 +9576,7 @@ module.exports = function(arr, obj){
9337
  }
9338
  return -1;
9339
  };
9340
- },{}],39:[function(_dereq_,module,exports){
9341
  module.exports = isFunction
9342
 
9343
  var toString = Object.prototype.toString
@@ -9354,14 +9593,14 @@ function isFunction (fn) {
9354
  fn === window.prompt))
9355
  };
9356
 
9357
- },{}],40:[function(_dereq_,module,exports){
9358
  var toString = {}.toString;
9359
 
9360
  module.exports = Array.isArray || function (arr) {
9361
  return toString.call(arr) == '[object Array]';
9362
  };
9363
 
9364
- },{}],41:[function(_dereq_,module,exports){
9365
  (function (global){
9366
  /*! https://mths.be/punycode v1.4.1 by @mathias */
9367
  ;(function(root) {
@@ -9898,7 +10137,7 @@ module.exports = Array.isArray || function (arr) {
9898
  }(this));
9899
 
9900
  }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
9901
- },{}],42:[function(_dereq_,module,exports){
9902
  /*!
9903
  * $script.js JS loader & dependency manager
9904
  * https://github.com/ded/script.js
@@ -10023,5 +10262,5 @@ module.exports = Array.isArray || function (arr) {
10023
  return $script
10024
  });
10025
 
10026
- },{}]},{},[29])(29)
10027
  });
1
  /*!
2
 
3
+ Flowplayer v7.2.1 (Thursday, 19. October 2017 01:23PM) | flowplayer.com/license
4
 
5
  */
6
  /*! (C) WebReflection Mit Style License */
74
  common.attr(el, key, attributes[key]);
75
  }
76
  }
77
+ if (innerHTML) el.innerHTML = innerHTML;
78
  return el;
79
  } catch (e) {
80
  if (!$) throw e;
298
 
299
  })(window.CSSStyleDeclaration.prototype);
300
 
301
+ },{"class-list":36,"computed-style":37,"punycode":44}],2:[function(_dereq_,module,exports){
302
  'use strict';
303
  var common = _dereq_('../common');
304
 
723
  return /^https?:/.test(url);
724
  }
725
 
726
+ },{"../common":1,"../flowplayer":31,"./embed":2,"bean":34,"extend-object":39}],4:[function(_dereq_,module,exports){
727
  'use strict';
728
+ var flowplayer = _dereq_('../flowplayer')
729
+ , support = flowplayer.support
730
+ , common = flowplayer.common
731
+ , html5factory = _dereq_('./html5-factory');
 
 
 
 
732
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
733
 
 
 
 
 
 
 
 
 
 
 
734
 
735
  function canPlay(type) {
736
+ if (typeof window.Hls === 'undefined') return false;
737
+ return /mpegurl/.test(type) && window.Hls.isSupported();
 
738
  }
739
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
740
  var engine;
741
 
742
  engine = function(player, root) {
743
 
744
+ var hls, Hls = window.Hls
745
+ , lastSelectedLevel
746
+ , lastSource;
 
 
 
 
 
 
 
747
 
748
+ return html5factory('hlsjs-lite', player, root, canPlay, function(video, api, engineApi) {
749
+ hls = engine.hls = new Hls(flowplayer.extend({}, player.conf.hlsjs, video.hlsjs));
750
+ engine.extensions.forEach(function(ext) {
751
+ ext(hls, player, root);
752
+ });
753
+ hls.loadSource(video.src);
 
754
 
755
+ // API overriders
756
+ engineApi.resume = function() {
757
+ if (player.live && !player.dvr) api.currentTime = hls.liveSyncPosition;
758
+ api.play();
759
+ };
760
+
761
+ engineApi.seek = function(seekTo) {
762
+ try {
763
+ if (player.live && !player.dvr) api.currentTime = Math.min(seekTo, hls.liveSyncPosition);
764
+ else api.currentTime = seekTo;
765
+ } catch (e) {
766
+ player.debug('Failed to seek to ', seekTo, e);
767
+ }
768
+ };
769
+
770
+ // Quality selection
771
+ player.on('quality', function(_ev, _api, q) {
772
+ hls.nextLevel = lastSelectedLevel = q;
773
+ });
774
+
775
+
776
+ hls.on(Hls.Events.MANIFEST_PARSED, function(_, data) {
777
+ var hlsQualities = video.hlsQualities || player.conf.hlsQualities
778
+ , confQualities
779
+ , qualityLabels = {}
780
+ , levels = data.levels;
781
+
782
+ if (hlsQualities === false) return hls.attachMedia(api);
783
+ if (hlsQualities === 'drive') switch (levels.length) {
784
+ case 4:
785
+ confQualities = [1, 2, 3];
786
+ break;
787
+ case 5:
788
+ confQualities = [1, 2, 3, 4];
789
+ break;
790
+ case 6:
791
+ confQualities = [1, 3, 4, 5];
792
+ break;
793
+ case 7:
794
+ confQualities = [1, 3, 5, 6];
795
+ break;
796
+ case 8:
797
+ confQualities = [1, 3, 6, 7];
798
+ break;
799
+ default:
800
+ if (levels.length < 3 || (levels[0].height && levels[2].height && levels[0].height === levels[2].height)) {
801
+ confQualities = [];
802
+ } else {
803
+ confQualities = [1, 2];
804
  }
805
+ break;
806
+ }
 
 
 
807
 
808
+ video.qualities = [{
809
+ value: -1,
810
+ label: 'Auto'
811
+ }]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
812
 
813
+ if (Array.isArray(hlsQualities)) {
814
+ video.qualities = [];
815
+ confQualities = hlsQualities.map(function(q) {
816
+ if (typeof q.level !== 'undefined') qualityLabels[q.level] = q.label;
817
+ return typeof q.level !== 'undefined' ? q.level : q;
818
+ });
819
+ }
820
 
821
+ var initialLevel = -2;
 
 
 
 
 
 
 
822
 
823
+ video.qualities = video.qualities.concat(levels.map(function(level, i) {
824
+ if (confQualities && confQualities.indexOf(i) === -1) return false;
825
+ var label = qualityLabels[i] || (Math.min(level.width, level.height) + 'p');
826
+ if (!qualityLabels[i] && hlsQualities !== 'drive') label += ' (' + Math.round(level.bitrate / 1000) + 'k)';
827
+ if (i === lastSelectedLevel) initialLevel = i;
828
 
829
+ return {
830
+ value: i,
831
+ label: label
832
+ };
833
+ })).filter(common.identity);
834
 
 
835
 
836
+ var currentLevel = video.quality = initialLevel === -2 ? video.qualities[0].value || -1 : initialLevel;
 
 
 
837
 
838
+ if (currentLevel !== hls.currentLevel) hls.currentLevel = currentLevel;
 
 
839
 
840
+ // End quality selection
 
 
841
 
842
+ hls.attachMedia(api);
 
 
843
 
844
+ if (lastSource && video.src !== lastSource) api.play();
845
+ lastSource = video.src;
846
+ });
847
+ });
848
+ };
 
 
849
 
 
 
 
 
 
 
850
 
851
+ engine.canPlay = function(type, conf) {
852
+ if (support.browser.safari && !(conf.clip && conf.clip.hlsjs || conf.hlsjs || {}).safari) return false;
853
+ return flowplayer.support.video && canPlay(type);
854
+ };
855
+
856
+ engine.engineName = 'hlsjs-lite';
857
+
858
+ engine.plugin = function(extension) {
859
+ engine.extensions.push(extension);
860
+ }
861
+
862
+ engine.extensions = [];
863
+
864
+ flowplayer.engines.push(engine);
865
+
866
+ },{"../flowplayer":31,"./html5-factory":5}],5:[function(_dereq_,module,exports){
867
+ /*eslint indent: ["error", 2]*/
868
+ /*eslint quotes: ["error", "single"]*/
869
+
870
+ var flowplayer = _dereq_('../flowplayer')
871
+ , common = flowplayer.common
872
+ , support = flowplayer.support
873
+ , bean = flowplayer.bean
874
+ , extend = flowplayer.extend;
875
+
876
+ var desktopSafari = support.browser.safari && !support.iOS;
877
+ // HTML5 --> Flowplayer event
878
+ var EVENTS = {
879
+ ended: 'finish',
880
+ pause: 'pause',
881
+ play: 'resume',
882
+ timeupdate: 'progress',
883
+ volumechange: 'volume',
884
+ ratechange: 'speed',
885
+ seeked: 'seek',
886
+ loadedmetadata: !desktopSafari ? 'ready' : 0,
887
+ canplaythrough: desktopSafari ? 'ready' : 0,
888
+ durationchange: 'ready',
889
+ error: 'error',
890
+ dataunavailable: 'error',
891
+ webkitendfullscreen: !flowplayer.support.inlineVideo && 'unload',
892
+ progress: 'buffer'
893
+ };
894
+
895
+
896
+ function html5factory(engineName, player, root, canPlay, ext) {
897
+ var api = common.findDirect('video', root)[0] || common.find('.fp-player > video', root)[0]
898
+ , conf = player.conf
899
+ , timer
900
+ , volumeLevel
901
+ , self;
902
+ return self = {
903
+ engineName: engineName,
904
+
905
+ pick: function(sources) {
906
+ var source = support.video && sources.filter(function(s) {
907
+ return canPlay(s.type);
908
+ })[0];
909
+
910
+ if (!source) return;
911
+ if (typeof source.src === 'string') source.src = common.createAbsoluteUrl(source.src);
912
+ return source;
913
+ },
914
+
915
+ load: function(video) {
916
+ var container = common.find('.fp-player', root)[0];
917
+
918
+ if (!api) {
919
+ api = document.createElement('video');
920
+ common.prepend(container, api);
921
+ api.autoplay = !!conf.splash;
922
  }
923
+ common.addClass(api, 'fp-engine');
924
+ common.find('track', api).forEach(common.removeNode);
925
+ api.preload = 'none';
926
 
927
+ if (!conf.nativesubtitles) common.attr(api, 'crossorigin', false);
928
 
929
+ if (!conf.disableInline) {
930
+ api.setAttribute('webkit-playsinline', 'true');
931
+ api.setAttribute('playsinline', 'true');
932
+ }
933
 
934
+ if (!support.inlineVideo) {
935
+ common.css(api, {
936
+ position: 'absolute',
937
+ top: '-9999em'
938
+ });
939
  }
 
940
 
941
+ if (support.subtitles && conf.nativesubtitles && video.subtitles && video.subtitles.length) {
942
+ common.addClass(api, 'native-subtitles');
943
+ var subtitles = video.subtitles;
944
+ var setMode = function(mode) {
945
+ var tracks = api.textTracks;
946
+ if (!tracks.length) return;
947
+ tracks[0].mode = mode;
948
+ };
949
+ if (subtitles.some(function(st) { return !common.isSameDomain(st.src); })) common.attr(api, 'crossorigin', 'anonymous');
950
+ if (typeof api.textTracks.addEventListener === 'function') api.textTracks.addEventListener('addtrack', function() {
951
+ setMode('disabled');
952
+ setMode('showing');
953
+ });
954
+ subtitles.forEach(function(st) {
955
+ api.appendChild(common.createElement('track', {
956
+ kind: 'subtitles',
957
+ srclang: st.srclang || 'en',
958
+ label: st.label || 'en',
959
+ src: st.src,
960
+ 'default': st['default']
961
+ }));
962
+ });
963
+ }
964
 
965
+ // IE does not fire delegated timeupdate events
966
+ bean.off(api, 'timeupdate', common.noop);
967
+ bean.on(api, 'timeupdate', common.noop);
 
 
968
 
969
+ common.prop(api, 'loop', false);
970
+ player.off('.loophack');
971
+ if (video.loop || conf.loop) {
972
+ player.on('finish.loophack', function() { player.resume(); });
973
+ }
974
 
975
+ if (typeof volumeLevel !== 'undefined') {
976
+ api.volume = volumeLevel;
977
+ }
978
+
979
+ ext(video, api, self);
980
+ if (conf.autoplay || conf.splash || video.autoplay) {
981
+ player.debug('Autoplay / Splash setup, try to start video');
982
+ try {
983
+ var p = api.play();
984
+ if (p && p.catch) {
985
+ p.catch(function(err) {
986
+ if (err.name === 'AbortError' && err.code === 20) return;
987
+ player.debug('Play errored, trying muted', err);
988
+ player.mute(true);
989
+ api.play();
990
+ });
991
+ }
992
+ } catch(e) {
993
+ player.debug('play() error thrown', e);
994
+ }
995
+ }
996
+
997
+ self._listeners = listen(api, common.find('source', api).concat(api), video) || self._listeners;
998
+
999
+
1000
+ var preloadCheck = function() {
1001
+ if (!isInViewport(root)) return;
1002
+ if (support.preloadMetadata) api.preload = 'metadata';
1003
+ else api.load();
1004
+ bean.off(document, 'scroll.preloadviewport');
1005
  };
1006
+ preloadCheck();
1007
+ bean.off(document, 'scroll.preloadviewport');
1008
+ bean.on(document, 'scroll.preloadviewport', function() {
1009
+ window.requestAnimationFrame(preloadCheck);
1010
+ });
1011
+ },
1012
 
1013
+ mute: function(flag) {
1014
+ api.muted = !!flag;
1015
+ player.trigger('mute', [player, flag]);
1016
+ player.trigger('volume', [player, flag ? 0 : api.volume]);
1017
+ },
1018
+
1019
+ pause: function() {
1020
+ api.pause();
1021
+ },
1022
+
1023
+ resume: function() {
1024
+ api.play();
1025
+ },
1026
+
1027
+ speed: function(val) {
1028
+ api.playbackRate = val;
1029
+ },
1030
+
1031
+ seek: function(time) {
1032
+ try {
1033
+ api.currentTime = time;
1034
+ } catch (ignored) {}
1035
+ },
1036
+
1037
+ volume: function(level) {
1038
+ volumeLevel = level;
1039
+ if (api) {
1040
+ api.volume = level;
1041
+ if (level) self.mute(false);
1042
+ }
1043
+ },
1044
+
1045
+ unload: function() {
1046
+ bean.off(document, 'scroll.preloadviewport');
1047
+ common.find('video.fp-engine', root).forEach(function (videoTag) {
1048
+ common.attr(videoTag, 'src', '');
1049
+ common.removeNode(videoTag);
1050
+ });
1051
+ timer = clearInterval(timer);
1052
+ var instanceId = root.getAttribute('data-flowplayer-instance-id');
1053
+ delete api.listeners[instanceId];
1054
+ api = 0;
1055
+ if (self._listeners) Object.keys(self._listeners).forEach(function(typ) {
1056
+ self._listeners[typ].forEach(function(l) {
1057
+ root.removeEventListener(typ, l, true);
1058
  });
1059
+ });
1060
+ }
1061
+ };
1062
+
1063
+ function listen(api, sources, video) {
1064
+ // listen only once
1065
+ var instanceId = root.getAttribute('data-flowplayer-instance-id');
1066
+
1067
+ if (api.listeners && api.listeners.hasOwnProperty(instanceId)) {
1068
+ api.listeners[instanceId] = video;
1069
+ return;
1070
+ }
1071
+ (api.listeners || (api.listeners = {}))[instanceId] = video;
1072
+
1073
+ bean.on(sources, 'error', function(e) {
1074
+ try {
1075
+ if (canPlay(e.target.getAttribute('type'))) {
1076
+ player.trigger('error', [player, { code: 4, video: extend(video, {src: api.src, url: api.src}) }]);
1077
+ }
1078
+ } catch (er) {
1079
+ // Most likely: https://bugzilla.mozilla.org/show_bug.cgi?id=208427
1080
  }
1081
+ });
1082
 
1083
+ player.on('shutdown', function() {
1084
+ bean.off(sources);
1085
+ bean.off(api, '.dvrhack');
1086
+ player.off('.loophack');
1087
+ });
 
1088
 
1089
+ var eventListeners = {};
1090
+ //Special event handling for HLS metadata events
1091
 
1092
+ var listenMetadata = function(track) {
1093
+ if (track.kind !== 'metadata') return;
1094
+ track.mode = 'hidden';
1095
+ track.addEventListener('cuechange', function() {
1096
+ player.trigger('metadata', [player, track.activeCues[0].value]);
1097
+ }, false);
1098
+ };
1099
 
1100
+ if (api && api.textTracks && api.textTracks.length) Array.prototype.forEach.call(api.textTracks, listenMetadata);
1101
+ if (api && api.textTracks && typeof api.textTracks.addEventListener === 'function') api.textTracks.addEventListener('addtrack', function(tev) {
1102
+ listenMetadata(tev.track);
1103
+ }, false);
1104
+ if (player.conf.dvr || player.dvr || video.dvr) {
1105
+ bean.on(api, 'progress.dvrhack', function() {
1106
+ if (!api.seekable.length) return;
1107
+ player.video.duration = api.seekable.end(null);
1108
+ player.video.seekOffset = api.seekable.start(null);
1109
+ player.trigger('dvrwindow', [player, {
1110
+ start: api.seekable.start(null),
1111
+ end: api.seekable.end(null)
1112
+ }]);
1113
+ if (api.currentTime >= api.seekable.start(null)) return;
1114
+ api.currentTime = api.seekable.start(null);
1115
+ });
1116
+ }
1117
 
1118
+ Object.keys(EVENTS).forEach(function(type) {
1119
+ var flow = EVENTS[type];
1120
+ if (type === 'webkitendfullscreen' && player.conf.disableInline) flow = 'unload';
1121
+ if (!flow) return;
1122
+ var l = function(e) {
1123
+ video = api.listeners[instanceId];
1124
+ if (!e.target || !common.hasClass(e.target, 'fp-engine')) return;
1125
 
1126
+ if (conf.debug && !/progress/.test(flow)) console.log(type, '->', flow, e);
1127
 
1128
+ var triggerEvent = function(f) {
1129
+ player.trigger(f || flow, [player, arg]);
1130
+ };
1131
 
1132
+ // no events if player not ready
1133
+ if (!player.ready && !/ready|error/.test(flow) || !flow || !common.find('video', root).length) {
1134
+ if (flow === 'resume') player.one('ready', function() { setTimeout(function() { triggerEvent(); }) });
1135
+ return;
1136
+ }
1137
+ var arg;
 
1138
 
1139
+ if (flow === 'unload') { //Call player unload
1140
+ player.unload();
1141
+ return;
1142
+ }
1143
 
1144
+ switch (flow) {
1145
+
1146
+ case 'ready':
1147
+ if (player.ready) return;
1148
+ if (!api.duration && !player.live) return;
1149
+ arg = extend(video, {
1150
+ duration: api.duration < Number.MAX_VALUE ? api.duration : 0,
1151
+ width: api.videoWidth,
1152
+ height: api.videoHeight,
1153
+ url: api.currentSrc,
1154
+ src: api.currentSrc
1155
+ });
1156
+
1157
+ try {
1158
+ arg.seekable = /mpegurl/i.test(video ? (video.type || '') : '') && api.duration || api.seekable && api.seekable.end(null) || player.live;
1159
+
1160
+ } catch (ignored) {}
1161
+
1162
+ if (!player.live && !arg.duration && !support.hlsDuration && type === 'loadeddata') {
1163
+ var durationChanged = function() {
1164
+ arg.duration = api.duration;
1165
+ try {
1166
+ arg.seekable = api.seekable && api.seekable.end(null);
1167
+
1168
+ } catch (ignored) {}
1169
+ triggerEvent();
1170
+ api.removeEventListener('durationchange', durationChanged);
1171
+ common.toggleClass(root, 'is-live', false);
1172
+ };
1173
+ api.addEventListener('durationchange', durationChanged);
1174
+
1175
+ // Ugly hack to handle broken Android devices
1176
+ var timeUpdated = function() {
1177
+ if (!player.ready && !api.duration) { // No duration even though the video already plays
1178
+ arg.duration = 0;
1179
+ common.addClass(root, 'is-live'); // Make UI believe it's live
1180
+ triggerEvent();
1181
+ }
1182
+ api.removeEventListener('timeupdate', timeUpdated);
1183
+ };
1184
+ api.addEventListener('timeupdate', timeUpdated);
1185
+ return;
1186
+ }
1187
 
1188
+ break;
 
1189
 
1190
+ case 'progress': case 'seek':
 
1191
 
1192
+ if (api.currentTime > 0 || player.live) {
1193
+ arg = Math.max(api.currentTime, 0);
1194
 
1195
+ } else if (flow === 'seek' && api.currentTime === 0) {
1196
+ arg = 0;
1197
+ } else if (flow == 'progress') {
1198
+ return;
1199
+ }
1200
+ break;
1201
+
1202
+ case 'buffer':
1203
+ arg = [];
1204
+ for (var i=0; i < api.buffered.length; i++) {
1205
+ arg.push({
1206
+ start: api.buffered.start(i),
1207
+ end: api.buffered.end(i)
1208
+ });
1209
+ }
1210
+ if (api.buffered.end(null) === api.duration) triggerEvent('buffered');
1211
+ break;
1212
+
1213
+ case 'speed':
1214
+ arg = round(api.playbackRate);
1215
+ break;
1216
+
1217
+ case 'volume':
1218
+ arg = round(api.muted ? 0 : api.volume);
1219
+ break;
1220
+
1221
+ case 'error':
1222
+ try {
1223
+ arg = (e.srcElement || e.originalTarget).error;
1224
+ arg.video = extend(video, {src: api.src, url: api.src});
1225
+ } catch (er) {
1226
+ // Most likely https://bugzilla.mozilla.org/show_bug.cgi?id=208427
1227
+ return;
1228
+ }
1229
+ }
1230
 
1231
+ triggerEvent();
 
 
 
 
 
 
 
1232
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1233
 
1234
+ };
1235
+ root.addEventListener(type, l, true);
1236
+ if (!eventListeners[type]) eventListeners[type] = [];
1237
+ eventListeners[type].push(l);
1238
 
1239
+ });
1240
+ return eventListeners;
1241
 
1242
+ }
 
1243
 
1244
+ }
 
 
 
1245
 
1246
+ module.exports = html5factory;
1247
 
1248
+ function round(val, per) {
1249
+ per = per || 100;
1250
+ return Math.round(val * per) / per;
1251
+ }
1252
 
1253
+ function isInViewport(elem) {
1254
+ var rect = elem.getBoundingClientRect();
 
1255
 
1256
+ return (
1257
+ rect.top >= 0 &&
1258
+ rect.left >= 0 &&
1259
+ rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) + rect.height && /*or $(window).height() */
1260
+ rect.right <= (window.innerWidth || document.documentElement.clientWidth) + rect.width /*or $(window).width() */
1261
+ );
1262
+ }
 
 
1263
 
1264
+ },{"../flowplayer":31}],6:[function(_dereq_,module,exports){
1265
+ 'use strict';
1266
+ var flowplayer = _dereq_('../flowplayer')
1267
+ , common = flowplayer.common
1268
+ , html5factory = _dereq_('./html5-factory');
1269
 
1270
+ var VIDEO = document.createElement('video');
1271
 
1272
+ function getType(type) {
1273
+ return /mpegurl/i.test(type) ? "application/x-mpegurl" : type;
1274
+ }
 
1275
 
1276
+ function canPlay(type) {
1277
+ if (!/^(video|application)/i.test(type))
1278
+ type = getType(type);
1279
+ return !!VIDEO.canPlayType(type).replace("no", '');
1280
+ }
1281
 
1282
+ var engine;
1283
+
1284
+ engine = function(player, root) {
1285
 
1286
+ return html5factory('html5', player, root, canPlay, function(video, api) {
1287
+ if (api.currentSrc !== video.src) {
1288
+ common.find('source', api).forEach(common.removeNode);
1289
+ api.src = video.src;
1290
+ api.type = video.type;
1291
+ }
1292
+ });
1293
  };
1294
 
1295
 
1301
 
1302
  flowplayer.engines.push(engine);
1303
 
1304
+ },{"../flowplayer":31,"./html5-factory":5}],7:[function(_dereq_,module,exports){
1305
  'use strict';
1306
  var flowplayer = _dereq_('../flowplayer')
1307
  , common = _dereq_('../common')
1340
 
1341
  });
1342
 
1343
+ },{"../common":1,"../flowplayer":31,"bean":34}],8:[function(_dereq_,module,exports){
1344
  'use strict';
1345
  /* global _gat */
1346
  var flowplayer = _dereq_('../flowplayer'),
1415
 
1416
  });
1417
 
1418
+ },{"../flowplayer":31,"./resolve":21,"bean":34,"scriptjs":45}],9:[function(_dereq_,module,exports){
1419
  /* global chrome */
1420
  /* eslint-disable no-console */
1421
 
1428
 
1429
 
1430
  flowplayer(function(api, root) {
1431
+ if (api.conf.chromecast === false) return;
1432
  scriptjs('https://www.gstatic.com/cv/js/sender/v1/cast_sender.js');
1433
  window['__onGCastApiAvailable'] = function(loaded) {
1434
  if (!loaded) return;
1550
 
1551
  });
1552
 
1553
+ },{"../common":1,"../flowplayer":31,"bean":34,"scriptjs":45}],10:[function(_dereq_,module,exports){
1554
  'use strict';
1555
  var flowplayer = _dereq_('../flowplayer'),
1556
  common = _dereq_('../common'),
1670
 
1671
  });
1672
 
1673
+ },{"../common":1,"../flowplayer":31,"bean":34}],11:[function(_dereq_,module,exports){
1674
  'use strict';
1675
  var flowplayer = _dereq_('../flowplayer'),
1676
  bean = _dereq_('bean'),
1716
 
1717
  });
1718
 
1719
+ },{"../common":1,"../flowplayer":31,"./util/clipboard":30,"bean":34}],12:[function(_dereq_,module,exports){
1720
  'use strict';
1721
  /**
1722
  * Mimimal jQuery-like event emitter implementation
1824
  'shutdown'
1825
  ];
1826
 
1827
+ },{}],13:[function(_dereq_,module,exports){
1828
  'use strict';
1829
 
1830
  var flowplayer = _dereq_('../flowplayer')
1867
  });
1868
  });
1869
 
1870
+ },{"../common":1,"../flowplayer":31,"bean":34}],14:[function(_dereq_,module,exports){
1871
  'use strict';
1872
  var flowplayer = _dereq_('../flowplayer'),
1873
  bean = _dereq_('bean'),
1886
  if (!FULL_PLAYER && (!el.parentNode || !el.parentNode.getAttribute('data-flowplayer-instance-id'))) return;
1887
  var player = FULL_PLAYER || flowplayer(el.parentNode);
1888
  if (el && !FULL_PLAYER) {
1889
+ FULL_PLAYER = player.trigger(FS_ENTER, [player]);
1890
  } else {
1891
  FULL_PLAYER.trigger(FS_EXIT, [FULL_PLAYER]);
1892
  FULL_PLAYER = null;
1926
  if (flag) {
1927
  ['requestFullScreen', 'webkitRequestFullScreen', 'mozRequestFullScreen', 'msRequestFullscreen'].forEach(function(fName) {
1928
  if (typeof wrapper[fName] === 'function') {
1929
+ wrapper[fName](Element.ALLOW_KEYBOARD_INPUT);
 
 
 
 
1930
  }
1931
  });
1932
 
1934
  ['exitFullscreen', 'webkitCancelFullScreen', 'mozCancelFullScreen', 'msExitFullscreen'].forEach(function(fName) {
1935
  if (typeof document[fName] === 'function') {
1936
  document[fName]();
 
1937
  }
1938
  });
1939
  }
1984
 
1985
  });
1986
 
1987
+ },{"../common":1,"../flowplayer":31,"bean":34}],15:[function(_dereq_,module,exports){
1988
  'use strict';
1989
  var flowplayer = _dereq_('../flowplayer'),
1990
  bean = _dereq_('bean'),
2056
  if (focused) focusedRoot = root;
2057
  });
2058
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2059
  api.bind('shutdown', function() {
2060
  if (focusedRoot == root) focusedRoot = null;
2061
  });
2063
  });
2064
 
2065
 
2066
+ },{"../common":1,"../flowplayer":31,"bean":34}],16:[function(_dereq_,module,exports){
2067
  var flowplayer = _dereq_('../flowplayer')
2068
  , common = _dereq_('../common')
2069
  , bean = _dereq_('bean');
2085
  top: common.offset(triggerElement).top + common.height(triggerElement)
2086
  };
2087
  }
2088
+ if (!coordinates) return common.css(menu, 'top', 'auto');
2089
  coordinates.rightFallbackOffset = coordinates.rightFallbackOffset || 0;
2090
  var top = coordinates.top - common.offset(ui).top
2091
  , left = coordinates.left - common.offset(ui).left
2099
 
2100
  api.hideMenu = function(menu) {
2101
  common.toggleClass(menu, 'fp-active', false);
2102
+ common.css(menu, {
2103
+ top: '-9999em'
2104
+ });
2105
  };
2106
  });
2107
 
2108
+ },{"../common":1,"../flowplayer":31,"bean":34}],17:[function(_dereq_,module,exports){
2109
  var flowplayer = _dereq_('../flowplayer')
2110
  , common = _dereq_('../common')
2111
  , bean = _dereq_('bean');
2152
  }