ravnur-player-public 3.4.4 → 3.4.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/dist/RavnurMediaPlayer.min.js +1 -1
  2. package/dist/cdn/RavnurMediaPlayer.min.js +1 -1
  3. package/package.json +10 -6
  4. package/.eslintignore +0 -7
  5. package/.eslintrc.js +0 -206
  6. package/.flowconfig +0 -3
  7. package/.vscode/extensions.json +0 -7
  8. package/.vscode/launch.json +0 -37
  9. package/.vscode/settings.json +0 -4
  10. package/README-Private.md +0 -54
  11. package/babel.config.js +0 -28
  12. package/bitbucket-pipelines.yml +0 -61
  13. package/cert.pem +0 -23
  14. package/demo/BaseM.mp4 +0 -0
  15. package/demo/HD.mp4 +0 -0
  16. package/demo/annotations.json +0 -50
  17. package/demo/annotations_ge.json +0 -50
  18. package/demo/base.mp3 +0 -0
  19. package/demo/cc_2125en.vtt +0 -4958
  20. package/demo/cc_en.vtt +0 -171
  21. package/demo/cc_ge.vtt +0 -178
  22. package/demo/chapters_en.vtt +0 -38
  23. package/demo/chapters_ge.vtt +0 -5
  24. package/demo/chapters_ge1.json +0 -23
  25. package/demo/hls/audio/stereo/en/128kbit.m3u8 +0 -912
  26. package/demo/hls/audio/stereo/none/128kbit.m3u8 +0 -912
  27. package/demo/hls/audio/surround/en/320kbit.m3u8 +0 -912
  28. package/demo/hls/playlist.m3u8 +0 -31
  29. package/demo/hls/video/10000kbit.m3u8 +0 -894
  30. package/demo/hls/video/1100kbit.m3u8 +0 -894
  31. package/demo/hls/video/1500kbit.m3u8 +0 -894
  32. package/demo/hls/video/250kbit.m3u8 +0 -894
  33. package/demo/hls/video/4000kbit.m3u8 +0 -894
  34. package/demo/hls/video/500kbit.m3u8 +0 -894
  35. package/demo/hls/video/6000kbit.m3u8 +0 -894
  36. package/demo/hls/video/800kbit.m3u8 +0 -894
  37. package/demo/hls.js +0 -5
  38. package/demo/hls.js.map +0 -1
  39. package/demo/hls.min.js +0 -2
  40. package/demo/hls.min.js.map +0 -1
  41. package/demo/playlist.m3u8 +0 -31
  42. package/demo/ravnur-flash-audio.swf +0 -0
  43. package/demo/ravnur-flash-video-hls.swf +0 -0
  44. package/demo/ravnur-flash-video.swf +0 -0
  45. package/demo/shaka/shaka-player.foo.debug.d.ts +0 -4532
  46. package/demo/shaka/shaka-player.foo.debug.externs.js +0 -3886
  47. package/demo/shaka/shaka-player.foo.debug.js +0 -1746
  48. package/demo/shaka/shaka-player.foo.debug.map +0 -8
  49. package/demo/shaka/wrapper.js +0 -7
  50. package/demo/test.html +0 -458
  51. package/jest.config.js +0 -4
  52. package/key.pem +0 -27
  53. package/lib/es5.js +0 -344
  54. package/lib/images/Spinner-small.gif +0 -0
  55. package/lib/images/close.png +0 -0
  56. package/lib/images/ic_check_box_black_24dp_1x.png +0 -0
  57. package/lib/images/ic_check_box_outline_blank_black_24dp_1x.png +0 -0
  58. package/lib/images/ic_chevron_left_white_24dp_1x.png +0 -0
  59. package/lib/images/ic_chevron_right_white_24dp_1x.png +0 -0
  60. package/lib/images/ic_closed_caption_white_24dp_1x.png +0 -0
  61. package/lib/images/ic_fast_forward_white_24dp_1x.png +0 -0
  62. package/lib/images/ic_fast_rewind_white_24dp_1x.png +0 -0
  63. package/lib/images/ic_fullscreen_exit_white_24dp_1x.png +0 -0
  64. package/lib/images/ic_fullscreen_white_24dp_1x.png +0 -0
  65. package/lib/images/ic_hd_white_24dp_1x.png +0 -0
  66. package/lib/images/ic_keyboard_arrow_left_black_24dp_1x.png +0 -0
  67. package/lib/images/ic_keyboard_arrow_right_black_24dp_1x.png +0 -0
  68. package/lib/images/ic_pause_white_24dp_1x.png +0 -0
  69. package/lib/images/ic_photo_white_24dp_1x.png +0 -0
  70. package/lib/images/ic_play_arrow_white_24dp_1x.png +0 -0
  71. package/lib/images/ic_refresh_white_24dp_1x.png +0 -0
  72. package/lib/images/ic_settings_white_24dp_1x.png +0 -0
  73. package/lib/images/ic_skip_next_white_24dp_1x.png +0 -0
  74. package/lib/images/ic_skip_previous_white_24dp_1x.png +0 -0
  75. package/lib/images/ic_toc_white_24dp_1x.png +0 -0
  76. package/lib/images/ic_volume_off_white_24dp_1x.png +0 -0
  77. package/lib/images/ic_volume_up_white_24dp_1x.png +0 -0
  78. package/lib/player4ie8.css +0 -225
  79. package/server.js +0 -29
  80. package/src/config/cc.js +0 -56
  81. package/src/config/i18n.js +0 -101
  82. package/src/config/options.js +0 -123
  83. package/src/config/playlist.js +0 -9
  84. package/src/config/source.js +0 -23
  85. package/src/config/statuses.js +0 -8
  86. package/src/config/styles.js +0 -16
  87. package/src/entity.js +0 -27
  88. package/src/events.js +0 -5
  89. package/src/extensions/annotations.js +0 -142
  90. package/src/extensions/audio-tarcks.js +0 -115
  91. package/src/extensions/backward.js +0 -45
  92. package/src/extensions/base.js +0 -73
  93. package/src/extensions/bottom-next.js +0 -50
  94. package/src/extensions/bottom-prev.js +0 -50
  95. package/src/extensions/buffering.js +0 -78
  96. package/src/extensions/c2pa.js +0 -350
  97. package/src/extensions/caption-search.js +0 -230
  98. package/src/extensions/cc.js +0 -874
  99. package/src/extensions/crawl.js +0 -118
  100. package/src/extensions/download.js +0 -411
  101. package/src/extensions/error.js +0 -47
  102. package/src/extensions/forward.js +0 -44
  103. package/src/extensions/fullscreen.js +0 -84
  104. package/src/extensions/help.js +0 -201
  105. package/src/extensions/helpers/FileSaver.js +0 -157
  106. package/src/extensions/helpers/clickOpener.js +0 -180
  107. package/src/extensions/helpers/opener.js +0 -30
  108. package/src/extensions/helpers/openerHeightChecker.js +0 -13
  109. package/src/extensions/helpers/popover.js +0 -33
  110. package/src/extensions/helpers/popoverPosition.js +0 -30
  111. package/src/extensions/helpers/scrollIntoView.js +0 -9
  112. package/src/extensions/helpers/storage.js +0 -20
  113. package/src/extensions/helpers/textContent.js +0 -6
  114. package/src/extensions/helpers/timeCodeToSeconds.js +0 -44
  115. package/src/extensions/helpers/transport.js +0 -43
  116. package/src/extensions/helpers/vtt-loader.js +0 -42
  117. package/src/extensions/index.js +0 -87
  118. package/src/extensions/live.js +0 -76
  119. package/src/extensions/mux.js +0 -57
  120. package/src/extensions/next-frame.js +0 -44
  121. package/src/extensions/next.js +0 -48
  122. package/src/extensions/placeholder.js +0 -241
  123. package/src/extensions/play.js +0 -102
  124. package/src/extensions/poster.js +0 -47
  125. package/src/extensions/prev-frame.js +0 -44
  126. package/src/extensions/prev.js +0 -48
  127. package/src/extensions/progress.js +0 -465
  128. package/src/extensions/resizer.js +0 -37
  129. package/src/extensions/settings.js +0 -367
  130. package/src/extensions/theater.js +0 -56
  131. package/src/extensions/title.js +0 -38
  132. package/src/extensions/toc.js +0 -334
  133. package/src/extensions/volume.js +0 -196
  134. package/src/flash/FlashPlugin.js +0 -301
  135. package/src/flash/MediaElement.js +0 -361
  136. package/src/flash/plugins.js +0 -32
  137. package/src/flash-detector.js +0 -66
  138. package/src/helpers/$t.js +0 -10
  139. package/src/helpers/binder.js +0 -11
  140. package/src/helpers/isAndroid.js +0 -5
  141. package/src/helpers/isBlackBerry.js +0 -5
  142. package/src/helpers/isCanvasSupported.js +0 -6
  143. package/src/helpers/isIE.js +0 -21
  144. package/src/helpers/isMobile.js +0 -10
  145. package/src/helpers/isWindows.js +0 -5
  146. package/src/helpers/isWindowsPhone.js +0 -5
  147. package/src/helpers/isiOS.js +0 -5
  148. package/src/html5media.js +0 -19
  149. package/src/index.js +0 -2
  150. package/src/logger.js +0 -31
  151. package/src/microevent.js +0 -65
  152. package/src/normalize-options.js +0 -139
  153. package/src/player.js +0 -864
  154. package/src/players/base.js +0 -209
  155. package/src/players/flash.js +0 -172
  156. package/src/players/hls.js +0 -278
  157. package/src/players/html.js +0 -205
  158. package/src/players/index.js +0 -59
  159. package/src/players/shaka.js +0 -219
  160. package/src/playlist.js +0 -362
  161. package/src/screenfull.js +0 -121
  162. package/src/state.js +0 -474
  163. package/src/static/es5.js +0 -344
  164. package/src/static/images/Spinner-small.gif +0 -0
  165. package/src/static/images/close.png +0 -0
  166. package/src/static/images/ic_check_box_black_24dp_1x.png +0 -0
  167. package/src/static/images/ic_check_box_outline_blank_black_24dp_1x.png +0 -0
  168. package/src/static/images/ic_chevron_left_white_24dp_1x.png +0 -0
  169. package/src/static/images/ic_chevron_right_white_24dp_1x.png +0 -0
  170. package/src/static/images/ic_closed_caption_white_24dp_1x.png +0 -0
  171. package/src/static/images/ic_fast_forward_white_24dp_1x.png +0 -0
  172. package/src/static/images/ic_fast_rewind_white_24dp_1x.png +0 -0
  173. package/src/static/images/ic_fullscreen_exit_white_24dp_1x.png +0 -0
  174. package/src/static/images/ic_fullscreen_white_24dp_1x.png +0 -0
  175. package/src/static/images/ic_hd_white_24dp_1x.png +0 -0
  176. package/src/static/images/ic_keyboard_arrow_left_black_24dp_1x.png +0 -0
  177. package/src/static/images/ic_keyboard_arrow_right_black_24dp_1x.png +0 -0
  178. package/src/static/images/ic_pause_white_24dp_1x.png +0 -0
  179. package/src/static/images/ic_play_arrow_white_24dp_1x.png +0 -0
  180. package/src/static/images/ic_refresh_white_24dp_1x.png +0 -0
  181. package/src/static/images/ic_settings_white_24dp_1x.png +0 -0
  182. package/src/static/images/ic_skip_next_white_24dp_1x.png +0 -0
  183. package/src/static/images/ic_skip_previous_white_24dp_1x.png +0 -0
  184. package/src/static/images/ic_toc_white_24dp_1x.png +0 -0
  185. package/src/static/images/ic_volume_off_white_24dp_1x.png +0 -0
  186. package/src/static/images/ic_volume_up_white_24dp_1x.png +0 -0
  187. package/src/static/player4ie8.css +0 -225
  188. package/src/styles/bplaylist.css.js +0 -124
  189. package/src/styles/index.js +0 -1966
  190. package/src/styles/playlist.css.js +0 -84
  191. package/src/styles/rplaylist.css.js +0 -98
  192. package/src/svgs.js +0 -111
  193. package/src/types/Logger.js +0 -10
  194. package/src/types/Options.js +0 -179
  195. package/src/types/Playlist.js +0 -3
  196. package/src/types/Source.js +0 -28
  197. package/src/types/State.js +0 -46
  198. package/src/types/Styles.js +0 -11
  199. package/src/types/TimeData.js +0 -8
  200. package/src/types/Translation.js +0 -69
  201. package/src/utils/absolutizeUrl.js +0 -9
  202. package/src/utils/addClass.js +0 -9
  203. package/src/utils/addEvent.js +0 -31
  204. package/src/utils/addProperty.js +0 -65
  205. package/src/utils/appendChild.js +0 -14
  206. package/src/utils/buff2hex.js +0 -5
  207. package/src/utils/contains.js +0 -33
  208. package/src/utils/createElement.js +0 -24
  209. package/src/utils/each.js +0 -34
  210. package/src/utils/escapeHTML.js +0 -8
  211. package/src/utils/existy.js +0 -4
  212. package/src/utils/extend.js +0 -17
  213. package/src/utils/filter.js +0 -16
  214. package/src/utils/find.js +0 -11
  215. package/src/utils/findIndex.js +0 -20
  216. package/src/utils/first.js +0 -5
  217. package/src/utils/get.js +0 -19
  218. package/src/utils/has.js +0 -5
  219. package/src/utils/hasClass.js +0 -6
  220. package/src/utils/head.js +0 -11
  221. package/src/utils/inRange.js +0 -16
  222. package/src/utils/index.js +0 -73
  223. package/src/utils/isArray.js +0 -4
  224. package/src/utils/isBoolean.js +0 -3
  225. package/src/utils/isElement.js +0 -7
  226. package/src/utils/isEmpty.js +0 -6
  227. package/src/utils/isEqual.js +0 -33
  228. package/src/utils/isEqualBuffer.js +0 -13
  229. package/src/utils/isFunction.js +0 -3
  230. package/src/utils/isNotEmpty.js +0 -5
  231. package/src/utils/isObject.js +0 -5
  232. package/src/utils/isString.js +0 -9
  233. package/src/utils/last.js +0 -4
  234. package/src/utils/map.js +0 -11
  235. package/src/utils/negate.js +0 -8
  236. package/src/utils/noop.js +0 -1
  237. package/src/utils/notExisty.js +0 -5
  238. package/src/utils/reduce.js +0 -8
  239. package/src/utils/remove.js +0 -7
  240. package/src/utils/removeClass.js +0 -8
  241. package/src/utils/removeEvent.js +0 -7
  242. package/src/utils/toArray.js +0 -7
  243. package/src/utils/toggleClass.js +0 -16
  244. package/src/utils/uidGenerator.js +0 -8
  245. package/src/utils/upperFirst.js +0 -4
  246. package/tests/extensions/__snapshots__/download.spec.js.snap +0 -226
  247. package/tests/extensions/__snapshots__/fullscreen.spec.js.snap +0 -30
  248. package/tests/extensions/__snapshots__/title.spec.js.snap +0 -16
  249. package/tests/extensions/download.spec.js +0 -111
  250. package/tests/extensions/fullscreen.spec.js +0 -56
  251. package/tests/extensions/title.spec.js +0 -35
  252. package/tests/mocks/assets/BaseM.mp4 +0 -0
  253. package/tests/mocks/assets/hls.min.js +0 -5
  254. package/tests/mocks/assets/styleMock.js +0 -1
  255. package/tests/mocks/base-player-options.js +0 -47
  256. package/tests/mocks/sources.js +0 -58
  257. package/tests/mocks/timedata/cc_en.vtt +0 -171
  258. package/tests/mocks/timedata/cc_ge.vtt +0 -178
  259. package/tests/utils/wait.js +0 -1
  260. package/webpack.config.js +0 -78
package/src/player.js DELETED
@@ -1,864 +0,0 @@
1
- // @flow
2
- import createPlayer from './players';
3
- import { isHLS } from './players';
4
- import screenfull from './screenfull';
5
- import extensions from './extensions';
6
- import appendStyles from './styles';
7
- import Playlist from './playlist';
8
- import Entity from './entity';
9
- import MicroEvent from './microevent';
10
-
11
- import hasFlashPlayer from './flash-detector';
12
-
13
- import BaseController from './players/base';
14
- import BaseExtension from './extensions/base';
15
-
16
- import createLogger from './logger';
17
- import normalizeOptions from './normalize-options';
18
-
19
- import $t from './helpers/$t';
20
- import binder from './helpers/binder';
21
-
22
- import {
23
- isElement, append, extend, each, createElement, existy, addClass, removeClass, toggleClass,
24
- contains, isArray, head, findIndex, get, hasClass
25
- } from './utils';
26
-
27
- import DEFAULT_OPTIONS from './config/options';
28
- import DEFAULT_STYLES from './config/styles';
29
- import { PLAYLIST_MODES, BOTTOM_MODE, RIGHT_MODE, AUTO_MODE } from './config/playlist';
30
-
31
- import isMobile from './helpers/isMobile';
32
- import isiOS from './helpers/isiOS';
33
- import isIE, { isIE8, isIE11 } from './helpers/isIE';
34
-
35
- import StateEntity from './state';
36
-
37
- import type { Player$Logger } from './types/Logger';
38
- import type { Player$Styles } from './types/Styles';
39
- import type { Player$Source } from './types/Source';
40
- import type { Player$PlaylistMode } from './types/Playlist';
41
- import type { Player$InputOptions, Player$CombineOptions } from './types/Options';
42
- import type { Player$State, Player$CCLocation, Player$CCFontSize } from './types/State';
43
- import type { Level } from './logger';
44
- import type { Player$CrawlOptions } from './config/options';
45
- import { getStoredData, storeData } from './extensions/helpers/storage';
46
- import CrawlExtension from './extensions/crawl';
47
-
48
- const CN = 'rplayer';
49
- const FULLSCREEN_CN = `${CN}--fullscreen`;
50
- const IPHONE_CN = `${CN}--iphone`;
51
- const MOBILE_CN = `${CN}--mobile`;
52
- const EL_BELOW_CC_75_CN = `${CN}--cc-75-below`;
53
- const EL_BELOW_CC_100_CN = `${CN}--cc-100-below`;
54
- const EL_BELOW_CC_125_CN = `${CN}--cc-125-below`;
55
- const EL_BELOW_CC_150_CN = `${CN}--cc-150-below`;
56
- const EL_BELOW_CC_200_CN = `${CN}--cc-200-below`;
57
-
58
- const INNER_CN = `${CN}__inner`;
59
- const INNER_PLAYING_CN = `${INNER_CN}--playing`;
60
- const INNER_ACTIVE_CN = `${INNER_CN}--active`;
61
- const INNER_HOVER_CN = `${INNER_CN}--hovering`;
62
- const INNER_LIGHT_CN = `${INNER_CN}--light`;
63
- const INNER_BELOW_CC_CN = `${INNER_CN}--cc-below`;
64
- const INNER_ACCESSABILITY_CN = `${INNER_CN}--accessibility`;
65
-
66
- const EXTENSIONS_CN = 'rmp-extensions';
67
- const EXTENSIONS_HIDDEN_CN = `${EXTENSIONS_CN}--hidden`;
68
- const EXTENSION_CRAWL_CN = 'rmp-ext-crawl';
69
- const EXTENSION_CRAWL_VISIBLE_CN = `${EXTENSION_CRAWL_CN}--exist`;
70
-
71
- const SAVE_PLAY_TIME_KEY = 'last-play-time';
72
- const SAVE_PLAY_TIME_LAST_TIME = 10; // 10 seconds
73
- const SAVE_PLAY_TIME_SKIP = 5; // 5 seconds
74
-
75
- let hasAddedStyles = false;
76
- let accessibility = false;
77
- let inactivityTimer = 0;
78
- let intervalId;
79
-
80
- const PLAYLIST_MODES_CN: { [key: Player$PlaylistMode]: string } = {
81
- [BOTTOM_MODE] : `${CN}--bottom-playlist`,
82
- [RIGHT_MODE] : `${CN}--right-playlist`
83
- };
84
-
85
- const TAB_KEY = 9;
86
-
87
- export default class Player extends Entity {
88
- controller: ?BaseController = null
89
- extensions: BaseExtension[] = []
90
- state: StateEntity
91
- _playlist: Player$Source[] = []
92
-
93
- originOptions: ?Player$InputOptions = null
94
- options: ?Player$CombineOptions = null
95
- activeSourceId: string;
96
-
97
- $el: HTMLElement
98
- $inner: HTMLElement
99
- $extensionsWrapper: ?HTMLElement = null
100
-
101
- playlistController: ?Playlist = null
102
-
103
- _timerId: ?TimeoutID = null
104
- _isOpenPopup: boolean = false
105
- _clipStopInterval: ?IntervalID = null
106
- _isPlaylist: boolean = false
107
-
108
- constructor(el: HTMLElement, styles?: $Shape<Player$Styles> = {}, logger?: Player$Logger = createLogger()) {
109
- super(new MicroEvent(), logger);
110
-
111
- if (!hasAddedStyles) {
112
- styles = extend({}, DEFAULT_STYLES, styles);
113
- appendStyles(styles, isIE8() ? el.getBoundingClientRect() : null);
114
- hasAddedStyles = true;
115
- }
116
-
117
- const parent = el;
118
- this.$el = createElement('div', { class: CN }, parent);
119
-
120
- toggleClass(this.$el, IPHONE_CN, isiOS());
121
- toggleClass(this.$el, MOBILE_CN, isMobile());
122
-
123
- this.$inner = createElement('div', { class: INNER_CN }, this.$el);
124
-
125
- binder(this, [ 'onStateChanged', 'onFullScreenChanged', 'disappearExtensions',
126
- 'appearExtensions', '_renderPlayer', 'onPlay', 'onPause', 'onMouseMove', 'onClick',
127
- '_disappearExtensionsDelayed', '_appearExtensionsImmediately', 'onOpenPopup', 'onClosePopup',
128
- 'onPlayClicked', 'onChangePlaylistMode', 'onMouseEnter', 'onMouseLeave', 'onKeydown', 'onMobileTouch',
129
- '_heartbeatExtension', '_handleQualityChange', 'onTimeUpdate', '_handleLastPlayTime']);
130
-
131
- this.bus.on('statechanged', this.onStateChanged);
132
- this.bus.on('pause', this.onPause);
133
- this.bus.on('timeupdate', this.onTimeUpdate);
134
- this.bus.on('ended', this.onPause);
135
- this.bus.on('play', this.onPlay);
136
- this.bus.on('changesource', this._renderPlayer );
137
- this.bus.on('showpopup', this.onOpenPopup);
138
- this.bus.on('hidepopup', this.onClosePopup);
139
- this.bus.on('handle-play-clicked', this.onPlayClicked);
140
- this.bus.on('changeplaylistmode', this.onChangePlaylistMode);
141
- this.bus.on('heartbeatextensions', this._heartbeatExtension);
142
- this.bus.on('manualquality', this._handleQualityChange);
143
-
144
- this.state = new StateEntity(this.bus, logger);
145
-
146
- if ( isMobile() ) {
147
- this.bus.on('mobiletouch', this.onMobileTouch);
148
- } else {
149
- this.addEvent(this.$el, 'mouseleave', this.onMouseLeave);
150
- this.addEvent(this.$el, 'mouseenter', this.onMouseEnter);
151
- this.addEvent(this.$el, 'mousemove', this.onMouseMove);
152
- this.addEvent(this.$el, 'keydown', this.onKeydown);
153
- this.addEvent(this.$el, 'click', this.onClick);
154
- }
155
-
156
- if (screenfull.enabled) {
157
- this.$el.addEventListener('webkitfullscreenchange', this.onFullScreenChanged);
158
- this.$el.addEventListener('fullscreenchange', this.onFullScreenChanged);
159
- document.addEventListener('mozfullscreenchange', this.onFullScreenChanged);
160
- document.addEventListener('MSFullscreenChange', this.onFullScreenChanged);
161
- }
162
- }
163
-
164
- onMouseLeave() {
165
- removeClass(this.$inner, INNER_HOVER_CN);
166
- this.disappearExtensions();
167
- }
168
-
169
- onMouseEnter() {
170
- addClass(this.$inner, INNER_HOVER_CN);
171
- this.appearExtensions();
172
- }
173
-
174
- onKeydown(e: KeyboardEvent) {
175
- if (!accessibility) return;
176
- clearInterval(intervalId);
177
- inactivityTimer = 0;
178
-
179
- const keyCode = e.keyCode;
180
-
181
- if (keyCode === TAB_KEY) {
182
- this.appearExtensions();
183
- }
184
-
185
- intervalId = setInterval(() => {
186
- inactivityTimer++;
187
- if (inactivityTimer > 5) {
188
- inactivityTimer = 0;
189
- this.disappearExtensions();
190
- clearInterval(intervalId);
191
- }
192
- }, 1000);
193
- }
194
-
195
- onPlay() {
196
- addClass(this.$inner, INNER_PLAYING_CN);
197
- this.onMouseMove();
198
- }
199
-
200
- onPause() {
201
- if (!this.options.playLoop) {
202
- removeClass(this.$inner, INNER_PLAYING_CN);
203
- this.appearExtensions();
204
- }
205
- }
206
-
207
- onPlayClicked() {
208
- removeClass(this.$inner, INNER_LIGHT_CN);
209
- }
210
-
211
- onTimeUpdate() {
212
- const { activeSourceId, controller } = this;
213
- const { savePlayTime } = this.originOptions;
214
- const ignoreSaveTime = controller.getDuration() <= (SAVE_PLAY_TIME_LAST_TIME + SAVE_PLAY_TIME_SKIP);
215
- let time = controller.getCurrentTime();
216
-
217
- if (time < SAVE_PLAY_TIME_SKIP || ignoreSaveTime) {
218
- return;
219
- }
220
-
221
- if (!savePlayTime || !activeSourceId) {
222
- return;
223
- }
224
-
225
- let existed = getStoredData(SAVE_PLAY_TIME_KEY) || '{}';
226
- existed = JSON.parse(existed);
227
-
228
- if (!existed.expires) {
229
- let expires = new Date();
230
- existed.expires = new Date().setMonth(expires.getMonth() + 1);
231
- }
232
-
233
- if (new Date().getTime() > existed.expires) {
234
- existed = {};
235
- existed.expires = new Date().setMonth(new Date().getMonth() + 1);
236
- }
237
-
238
- const lastAvailableTime = controller.getDuration() - SAVE_PLAY_TIME_LAST_TIME;
239
- time = time <= lastAvailableTime ? time : lastAvailableTime;
240
-
241
- existed[activeSourceId] = time;
242
-
243
- storeData(SAVE_PLAY_TIME_KEY, JSON.stringify(existed));
244
- }
245
-
246
- isShownExtensions() {
247
- const { $extensionsWrapper } = this;
248
-
249
- if (!$extensionsWrapper) {
250
- return false;
251
- }
252
-
253
- let res = !hasClass(this.$inner, EXTENSIONS_HIDDEN_CN);
254
- res = res || hasClass(this.$inner, INNER_LIGHT_CN);
255
- // res = res || hasClass(this.$inner, INNER_HOVER_CN);
256
- return res;
257
- }
258
-
259
- onMobileTouch() {
260
- const { controller } = this;
261
- if ( controller && this.isShownExtensions() ) {
262
- if ( controller.isPaused() ) {
263
- controller.play();
264
- } else {
265
- controller.pause();
266
- }
267
- }
268
- this._heartbeatExtension();
269
- }
270
-
271
- onMouseMove() {
272
- this._heartbeatExtension();
273
- }
274
-
275
- onClick() {
276
- this._heartbeatExtension();
277
- }
278
-
279
- _heartbeatExtension() {
280
- this._appearExtensionsImmediately();
281
-
282
- if (!this._isOpenPopup) {
283
- this._disappearExtensionsDelayed();
284
- }
285
- }
286
-
287
- onOpenPopup() {
288
- this._isOpenPopup = true;
289
- addClass(this.$inner, INNER_ACTIVE_CN);
290
- this._appearExtensionsImmediately();
291
- }
292
-
293
- onClosePopup() {
294
- this._isOpenPopup = false;
295
- removeClass(this.$inner, INNER_ACTIVE_CN);
296
- this._disappearExtensionsDelayed();
297
- }
298
-
299
- _appearExtensionsImmediately() {
300
- this.appearExtensions();
301
- if (this._timerId) {
302
- clearTimeout(this._timerId);
303
- }
304
- }
305
-
306
- _disappearExtensionsDelayed() {
307
- const { originOptions } = this;
308
- if (!originOptions || originOptions.alwaysShowExtensions) {
309
- return;
310
- }
311
- this._timerId = setTimeout(this.disappearExtensions, originOptions.extensionsVisibilityTimeout);
312
- }
313
-
314
- _getParentElementForController(): ?HTMLElement {
315
- const { controller } = this;
316
- if (!controller) {
317
- return null;
318
- }
319
-
320
- const $el = controller.getElement();
321
- if (!$el) {
322
- return null;
323
- }
324
-
325
- const parent = $el.parentNode;
326
- if (parent && parent instanceof HTMLElement) {
327
- return parent;
328
- }
329
-
330
- return null;
331
- }
332
-
333
- changeFullScreenMode() {
334
- const parent = this._getParentElementForController();
335
- if (!parent && !isiOS()) {
336
- return;
337
- }
338
-
339
- const isFullScreenMode = this.state.isFullScreen();
340
-
341
- // if ( isFullScreenMode) {
342
- // if (!screenfull.enabled) {
343
- // _setFullSize(parent);
344
- // }
345
-
346
- // return;
347
- // }
348
-
349
- this.$inner.style.width = '';
350
- this.$inner.style.height = '';
351
-
352
- if (screenfull.enabled) {
353
- if (isFullScreenMode) {
354
- screenfull.request(this.$el);
355
- } else {
356
- screenfull.exit();
357
- }
358
- } else if (isiOS() && this.controller) {
359
- // $FlowFixMe
360
- this.controller.getElement().webkitEnterFullscreen();
361
- this.bus.emit('fullscreenchanging', false);
362
- } else {
363
- const parent = this.$el.parentNode;
364
- if (!parent || !( parent instanceof HTMLElement )) {
365
- return;
366
- }
367
-
368
- if (isFullScreenMode) {
369
- addClass(parent, FULLSCREEN_CN);
370
- _setFullSize(parent);
371
- } else {
372
- removeClass(parent, FULLSCREEN_CN);
373
- _clearSize(parent);
374
- }
375
- this.bus.emit('fullscreenchanged', isFullScreenMode);
376
- }
377
- }
378
-
379
- onStateChanged(state: Player$State, old: Player$State) {
380
- if (state.isFullScreen !== old.isFullScreen) {
381
- this.changeFullScreenMode();
382
- }
383
- if ( state.cc.fontSize !== old.cc.fontSize ||
384
- state.cc.location !== old.cc.location ||
385
- state.cc.lang !== old.cc.lang
386
- ) {
387
-
388
- const lang = state.cc.lang;
389
- if (lang) {
390
- this.changeLayout(lang, state.cc.fontSize, state.cc.location);
391
- }
392
- }
393
- }
394
-
395
- onFullScreenChanged() {
396
- const isFullScreen = screenfull.isFullscreen;
397
- this.bus.emit('fullscreenchanging', isFullScreen);
398
- const parent = this.$el.parentNode;
399
- if (!parent || !( parent instanceof HTMLElement )) {
400
- return;
401
- }
402
-
403
- toggleClass(parent, FULLSCREEN_CN, screenfull.isFullscreen);
404
- }
405
-
406
- changeLayout(lang: string, fontSize: Player$CCFontSize, location: Player$CCLocation) {
407
- const isBelowtMode = lang && location === 'below';
408
- toggleClass(this.$inner, INNER_BELOW_CC_CN, isBelowtMode);
409
- toggleClass(this.$el, EL_BELOW_CC_75_CN, isBelowtMode && fontSize === '75%');
410
- toggleClass(this.$el, EL_BELOW_CC_100_CN, isBelowtMode && fontSize === '100%');
411
- toggleClass(this.$el, EL_BELOW_CC_125_CN, isBelowtMode && fontSize === '125%');
412
- toggleClass(this.$el, EL_BELOW_CC_150_CN, isBelowtMode && fontSize === '150%');
413
- toggleClass(this.$el, EL_BELOW_CC_200_CN, isBelowtMode && fontSize === '200%');
414
- }
415
-
416
- _detectPlaylistMode(): Player$PlaylistMode {
417
- const { originOptions } = this;
418
- if (!originOptions) {
419
- return 'auto';
420
- }
421
- let mode = originOptions.playlistmode;
422
- mode = contains(PLAYLIST_MODES, mode) ? mode : head(PLAYLIST_MODES);
423
- if ( mode === AUTO_MODE ) {
424
- mode = isMobile() ? BOTTOM_MODE : RIGHT_MODE;
425
- }
426
- return mode;
427
- }
428
-
429
- setup(playlist: Player$Source | Player$Source[], options?: $Shape<Player$InputOptions> = {}) {
430
- // $FlowFixMe
431
- const level: Level = existy(options.loggerLevel) ? options.loggerLevel : DEFAULT_OPTIONS.loggerLevel;
432
- const logger = options.logger || createLogger(level);
433
- const o = { bus: this.bus, logger: options.logger || logger };
434
- const originOptions: Player$InputOptions = extend(o, DEFAULT_OPTIONS, options);
435
-
436
- accessibility = options.accessibility;
437
-
438
- // Accessability: always keep controls visible
439
- if (accessibility) {
440
- addClass(this.$inner, INNER_ACCESSABILITY_CN);
441
- }
442
-
443
- this.originOptions = originOptions;
444
-
445
- this._isPlaylist = isArray(playlist);
446
- this._playlist = [].concat(playlist);
447
-
448
- if ( !this._playlist.length ) {
449
- setTimeout(() => {
450
- const parent = this.$el.parentNode;
451
- if (parent && parent instanceof HTMLElement) {
452
- parent.style.position = 'relative';
453
- parent.style.border = '1px solid grey';
454
- }
455
- this.destroy();
456
- const h1 = createElement('i', { class: 'rmp-no-video' }, parent);
457
- h1.textContent = $t(originOptions.i18n, 'no-video');
458
- }, 5);
459
- return;
460
- }
461
-
462
- if (this._isPlaylist) {
463
- const mode = this._detectPlaylistMode();
464
- this.onChangePlaylistMode(mode);
465
- const label = $t(originOptions.i18n, 'playlist-count-of');
466
- const title = originOptions.playlistitle;
467
- const forcePoint = originOptions.playlistforcepoint;
468
- const loop = originOptions.playLoop;
469
- const opts = { mode, bus: this.bus, title, label, forcePoint, logger, loop };
470
- this.playlistController = new Playlist(this._playlist, opts);
471
-
472
- if (!originOptions.hideplaylist) {
473
- append(this.$el, this.playlistController.getElement());
474
- }
475
-
476
- if (originOptions.plalistAutoGoNext) {
477
- this.bus.on('ended', () => {
478
- this.bus.emit('nexttrack');
479
- this._playOnLoad();
480
- });
481
- }
482
- }
483
-
484
- if (!this._isPlaylist || this.originOptions.hideplaylist) {
485
- this.bus.emit('changesource', head(this._playlist));
486
- }
487
-
488
- this.bus.on('*', e => originOptions.logger.debug(e) );
489
- const state = this.state;
490
- const mode = state.getCCLang() && state.getCCLocation() || 'over';
491
- this._afterSetup();
492
-
493
- setTimeout(() => {
494
- this.bus.emit('cclayoutchange', { mode, fontSize: state.getCCFontSize() });
495
- });
496
- }
497
-
498
- onChangePlaylistMode(mode: Player$PlaylistMode) {
499
- if (!this.originOptions.hideplaylist) {
500
- each(PLAYLIST_MODES_CN, (cls, key) => toggleClass(this.$el, cls, key === mode) );
501
- }
502
- }
503
-
504
- _runOnce(fnc: () => void) {
505
- this.bus.once('canplaythrough', () => setTimeout(fnc));
506
- this.bus.once('loadedmetadata', () => setTimeout(fnc));
507
- }
508
-
509
- _playOnLoad() {
510
- this._runOnce(() => {
511
- const { controller } = this;
512
- if (controller) {
513
- controller.play();
514
- }
515
- });
516
- }
517
-
518
- _afterSetup() {
519
- const { controller, originOptions } = this;
520
- if (!controller || !originOptions) {
521
- return;
522
- }
523
- const { autoStart, startTime, endTime } = originOptions;
524
-
525
- if (autoStart) {
526
- this._playOnLoad();
527
- }
528
-
529
- if (startTime || endTime) {
530
- this.playPart(startTime, endTime, true);
531
- }
532
- }
533
-
534
- _handleLastPlayTime() {
535
- const { savePlayTime, startTime } = this.originOptions;
536
- const { activeSourceId } = this;
537
-
538
- if (startTime || !savePlayTime || !activeSourceId) {
539
- return;
540
- }
541
-
542
- let existed = getStoredData(SAVE_PLAY_TIME_KEY);
543
-
544
- if (!existed) {
545
- return;
546
- }
547
-
548
- existed = JSON.parse(existed);
549
-
550
- const storedTime = existed[activeSourceId];
551
-
552
- if (storedTime) {
553
- this.playPart(storedTime, undefined, true);
554
- }
555
- }
556
-
557
- playPart(from: ?number, to: ?number, lazy: boolean = false) {
558
- const { controller } = this;
559
- if (!controller) {
560
- return;
561
- }
562
-
563
- if (typeof from === 'number') {
564
- if (lazy) {
565
- const f = from;
566
- this._runOnce(() => controller.setCurrentTime(f));
567
- } else {
568
- controller.setCurrentTime(from);
569
- }
570
- }
571
-
572
- if (typeof to === 'number') {
573
- const _listener = () => {
574
- const currentTime = controller.getCurrentTime();
575
- if (typeof currentTime === 'number' && typeof to === 'number' && currentTime > to) {
576
- controller.pause();
577
- this.bus.off('timeupdate', _listener);
578
- }
579
- };
580
- this.bus.on('timeupdate', _listener);
581
- }
582
-
583
- if (!lazy) {
584
- controller.play();
585
- }
586
- }
587
-
588
- // eslint-disable-next-line complexity
589
- _renderPlayer(source: Player$Source) {
590
- if ( !source.src ) {
591
- throw new Error('Incorrent load\'s options.');
592
- }
593
-
594
- this.activeSourceId = source.id;
595
-
596
- const lang = this.state.getCCLang();
597
- if (lang) {
598
- this.changeLayout(lang, this.state.getCCFontSize(), this.state.getCCLocation());
599
- }
600
-
601
- let playlistMoverOptions = {};
602
- if (this._isPlaylist && !this.originOptions.hideplaylist) {
603
- const idx = findIndex(this._playlist, source);
604
- const next = this._playlist[idx + 1] || null;
605
- const prev = this._playlist[idx - 1] || null;
606
- playlistMoverOptions = {
607
- showNext: existy(next),
608
- nextTrackThumbnails: get(next, 'poster', ''),
609
- nextTrackTitle: get(next, 'title', ''),
610
-
611
- showPrev: existy(prev),
612
- prevTrackThumbnails: get(prev, 'poster', ''),
613
- prevTrackTitle: get(prev, 'title', '')
614
- };
615
- }
616
- const options = normalizeOptions(this.originOptions || {}, extend({}, source, playlistMoverOptions));
617
- this.options = options;
618
-
619
- if ( this.controller ) {
620
- this.controller.destroy();
621
- }
622
-
623
- this.destroyExtensions();
624
-
625
- if ( isHLS(options.type) && !Player.canPlayHLS ) {
626
- const parent = this.$el.parentNode;
627
- if (parent && parent instanceof HTMLElement) {
628
- parent.style.position = 'relative';
629
- parent.style.border = '1px solid grey';
630
- }
631
- this.destroy();
632
- const h1 = createElement('i', { class: 'rmp-no-video' }, parent);
633
- if (this.originOptions) {
634
- h1.textContent = $t(this.originOptions.i18n || {}, 'no-flash');
635
- }
636
- return;
637
- }
638
-
639
- this._beforeRender(options);
640
-
641
- const controller = createPlayer(options, this.state);
642
- this.controller = controller;
643
- append(this.$inner, controller.$el);
644
-
645
- controller.load(options);
646
-
647
- this._handleLastPlayTime();
648
-
649
- if (options.useNativeControls) {
650
- return;
651
- }
652
- removeClass(this.$inner, INNER_PLAYING_CN);
653
- addClass(this.$inner, INNER_LIGHT_CN);
654
-
655
- if (options.showCrawl) {
656
- addClass(this.$inner, EXTENSION_CRAWL_VISIBLE_CN);
657
- }
658
-
659
- const $extensionsWrapper = createElement('div', { class: EXTENSIONS_CN }, this.$inner);
660
- this.$extensionsWrapper = $extensionsWrapper;
661
-
662
- each(extensions(controller, this.state, options), ext => {
663
- try {
664
- const element = ext.getElement();
665
- if ( element ) {
666
- append($extensionsWrapper, element);
667
- ext.addEvent(element, 'dblclick', _stop);
668
- }
669
-
670
- const outer = ext.getOuter();
671
- if ( outer ) {
672
- append(this.$inner, outer, $extensionsWrapper);
673
- }
674
- this.extensions.push(ext);
675
- } catch (e) {
676
- options.logger.error(e);
677
- }
678
- });
679
- }
680
-
681
- _beforeRender({ clip, timecode }: $Shape<Player$CombineOptions>) {
682
- if (this._clipStopInterval) {
683
- clearInterval(this._clipStopInterval);
684
- }
685
- if ( clip ) {
686
- const [ start, end ] = clip;
687
- if (start) {
688
- this._runOnce(() => {
689
- if (this.controller) {
690
- this.controller.setCurrentTime(start);
691
- }
692
- });
693
- }
694
-
695
- if ( end ) {
696
- this._clipStopInterval = setInterval(() => {
697
- const controller = this.controller;
698
- if ( !controller || controller.isPaused() ) {
699
- return;
700
- }
701
- const currentTime = controller.getCurrentTime();
702
- if (currentTime > end + timecode) {
703
- controller.pause();
704
- setTimeout(() => this.bus.emit('ended'));
705
- }
706
- }, 26);
707
- }
708
- }
709
- }
710
-
711
- _handleQualityChange(quality: mixed) {
712
- if (this.originOptions) {
713
- // $FlowFixMe
714
- this.originOptions.qualityLevel = quality;
715
- }
716
- }
717
-
718
- refreshCrawlExtension(crawl: Player$CrawlOptions, visibility: boolean = true) {
719
- this.originOptions.logger.debug('crawl:extensions:refreshing');
720
-
721
- if (!crawl) {
722
- throw new Error('Crawl options not found');
723
- }
724
-
725
- const crawlExtension = this.extensions.find(ext => '$crawl' in ext);
726
-
727
- if (!crawlExtension) {
728
- this.originOptions.logger.debug('crawl:extensions:creating');
729
-
730
- const options = extend({}, this.originOptions, { crawl });
731
- const extension = new CrawlExtension(this.controller, this.state, options);
732
- const outer = extension.getOuter();
733
-
734
- if ( outer ) {
735
- append(this.$inner, outer, this.$extensionsWrapper);
736
- }
737
-
738
- this.extensions.push(extension);
739
-
740
- return;
741
- }
742
-
743
- this.logger.debug('crawl:extensions:refreshing');
744
-
745
- // $FlowFixMe
746
- crawlExtension.refresh(crawl, visibility);
747
- }
748
-
749
- destroyExtensions() {
750
- each(this.extensions, ext => ext.destroy());
751
- this.extensions.length = 0;
752
-
753
- const { $extensionsWrapper } = this;
754
-
755
- if ( $extensionsWrapper && isElement($extensionsWrapper) ) {
756
- const parent = $extensionsWrapper.parentNode;
757
- if (parent) {
758
- parent.removeChild($extensionsWrapper);
759
- }
760
- }
761
- }
762
-
763
- disappearExtensions() {
764
- const { originOptions, $inner } = this;
765
-
766
- if (!originOptions || !$inner) {
767
- return;
768
- }
769
-
770
- const showExts = originOptions.alwaysShowExtensions;
771
- if (this.controller && (showExts || this._isOpenPopup || this.controller.isPaused())) {
772
- return;
773
- }
774
- addClass($inner, EXTENSIONS_HIDDEN_CN);
775
- }
776
-
777
- appearExtensions() {
778
- removeClass(this.$inner, EXTENSIONS_HIDDEN_CN);
779
- }
780
-
781
- on(event: string, fnc: (...args: Array<mixed>) => mixed) {
782
- this.bus.on(event, fnc);
783
- }
784
-
785
- off(event: string, fnc: (...args: Array<mixed>) => mixed) {
786
- this.bus.off(event, fnc);
787
- }
788
-
789
- destroy() {
790
- super.destroy();
791
- this.bus.destroy();
792
-
793
- if (this._clipStopInterval) {
794
- clearInterval(this._clipStopInterval);
795
- }
796
-
797
- this.destroyExtensions();
798
- const { controller } = this;
799
-
800
- if (controller) {
801
- controller.pause();
802
- controller.destroy();
803
- }
804
- this.controller = null;
805
-
806
- if (screenfull.enabled) {
807
- this.$el.removeEventListener('webkitfullscreenchange', this.onFullScreenChanged);
808
- this.$el.removeEventListener('fullscreenchange', this.onFullScreenChanged);
809
- document.removeEventListener('mozfullscreenchange', this.onFullScreenChanged);
810
- document.removeEventListener('MSFullscreenChange', this.onFullScreenChanged);
811
- }
812
-
813
- if (this.playlistController) {
814
- this.playlistController.destroy();
815
- }
816
-
817
- const parent = this.$el.parentNode;
818
- this.$el.removeChild(this.$inner);
819
-
820
- if (parent) {
821
- parent.removeChild(this.$el);
822
- }
823
- }
824
-
825
- static addStyles(styles: $Shape<Player$Styles>) {
826
- appendStyles(extend({}, DEFAULT_STYLES, styles));
827
- }
828
-
829
- static canPlayHLS = !(isIE() || isIE11()) || hasFlashPlayer
830
- }
831
-
832
- function _windowWidth() {
833
- const de = document.documentElement;
834
- return de ? de.clientWidth : null;
835
- }
836
-
837
- function _windowHeight() {
838
- const de = document.documentElement;
839
- return de ? de.clientHeight : null;
840
- }
841
-
842
- /* set correct width/height for fullsize mode */
843
- function _setFullSize(el: HTMLElement) {
844
- const w = _windowWidth();
845
- const h = _windowHeight();
846
- if (typeof w === 'number' && typeof h === 'number') {
847
- _normalizeSize(el, w, h);
848
- }
849
- }
850
-
851
- /* set correct width/height */
852
- function _normalizeSize(el: HTMLElement, w: number, h: number) {
853
- el.style.width = `${w}px`;
854
- el.style.height = `${h}px`;
855
- }
856
-
857
- function _clearSize(el: HTMLElement) {
858
- el.style.width = '';
859
- el.style.height = '';
860
- }
861
-
862
- function _stop(e: Event) {
863
- e.stopPropagation();
864
- }