UNPKG

11.3 kBJavaScriptView Raw
1'use strict';
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6
7var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
8
9var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
10
11var _react = require('react');
12
13var _react2 = _interopRequireDefault(_react);
14
15var _props2 = require('./props');
16
17var _utils = require('./utils');
18
19function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
20
21function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
22
23function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
24
25function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
26
27var SEEK_ON_PLAY_EXPIRY = 5000;
28
29var Player = function (_Component) {
30 _inherits(Player, _Component);
31
32 function Player() {
33 var _ref;
34
35 var _temp, _this, _ret;
36
37 _classCallCheck(this, Player);
38
39 for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
40 args[_key] = arguments[_key];
41 }
42
43 return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = Player.__proto__ || Object.getPrototypeOf(Player)).call.apply(_ref, [this].concat(args))), _this), _this.mounted = false, _this.isReady = false, _this.isPlaying = false, _this.isLoading = true, _this.loadOnReady = null, _this.startOnPlay = true, _this.seekOnPlay = null, _this.onDurationCalled = false, _this.getInternalPlayer = function (key) {
44 if (!_this.player) return null;
45 return _this.player[key];
46 }, _this.progress = function () {
47 if (_this.props.url && _this.player && _this.isReady) {
48 var playedSeconds = _this.getCurrentTime() || 0;
49 var loadedSeconds = _this.getSecondsLoaded();
50 var duration = _this.getDuration();
51 if (duration) {
52 var progress = {
53 playedSeconds: playedSeconds,
54 played: playedSeconds / duration
55 };
56 if (loadedSeconds !== null) {
57 progress.loadedSeconds = loadedSeconds;
58 progress.loaded = loadedSeconds / duration;
59 }
60 // Only call onProgress if values have changed
61 if (progress.played !== _this.prevPlayed || progress.loaded !== _this.prevLoaded) {
62 _this.props.onProgress(progress);
63 }
64 _this.prevPlayed = progress.played;
65 _this.prevLoaded = progress.loaded;
66 }
67 }
68 _this.progressTimeout = setTimeout(_this.progress, _this.props.progressFrequency || _this.props.progressInterval);
69 }, _this.onReady = function () {
70 if (!_this.mounted) return;
71 _this.isReady = true;
72 _this.isLoading = false;
73 var _this$props = _this.props,
74 onReady = _this$props.onReady,
75 playing = _this$props.playing,
76 volume = _this$props.volume,
77 muted = _this$props.muted;
78
79 onReady();
80 if (!muted && volume !== null) {
81 _this.player.setVolume(volume);
82 }
83 if (_this.loadOnReady) {
84 _this.player.load(_this.loadOnReady, true);
85 _this.loadOnReady = null;
86 } else if (playing) {
87 _this.player.play();
88 }
89 _this.onDurationCheck();
90 }, _this.onPlay = function () {
91 _this.isPlaying = true;
92 _this.isLoading = false;
93 var _this$props2 = _this.props,
94 onStart = _this$props2.onStart,
95 onPlay = _this$props2.onPlay,
96 playbackRate = _this$props2.playbackRate;
97
98 if (_this.startOnPlay) {
99 if (_this.player.setPlaybackRate) {
100 _this.player.setPlaybackRate(playbackRate);
101 }
102 onStart();
103 _this.startOnPlay = false;
104 }
105 onPlay();
106 if (_this.seekOnPlay) {
107 _this.seekTo(_this.seekOnPlay);
108 _this.seekOnPlay = null;
109 }
110 _this.onDurationCheck();
111 }, _this.onPause = function (e) {
112 _this.isPlaying = false;
113 if (!_this.isLoading) {
114 _this.props.onPause(e);
115 }
116 }, _this.onEnded = function () {
117 var _this$props3 = _this.props,
118 activePlayer = _this$props3.activePlayer,
119 loop = _this$props3.loop,
120 onEnded = _this$props3.onEnded;
121
122 if (activePlayer.loopOnEnded && loop) {
123 _this.seekTo(0);
124 }
125 if (!loop) {
126 _this.isPlaying = false;
127 onEnded();
128 }
129 }, _this.onError = function (e) {
130 _this.isLoading = false;
131 _this.props.onError(e);
132 }, _this.onDurationCheck = function () {
133 clearTimeout(_this.durationCheckTimeout);
134 var duration = _this.getDuration();
135 if (duration) {
136 if (!_this.onDurationCalled) {
137 _this.props.onDuration(duration);
138 _this.onDurationCalled = true;
139 }
140 } else {
141 _this.durationCheckTimeout = setTimeout(_this.onDurationCheck, 100);
142 }
143 }, _this.onLoaded = function () {
144 // Sometimes we know loading has stopped but onReady/onPlay are never called
145 // so this provides a way for players to avoid getting stuck
146 _this.isLoading = false;
147 }, _this.ref = function (player) {
148 if (player) {
149 _this.player = player;
150 }
151 }, _temp), _possibleConstructorReturn(_this, _ret);
152 } // Track playing state internally to prevent bugs
153 // Use isLoading to prevent onPause when switching URL
154
155
156 _createClass(Player, [{
157 key: 'componentDidMount',
158 value: function componentDidMount() {
159 this.mounted = true;
160 this.player.load(this.props.url);
161 this.progress();
162 }
163 }, {
164 key: 'componentWillUnmount',
165 value: function componentWillUnmount() {
166 clearTimeout(this.progressTimeout);
167 clearTimeout(this.durationCheckTimeout);
168 if (this.isReady) {
169 this.player.stop();
170 }
171 if (this.player.disablePIP) {
172 this.player.disablePIP();
173 }
174 this.mounted = false;
175 }
176 }, {
177 key: 'componentWillReceiveProps',
178 value: function componentWillReceiveProps(nextProps) {
179 var _this2 = this;
180
181 // Invoke player methods based on incoming props
182 var _props = this.props,
183 url = _props.url,
184 playing = _props.playing,
185 volume = _props.volume,
186 muted = _props.muted,
187 playbackRate = _props.playbackRate,
188 pip = _props.pip,
189 loop = _props.loop;
190
191 if (!(0, _utils.isEqual)(url, nextProps.url)) {
192 if (this.isLoading) {
193 console.warn('ReactPlayer: the attempt to load ' + nextProps.url + ' is being deferred until the player has loaded');
194 this.loadOnReady = nextProps.url;
195 return;
196 }
197 this.isLoading = true;
198 this.startOnPlay = true;
199 this.onDurationCalled = false;
200 this.player.load(nextProps.url, this.isReady);
201 }
202 if (!playing && nextProps.playing && !this.isPlaying) {
203 this.player.play();
204 }
205 if (playing && !nextProps.playing && this.isPlaying) {
206 this.player.pause();
207 }
208 if (!pip && nextProps.pip && this.player.enablePIP) {
209 this.player.enablePIP();
210 } else if (pip && !nextProps.pip && this.player.disablePIP) {
211 this.player.disablePIP();
212 }
213 if (volume !== nextProps.volume && nextProps.volume !== null) {
214 this.player.setVolume(nextProps.volume);
215 }
216 if (muted !== nextProps.muted) {
217 if (nextProps.muted) {
218 this.player.mute();
219 } else {
220 this.player.unmute();
221 if (nextProps.volume !== null) {
222 // Set volume next tick to fix a bug with DailyMotion
223 setTimeout(function () {
224 return _this2.player.setVolume(nextProps.volume);
225 });
226 }
227 }
228 }
229 if (playbackRate !== nextProps.playbackRate && this.player.setPlaybackRate) {
230 this.player.setPlaybackRate(nextProps.playbackRate);
231 }
232 if (loop !== nextProps.loop && this.player.setLoop) {
233 this.player.setLoop(nextProps.loop);
234 }
235 }
236 }, {
237 key: 'getDuration',
238 value: function getDuration() {
239 if (!this.isReady) return null;
240 return this.player.getDuration();
241 }
242 }, {
243 key: 'getCurrentTime',
244 value: function getCurrentTime() {
245 if (!this.isReady) return null;
246 return this.player.getCurrentTime();
247 }
248 }, {
249 key: 'getSecondsLoaded',
250 value: function getSecondsLoaded() {
251 if (!this.isReady) return null;
252 return this.player.getSecondsLoaded();
253 }
254 }, {
255 key: 'seekTo',
256 value: function seekTo(amount, type) {
257 var _this3 = this;
258
259 // When seeking before player is ready, store value and seek later
260 if (!this.isReady && amount !== 0) {
261 this.seekOnPlay = amount;
262 setTimeout(function () {
263 _this3.seekOnPlay = null;
264 }, SEEK_ON_PLAY_EXPIRY);
265 return;
266 }
267 var isFraction = !type ? amount > 0 && amount < 1 : type === 'fraction';
268 if (isFraction) {
269 // Convert fraction to seconds based on duration
270 var duration = this.player.getDuration();
271 if (!duration) {
272 console.warn('ReactPlayer: could not seek using fraction – duration not yet available');
273 return;
274 }
275 this.player.seekTo(duration * amount);
276 return;
277 }
278 this.player.seekTo(amount);
279 }
280 }, {
281 key: 'render',
282 value: function render() {
283 var Player = this.props.activePlayer;
284 if (!Player) {
285 return null;
286 }
287 return _react2['default'].createElement(Player, _extends({}, this.props, {
288 ref: this.ref,
289 onReady: this.onReady,
290 onPlay: this.onPlay,
291 onPause: this.onPause,
292 onEnded: this.onEnded,
293 onLoaded: this.onLoaded,
294 onError: this.onError
295 }));
296 }
297 }]);
298
299 return Player;
300}(_react.Component);
301
302Player.displayName = 'Player';
303Player.propTypes = _props2.propTypes;
304Player.defaultProps = _props2.defaultProps;
305exports['default'] = Player;
\No newline at end of file