@lahzenegar/video-react
Version:
Video-React is a web video player built from the ground up for an HTML5 world using React library.
1,664 lines (1,402 loc) • 47.8 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
var _extends2 = require('babel-runtime/helpers/extends');
var _extends3 = _interopRequireDefault(_extends2);
var _regenerator = require('babel-runtime/regenerator');
var _regenerator2 = _interopRequireDefault(_regenerator);
var _asyncToGenerator2 = require('babel-runtime/helpers/asyncToGenerator');
var _asyncToGenerator3 = _interopRequireDefault(_asyncToGenerator2);
var _getPrototypeOf = require('babel-runtime/core-js/object/get-prototype-of');
var _getPrototypeOf2 = _interopRequireDefault(_getPrototypeOf);
var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck');
var _classCallCheck3 = _interopRequireDefault(_classCallCheck2);
var _createClass2 = require('babel-runtime/helpers/createClass');
var _createClass3 = _interopRequireDefault(_createClass2);
var _possibleConstructorReturn2 = require('babel-runtime/helpers/possibleConstructorReturn');
var _possibleConstructorReturn3 = _interopRequireDefault(_possibleConstructorReturn2);
var _inherits2 = require('babel-runtime/helpers/inherits');
var _inherits3 = _interopRequireDefault(_inherits2);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
var _vastParser = require('../vast-parser');
var _HLSSource = require('./hls/HLSSource');
var _HLSSource2 = _interopRequireDefault(_HLSSource);
var _browser = require('../utils/browser');
var browser = _interopRequireWildcard(_browser);
var _utils = require('../utils');
var _AdControllers = require('./AdControllers');
var _AdControllers2 = _interopRequireDefault(_AdControllers);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
var propTypes = {
actions: _propTypes2.default.object,
player: _propTypes2.default.object,
children: _propTypes2.default.any,
startTime: _propTypes2.default.number,
loop: _propTypes2.default.bool,
muted: _propTypes2.default.bool,
autoPlay: _propTypes2.default.bool,
forceAutoPlay: _propTypes2.default.bool,
targetTotalTime: _propTypes2.default.number,
playsInline: _propTypes2.default.bool,
src: _propTypes2.default.string,
poster: _propTypes2.default.string,
className: _propTypes2.default.string,
preload: _propTypes2.default.oneOf(['auto', 'metadata', 'none']),
crossOrigin: _propTypes2.default.string,
onLoadStart: _propTypes2.default.func,
onWaiting: _propTypes2.default.func,
onCanPlay: _propTypes2.default.func,
onCanPlayThrough: _propTypes2.default.func,
onPlaying: _propTypes2.default.func,
onEnded: _propTypes2.default.func,
onSeeking: _propTypes2.default.func,
onSeeked: _propTypes2.default.func,
onPlay: _propTypes2.default.func,
onPause: _propTypes2.default.func,
onProgress: _propTypes2.default.func,
onDurationChange: _propTypes2.default.func,
onError: _propTypes2.default.func,
onSuspend: _propTypes2.default.func,
onAbort: _propTypes2.default.func,
onEmptied: _propTypes2.default.func,
onStalled: _propTypes2.default.func,
onLoadedMetadata: _propTypes2.default.func,
onSecondsPlayedReached: _propTypes2.default.func,
onLoadedData: _propTypes2.default.func,
onTimeUpdate: _propTypes2.default.func,
onRateChange: _propTypes2.default.func,
onVolumeChange: _propTypes2.default.func,
onAllAdsCompleted: _propTypes2.default.func,
sendPlayerEvent: _propTypes2.default.func,
onAdError: _propTypes2.default.func,
onAdStart: _propTypes2.default.func,
debugMode: _propTypes2.default.bool,
onAdPlaying: _propTypes2.default.func,
onStartFirstTime: _propTypes2.default.func,
onAdStartFirstTime: _propTypes2.default.func,
onVASTLoadedFirstTime: _propTypes2.default.func,
onFirstPlayAttempt: _propTypes2.default.func,
onFirstPlayAdAttempt: _propTypes2.default.func,
onStartError: _propTypes2.default.func,
chapters: _propTypes2.default.array,
storyboard: _propTypes2.default.object
};
var defaultProps = {
preload: 'auto'
};
var Video = function (_Component) {
(0, _inherits3.default)(Video, _Component);
function Video(props) {
(0, _classCallCheck3.default)(this, Video);
var _this = (0, _possibleConstructorReturn3.default)(this, (Video.__proto__ || (0, _getPrototypeOf2.default)(Video)).call(this, props));
_this.isFirstTimeToPlay = true;
_this.video = null;
_this.isVideoPlayed = false;
_this.isReachedSecond = false;
_this.delayToStartVideoTimer = null;
_this.delayToStartVideoAdTimer = null;
_this.videoWaitingTimer = null;
_this.defaultAdState = {
skipTimeOffset: null,
skipOn: null,
time: 0,
clickThroughUrl: null,
isPlaying: false,
isPlayed: false,
isCompleted: false,
source: null,
name: null
};
_this.totalWaitingDuration = 0;
_this.waitingInterval = null;
_this.inlinePlay = browser.IS_IOS;
_this.state = {
ad: _this.defaultAdState,
allowToPlay: false,
allowToAutoPlay: true,
videoURL: null,
currentError: null
};
_this.metricIntervalTimeout = 10000;
_this.play = _this.play.bind(_this);
_this.pause = _this.pause.bind(_this);
_this.seek = _this.seek.bind(_this);
_this.forward = _this.forward.bind(_this);
_this.replay = _this.replay.bind(_this);
_this.toggleFullscreen = _this.toggleFullscreen.bind(_this);
_this.getProperties = _this.getProperties.bind(_this);
_this.handleLoadStart = _this.handleLoadStart.bind(_this);
_this.handleCanPlay = _this.handleCanPlay.bind(_this);
_this.handleCanPlayThrough = _this.handleCanPlayThrough.bind(_this);
_this.handlePlay = _this.handlePlay.bind(_this);
_this.handlePlaying = _this.handlePlaying.bind(_this);
_this.handlePause = _this.handlePause.bind(_this);
_this.handleEnded = _this.handleEnded.bind(_this);
_this.handleWaiting = _this.handleWaiting.bind(_this);
_this.handleSeeking = _this.handleSeeking.bind(_this);
_this.handleResize = _this.handleResize.bind(_this);
_this.handleSeeked = _this.handleSeeked.bind(_this);
_this.handleError = _this.handleError.bind(_this);
_this.handleSuspend = _this.handleSuspend.bind(_this);
_this.handleAbort = _this.handleAbort.bind(_this);
_this.handleEmptied = _this.handleEmptied.bind(_this);
_this.handleStalled = _this.handleStalled.bind(_this);
_this.handleLoadedMetaData = _this.handleLoadedMetaData.bind(_this);
_this.handleLoadedData = _this.handleLoadedData.bind(_this);
_this.handleTimeUpdate = _this.handleTimeUpdate.bind(_this);
_this.handleRateChange = _this.handleRateChange.bind(_this);
_this.handleVolumeChange = _this.handleVolumeChange.bind(_this);
_this.handleDurationChange = _this.handleDurationChange.bind(_this);
_this.handleProgress = (0, _utils.throttle)(_this.handleProgress.bind(_this), 250);
_this.adHandleElapsedTime = _this.adHandleElapsedTime.bind(_this);
return _this;
}
(0, _createClass3.default)(Video, [{
key: 'componentDidMount',
value: function () {
var _ref = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee() {
return _regenerator2.default.wrap(function _callee$(_context) {
while (1) {
switch (_context.prev = _context.next) {
case 0:
this.methodCalls('componentDidMount');
window.addEventListener('resize', this.handleResize);
_context.next = 4;
return this.handleVideoContentInit();
case 4:
if (!this.autoPlay) {
this.setContentLoading(false);
}
case 5:
case 'end':
return _context.stop();
}
}
}, _callee, this);
}));
function componentDidMount() {
return _ref.apply(this, arguments);
}
return componentDidMount;
}()
}, {
key: 'componentWillMount',
value: function componentWillMount() {
this.methodCalls('componentWillMount');
}
}, {
key: 'componentWillUnmount',
value: function componentWillUnmount() {
this.methodCalls('componentWillUnmount');
window.removeEventListener('resize', this.handleResize);
if (this.delayToStartVideoTimer) {
this.delayToStartVideoTimer.end();
}
if (this.delayToStartVideoAdTimer) {
this.delayToStartVideoAdTimer.end();
}
if (this.videoWaitingTimer) {
this.videoWaitingTimer.end();
}
this.delayToStartVideoTimer = null;
this.delayToStartVideoAdTimer = null;
this.videoWaitingTimer = null;
this.isVideoPlayed = false;
this.isReachedSecond = false;
this.totalWaitingDuration = 0;
if (this.waitingInterval) {
clearInterval(this.waitingInterval);
this.waitingInterval = null;
}
}
}, {
key: 'componentWillReceiveProps',
value: function componentWillReceiveProps(nextProps) {
var _this2 = this;
if (nextProps.src !== this.props.src) {
this.video = null;
this.setState({
videoURL: nextProps.src
}, function () {
_this2.play();
});
}
}
}, {
key: 'getVideoSRC',
value: function getVideoSRC() {
var videoSRC = void 0;
if (this.props.src) {
videoSRC = this.props.src;
} else if (this.props.children) {
_react2.default.Children.toArray(this.props.children).filter(_utils.isVideoChild).map(function (component) {
var componentProps = void 0;
if (typeof component.type === 'string' && component.type === 'source') {
componentProps = (0, _extends3.default)({}, component.props);
}
videoSRC = componentProps.src;
});
}
return videoSRC || null;
}
}, {
key: 'setVideoURL',
value: function setVideoURL() {
var videoURL = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.getVideoSRC();
this.methodCalls('setVideoURL');
if (videoURL !== this.state.videoURL) {
this.methodCalls('setVideoURL', videoURL);
this.setState({
videoURL: videoURL
});
}
}
// get all video properties
}, {
key: 'getProperties',
value: function getProperties() {
var _this3 = this;
if (!this.video) {
return null;
}
return _utils.mediaProperties.reduce(function (properties, key) {
properties[key] = _this3.video[key];
return properties;
}, {});
}
// get playback rate
}, {
key: 'setContentLoading',
value: function setContentLoading() {
var contentLoading = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
var actions = this.props.actions;
if (this.isVideoPlayed === contentLoading) {
this.isVideoPlayed = !contentLoading;
actions.handleContentLoading(contentLoading);
}
}
}, {
key: 'play',
value: function play() {
var _this4 = this;
var attempts = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
var forceToPlay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
if (this.isSafe) {
this.setContentLoading(false);
var forceAutoPlay = this.props.forceAutoPlay,
_state = this.state,
allowToPlay = _state.allowToPlay,
ad = _state.ad;
if (allowToPlay || forceToPlay) {
// const { muted } = this.props;
this.methodCalls('play', attempts);
var promise = this.video.play();
if (promise) {
promise.then(function () {
_this4.adPlayEvent();
var _props = _this4.props,
onFirstPlayAttempt = _props.onFirstPlayAttempt,
onFirstPlayAdAttempt = _props.onFirstPlayAdAttempt;
if (_this4.isFirstTimeToPlay) {
_this4.isFirstTimeToPlay = false;
if (!ad.isPlaying && onFirstPlayAttempt) {
onFirstPlayAttempt();
}
if (ad.isPlaying && onFirstPlayAdAttempt) {
onFirstPlayAdAttempt();
}
}
}).catch(function (error) {
var isNotAllowedError = error && error.name === 'NotAllowedError';
_this4.error(error);
if (forceAutoPlay) {
if (isNotAllowedError) {
_this4.muted = true;
}
if (attempts < 10) {
setTimeout(function () {
return _this4.play(attempts + 1);
}, 200);
}
} else if (isNotAllowedError) {
_this4.allowToAutoPlay = false;
}
});
return promise;
}
}
}
}
// pause the video
}, {
key: 'pause',
value: function pause() {
var sendEvent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
this.methodCalls('pause');
if (sendEvent) {
this.adPausedEvent();
}
if (this.isSafe) {
this.video.pause();
}
}
// Change the video source and re-load the video:
}, {
key: 'load',
value: function load() {
this.methodCalls('load');
if (this.isSafe) {
this.video.load();
}
}
// Add a new text track to the video
}, {
key: 'addTextTrack',
value: function addTextTrack() {
this.methodCalls('addTextTrack');
if (this.isSafe) {
var _video;
(_video = this.video).addTextTrack.apply(_video, arguments);
}
}
// Check if your browser can play different types of video:
}, {
key: 'canPlayType',
value: function canPlayType() {
this.methodCalls('canPlayType');
if (this.isSafe) {
var _video2;
(_video2 = this.video).canPlayType.apply(_video2, arguments);
}
}
// toggle play
}, {
key: 'togglePlay',
value: function togglePlay() {
this.methodCalls('togglePlay');
if (this.isSafe) {
if (this.video.paused) {
this.play();
} else {
this.pause();
}
}
}
// seek video by time
}, {
key: 'seek',
value: function seek(time) {
this.methodCalls('time');
if (this.isSafe) {
try {
this.currentTime = time;
} catch (e) {
this.error('seek', e);
}
}
}
// jump forward x seconds
}, {
key: 'forward',
value: function forward(seconds) {
this.methodCalls('forward', seconds);
if (this.isSafe) {
this.seek(this.video.currentTime + seconds);
}
}
// jump back x seconds
}, {
key: 'replay',
value: function replay(seconds) {
this.methodCalls('replay', seconds);
if (this.isSafe) {
this.forward(-seconds);
}
}
// enter or exist full screen
}, {
key: 'toggleFullscreen',
value: function toggleFullscreen() {
this.methodCalls('toggleFullscreen');
var _props2 = this.props,
player = _props2.player,
actions = _props2.actions;
actions.toggleFullscreen(player);
}
// Fired when the user agent
// begins looking for media data
}, {
key: 'handleLoadStart',
value: function handleLoadStart() {
this.methodCalls('handleLoadStart');
var _props3 = this.props,
actions = _props3.actions,
onLoadStart = _props3.onLoadStart;
actions.handleLoadStart(this.getProperties());
if (!this.delayToStartVideoTimer || !this.delayToStartVideoAdTimer) {
this.delayToStartVideoAdTimer = (0, _utils.startTimer)();
this.delayToStartVideoTimer = (0, _utils.startTimer)();
}
if (onLoadStart) {
onLoadStart.apply(undefined, arguments);
}
}
// A handler for events that
// signal that waiting has ended
}, {
key: 'handleCanPlay',
value: function handleCanPlay() {
this.methodCalls('handleCanPlay');
var _props4 = this.props,
actions = _props4.actions,
onCanPlay = _props4.onCanPlay;
actions.handleCanPlay(this.getProperties());
if (onCanPlay) {
onCanPlay.apply(undefined, arguments);
}
}
// A handler for events that
// signal that waiting has ended
}, {
key: 'handleCanPlayThrough',
value: function handleCanPlayThrough() {
this.methodCalls('handleCanPlayThrough');
var _props5 = this.props,
actions = _props5.actions,
onCanPlayThrough = _props5.onCanPlayThrough;
// Calculate exact delay to start playing
if (this.delayToStartVideoTimer && this.isFirstTimeToPlay) {
this.handleDelayToStartPlaying();
this.handleDelayToAdStartPlaying();
} else {
if (this.state.currentError) {
if (this.state.currentError.isFatal) {
this.setWaitingFlag();
}
this.setState({
currentError: null
});
}
this.handleWaitingDuration();
}
actions.handleCanPlayThrough(this.getProperties());
if (onCanPlayThrough) {
onCanPlayThrough.apply(undefined, arguments);
}
}
}, {
key: 'handleDelayToStartPlaying',
value: function handleDelayToStartPlaying() {
var onStartFirstTime = this.props.onStartFirstTime,
ad = this.state.ad;
if (!ad.isPlaying && onStartFirstTime) {
onStartFirstTime({
quality: this.trackQuality,
delayToStartPlaying: this.delayToStartVideoTimer.end() / 1000
});
}
}
}, {
key: 'handleDelayToAdStartPlaying',
value: function handleDelayToAdStartPlaying() {
var onAdStartFirstTime = this.props.onAdStartFirstTime,
ad = this.state.ad;
if (ad.isPlaying && onAdStartFirstTime) {
onAdStartFirstTime({
delayToStartPlaying: this.delayToStartVideoAdTimer.end() / 1000
});
}
}
}, {
key: 'handleWaitingDuration',
value: function handleWaitingDuration() {
var removeInterval = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
if (this.videoWaitingTimer) {
if (removeInterval) {
clearInterval(this.waitingInterval);
}
var onWaitingStop = this.props.onWaitingStop,
currentWaitingDuration = this.videoWaitingTimer.end() / 1000;
if (currentWaitingDuration > 0.1) {
this.totalWaitingDuration += currentWaitingDuration;
if (onWaitingStop) {
onWaitingStop({
quality: this.trackQuality,
waitingDuration: currentWaitingDuration,
totalWaitingDuration: this.totalWaitingDuration
});
}
}
this.videoWaitingTimer = null;
}
}
}, {
key: 'handlePlaying',
// A handler for events that
// signal that waiting has ended
value: function handlePlaying() {
this.methodCalls('handlePlaying');
var _props6 = this.props,
actions = _props6.actions,
onPlaying = _props6.onPlaying;
actions.handlePlaying(this.getProperties());
if (onPlaying) {
onPlaying.apply(undefined, arguments);
}
}
// Fired whenever the media has been started
}, {
key: 'handlePlay',
value: function handlePlay() {
this.methodCalls('handlePlay');
var _props7 = this.props,
actions = _props7.actions,
onPlay = _props7.onPlay;
actions.handlePlay(this.getProperties());
if (onPlay) {
onPlay.apply(undefined, arguments);
}
}
// Fired whenever the media has been paused
}, {
key: 'handlePause',
value: function handlePause() {
this.methodCalls('handlePause');
var _props8 = this.props,
actions = _props8.actions,
onPause = _props8.onPause;
actions.handlePause(this.getProperties());
if (onPause) {
onPause.apply(undefined, arguments);
}
}
// Fired when the duration of
// the media resource is first known or changed
}, {
key: 'handleDurationChange',
value: function handleDurationChange() {
this.methodCalls('handleDurationChange');
var _props9 = this.props,
actions = _props9.actions,
onDurationChange = _props9.onDurationChange;
actions.handleDurationChange(this.getProperties());
if (onDurationChange) {
onDurationChange.apply(undefined, arguments);
}
}
// Fired while the user agent
// is downloading media data
}, {
key: 'handleProgress',
value: function handleProgress() {
this.methodCalls('handleProgress');
var _props10 = this.props,
actions = _props10.actions,
onProgress = _props10.onProgress;
if (this.video) {
actions.handleProgressChange(this.getProperties());
}
if (onProgress) {
onProgress.apply(undefined, arguments);
}
}
// Fired when the end of the media resource
// is reached (currentTime == duration)
}, {
key: 'handleEnded',
value: function handleEnded() {
this.methodCalls('handleEnded');
var _props11 = this.props,
loop = _props11.loop,
player = _props11.player,
actions = _props11.actions,
onEnded = _props11.onEnded,
source = this.state.ad.source;
if (source) {
this.adHandleEnd();
} else {
if (loop) {
this.seek(0);
this.play();
} else if (!player.paused) {
this.pause();
}
actions.handleEnd(this.getProperties());
if (onEnded) {
onEnded.apply(undefined, arguments);
}
}
}
// Fired whenever the player
// is jumping to a new time
}, {
key: 'handleSeeking',
value: function handleSeeking() {
this.methodCalls('handleSeeking');
if (this.video.paused) {
this.setWaitingFlag();
}
var _props12 = this.props,
actions = _props12.actions,
onSeeking = _props12.onSeeking;
actions.handleSeeking(this.getProperties());
if (onSeeking) {
onSeeking.apply(undefined, arguments);
}
}
// Fired when the player has
// finished jumping to a new time
}, {
key: 'handleSeeked',
value: function handleSeeked() {
this.methodCalls('handleSeeked');
var _props13 = this.props,
actions = _props13.actions,
onSeeked = _props13.onSeeked;
actions.handleSeeked(this.getProperties());
if (onSeeked) {
onSeeked.apply(undefined, arguments);
}
}
// Fires when the browser is
// intentionally not getting media data
}, {
key: 'handleSuspend',
value: function handleSuspend() {
this.methodCalls('handleSuspend');
var _props14 = this.props,
actions = _props14.actions,
onSuspend = _props14.onSuspend;
actions.handleSuspend(this.getProperties());
if (onSuspend) {
onSuspend.apply(undefined, arguments);
}
}
// Fires when the loading of an audio/video is aborted
}, {
key: 'handleAbort',
value: function handleAbort() {
this.methodCalls('handleAbort');
var _props15 = this.props,
actions = _props15.actions,
onAbort = _props15.onAbort;
actions.handleAbort(this.getProperties());
if (onAbort) {
onAbort.apply(undefined, arguments);
}
}
// Fires when the current playlist is empty
}, {
key: 'handleEmptied',
value: function handleEmptied() {
this.methodCalls('handleEmptied');
var _props16 = this.props,
actions = _props16.actions,
onEmptied = _props16.onEmptied;
actions.handleEmptied(this.getProperties());
if (onEmptied) {
onEmptied.apply(undefined, arguments);
}
}
// Fires when the browser is trying to
// get media data, but data is not available
}, {
key: 'handleStalled',
value: function handleStalled() {
this.methodCalls('handleStalled');
var _props17 = this.props,
actions = _props17.actions,
onStalled = _props17.onStalled;
actions.handleStalled(this.getProperties());
if (onStalled) {
onStalled.apply(undefined, arguments);
}
}
// Fires when the browser has loaded
// meta data for the audio/video
}, {
key: 'handleLoadedMetaData',
value: function handleLoadedMetaData() {
this.methodCalls('handleLoadedMetaData');
if (this.isSafe) {
var _props18 = this.props,
actions = _props18.actions,
onLoadedMetadata = _props18.onLoadedMetadata,
adsTagUrl = _props18.adsTagUrl,
isCompleted = this.state.ad.isCompleted;
actions.handleLoadedMetaData(this.getProperties());
if (this.inlinePlay && adsTagUrl && isCompleted) {
this.play();
} else {
this.setContentLoading(false);
}
if (onLoadedMetadata) {
onLoadedMetadata.apply(undefined, arguments);
}
}
}
// Fires when the browser has loaded
// the current frame of the audio/video
}, {
key: 'handleLoadedData',
value: function handleLoadedData() {
this.methodCalls('handleLoadedData');
var _props19 = this.props,
actions = _props19.actions,
onLoadedData = _props19.onLoadedData,
startTime = _props19.startTime,
isPlaying = this.state.ad.isPlaying;
actions.handleLoadedData(this.getProperties());
if (!isPlaying && startTime && startTime > 0) {
this.currentTime = startTime;
}
if (onLoadedData) {
onLoadedData.apply(undefined, arguments);
}
if (this.autoPlay) {
this.play();
} else {
this.setContentLoading(false);
}
}
// Fired whenever the media begins waiting
}, {
key: 'handleWaiting',
value: function handleWaiting() {
this.methodCalls('handleWaiting', this.props.player);
var _props20 = this.props,
actions = _props20.actions,
onWaiting = _props20.onWaiting;
this.setWaitingFlag();
actions.handleWaiting(this.getProperties());
if (onWaiting) {
onWaiting.apply(undefined, arguments);
}
}
}, {
key: 'setWaitingFlag',
value: function setWaitingFlag() {
var _this5 = this;
var currentTime = this.props.player.currentTime;
if (!this.videoWaitingTimer && currentTime) {
this.videoWaitingTimer = (0, _utils.startTimer)();
this.waitingInterval = setInterval(function () {
_this5.handleWaitingDuration(false);
_this5.handleTimeUpdate();
if (_this5.videoWaitingTimer) {
_this5.videoWaitingTimer.end();
}
_this5.videoWaitingTimer = (0, _utils.startTimer)();
}, this.metricIntervalTimeout);
}
}
// Fires when the current
// playback position has changed
}, {
key: 'handleTimeUpdate',
value: function handleTimeUpdate() {
// reset waiting flag until current time if it set.
if (this.isSafe) {
if (this.videoWaitingTimer) {
this.handleWaitingDuration();
this.setWaitingFlag();
}
var _props21 = this.props,
actions = _props21.actions,
onTimeUpdate = _props21.onTimeUpdate,
onSecondsPlayedReached = _props21.onSecondsPlayedReached,
_props21$targetTotalT = _props21.targetTotalTime,
targetTotalTime = _props21$targetTotalT === undefined ? 10 : _props21$targetTotalT,
_props21$player = _props21.player,
currentTime = _props21$player.currentTime,
duration = _props21$player.duration,
hls = _props21$player.hls,
isLive = _props21$player.isLive,
ad = this.state.ad,
timeRanges = this.video.played;
var secondsPlayed = 0,
percentPlayed = 0;
if (duration && timeRanges) {
for (var i = 0; i < timeRanges.length; i++) {
secondsPlayed = secondsPlayed + (timeRanges.end(i) - timeRanges.start(i));
}
percentPlayed = 100 / duration * secondsPlayed;
}
actions.handleTimeUpdate(this.getProperties(), secondsPlayed, percentPlayed, this.totalWaitingDuration);
if (isLive && hls && hls.levels[hls.currentLevel] && hls.levels[hls.currentLevel].details) {
var targetDuration = hls.levels[hls.currentLevel].details.targetduration,
liveSync = hls.config.liveSyncDurationCount,
liveOffset = targetDuration * liveSync,
liveTime = duration - liveOffset,
latency = liveTime - currentTime;
actions.handleMediaLatencyChange(liveTime, latency);
}
if (!ad.isPlaying && onSecondsPlayedReached && secondsPlayed >= targetTotalTime && !this.isReachedSecond) {
this.isReachedSecond = true;
onSecondsPlayedReached.apply(undefined, arguments);
}
if (onTimeUpdate) {
onTimeUpdate.apply(undefined, arguments);
}
}
}
/**
* Fires when the playing speed of the audio/video is changed
*/
}, {
key: 'handleRateChange',
value: function handleRateChange() {
this.methodCalls('handleRateChange');
var _props22 = this.props,
actions = _props22.actions,
onRateChange = _props22.onRateChange;
actions.handleRateChange(this.getProperties());
if (onRateChange) {
onRateChange.apply(undefined, arguments);
}
}
// Fires when the volume has been changed
}, {
key: 'handleVolumeChange',
value: function handleVolumeChange() {
this.methodCalls('handleVolumeChange');
var _props23 = this.props,
actions = _props23.actions,
onVolumeChange = _props23.onVolumeChange;
actions.handleVolumeChange(this.getProperties());
if (onVolumeChange) {
onVolumeChange.apply(undefined, arguments);
}
}
// Fires when an error occurred
// during the loading of an audio/video
}, {
key: 'handleError',
value: function handleError(type, data) {
var reason = (0, _utils.getErrorSchema)(data);
this.error(type, data, reason);
var _props24 = this.props,
actions = _props24.actions,
onError = _props24.onError;
actions.handleError(this.getProperties());
if (onError) {
onError(type, data, reason);
}
if (this.isFirstTimeToPlay) {
this.handleStartupError(reason);
}
this.setState({
currentError: reason
});
if (reason && reason.isFatal && this.videoWaitingTimer) {
this.handleWaitingDuration();
}
}
}, {
key: 'handleStartupError',
value: function handleStartupError(reason) {
this.methodCalls('handleStartupError', reason);
var _props25 = this.props,
onFirstPlayAttempt = _props25.onFirstPlayAttempt,
onStartError = _props25.onStartError,
ad = this.state.ad;
if (!ad.isPlaying && this.isFirstTimeToPlay && onFirstPlayAttempt) {
this.isFirstTimeToPlay = false;
onFirstPlayAttempt();
}
if (reason && reason.type && reason.detail && onStartError) {
onStartError(reason, ad.isPlaying);
}
if (ad.isPlaying && (!reason || reason.isFatal)) {
this.adEvent('error');
this.destroyAd();
}
}
}, {
key: 'handleResize',
value: function handleResize() {
this.methodCalls('handleResize');
var _props26 = this.props,
actions = _props26.actions,
onResize = _props26.onResize;
actions.handleResize(this.getProperties());
if (onResize) {
onResize.apply(undefined, arguments);
}
}
}, {
key: 'handleVideoContentInit',
value: function () {
var _ref2 = (0, _asyncToGenerator3.default)( /*#__PURE__*/_regenerator2.default.mark(function _callee2() {
var _props27, actions, adsTagUrl, onVASTLoadedFirstTime, delayToLoadVastTimer, VAST, _VAST$, mediaFiles, videoClicks, skipOn, adTitle;
return _regenerator2.default.wrap(function _callee2$(_context2) {
while (1) {
switch (_context2.prev = _context2.next) {
case 0:
this.methodCalls('handleVideoContentInit');
_props27 = this.props, actions = _props27.actions, adsTagUrl = _props27.adsTagUrl, onVASTLoadedFirstTime = _props27.onVASTLoadedFirstTime;
if (!adsTagUrl) {
_context2.next = 22;
break;
}
_context2.prev = 3;
delayToLoadVastTimer = (0, _utils.startTimer)();
this.log('getting VAST data');
_context2.next = 8;
return (0, _vastParser.handleVAST)(adsTagUrl);
case 8:
VAST = _context2.sent;
this.log('VAST data', VAST);
if (VAST && VAST.length) {
_VAST$ = VAST[0], mediaFiles = _VAST$.mediaFiles, videoClicks = _VAST$.videoClicks, skipOn = _VAST$.skipOn, adTitle = _VAST$.adTitle;
this.setState(function (_ref3) {
var ad = _ref3.ad;
return {
ad: (0, _extends3.default)({}, ad, {
source: mediaFiles[0].URL,
clickThroughUrl: videoClicks || null,
skipTimeOffset: skipOn ? skipOn + 1 : null,
name: adTitle,
isPlaying: true
}),
allowToPlay: true,
videoURL: mediaFiles[0].URL
};
});
this.adEvent('loaded');
if (onVASTLoadedFirstTime) {
onVASTLoadedFirstTime({
delayToLoad: delayToLoadVastTimer.end() / 1000
});
}
if (this.video) {
this.video.addEventListener('timeupdate', this.adHandleElapsedTime);
}
actions.handleAdStart();
}
_context2.next = 20;
break;
case 13:
_context2.prev = 13;
_context2.t0 = _context2['catch'](3);
// this.handleStartupError({
// type: 'VAST_ERROR',
// detail: error
// });
this.setVideoURL();
this.error(_context2.t0);
this.adEvent('error');
this.destroyAd();
this.allowToPlay = true;
case 20:
_context2.next = 24;
break;
case 22:
this.setVideoURL();
this.allowToPlay = true;
case 24:
case 'end':
return _context2.stop();
}
}
}, _callee2, this, [[3, 13]]);
}));
function handleVideoContentInit() {
return _ref2.apply(this, arguments);
}
return handleVideoContentInit;
}()
}, {
key: 'methodCalls',
value: function methodCalls() {
for (var _len = arguments.length, logs = Array(_len), _key = 0; _key < _len; _key++) {
logs[_key] = arguments[_key];
}
this.log.apply(this, ['Method: '].concat(logs));
}
}, {
key: 'error',
value: function error() {
if (this.props.debugMode) {
var _console;
for (var _len2 = arguments.length, logs = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
logs[_key2] = arguments[_key2];
}
(_console = console).error.apply(_console, ['VIDEO_REACT'].concat(logs));
}
}
}, {
key: 'log',
value: function log() {
if (this.props.debugMode) {
var _console2;
for (var _len3 = arguments.length, logs = Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
logs[_key3] = arguments[_key3];
}
(_console2 = console).log.apply(_console2, ['VIDEO_REACT'].concat(logs));
}
}
/*
* ////////////////////////////// ADS METHODS //////////////////////////////
*/
}, {
key: 'adEvent',
value: function adEvent(event) {
var sendPlayerEvent = this.props.sendPlayerEvent,
name = this.state.ad.name;
if (sendPlayerEvent) {
sendPlayerEvent('Ads', event, name);
}
}
}, {
key: 'adPlayEvent',
value: function adPlayEvent() {
var _state$ad = this.state.ad,
source = _state$ad.source,
isPlaying = _state$ad.isPlaying;
if (source) {
this.adEvent(isPlaying ? 'play' : 'resume');
this.setState(function (_ref4) {
var ad = _ref4.ad;
return {
ad: (0, _extends3.default)({}, ad, {
isPlaying: true
})
};
});
this.isAdPlaying(true);
}
}
}, {
key: 'adPausedEvent',
value: function adPausedEvent() {
var source = this.state.ad.source;
if (source) {
this.adEvent('paused');
this.setState(function (_ref5) {
var ad = _ref5.ad;
return {
ad: (0, _extends3.default)({}, ad, {
isPlaying: false
})
};
});
}
}
}, {
key: 'adEndEvent',
value: function adEndEvent() {
this.adEvent('complete');
}
}, {
key: 'adClickEvent',
value: function adClickEvent() {
this.adEvent('clicked');
}
}, {
key: 'adSkip',
value: function adSkip() {
this.adEvent('skip');
this.adHandleEnd(false);
}
}, {
key: 'adMoreInfo',
value: function adMoreInfo() {
this.pause(false);
this.adClickEvent();
}
}, {
key: 'destroyAd',
value: function destroyAd() {
var _this6 = this;
this.methodCalls('destroyAd');
if (this.delayToStartVideoTimer) {
this.delayToStartVideoTimer.end();
}
this.delayToStartVideoTimer = (0, _utils.startTimer)();
this.isFirstTimeToPlay = true;
this.pause();
var actions = this.props.actions;
actions.handleAdEnded();
this.setState(function (_ref6) {
var ad = _ref6.ad;
return {
ad: (0, _extends3.default)({}, ad, _this6.defaultAdState, {
isPlayed: false,
isPlaying: false,
isCompleted: true
}),
allowToAutoPlay: true,
allowToPlay: true
};
});
this.isAdPlaying(false);
this.setContentLoading(true);
if (this.video) {
this.video.removeEventListener('timeupdate', this.adHandleElapsedTime);
this.video = null;
}
this.setVideoURL();
}
}, {
key: 'adHandleEnd',
value: function adHandleEnd() {
var sendEvent = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
this.methodCalls('handleAdEnded');
if (sendEvent) {
this.adEndEvent();
}
this.destroyAd();
}
}, {
key: 'adHandleElapsedTime',
value: function adHandleElapsedTime() {
this.methodCalls('adHandleElapsedTime');
if (this.isSafe) {
var duration = Math.ceil(this.video.duration),
currentTime = Math.ceil(this.video.currentTime),
time = Math.abs(currentTime - duration);
if (time !== this.state.ad.time) {
var states = {
time: time
};
if (this.state.ad.skipTimeOffset) {
states.skipOn = this.state.ad.skipTimeOffset - currentTime;
}
this.setState(function (_ref7) {
var ad = _ref7.ad;
return {
ad: (0, _extends3.default)({}, ad, states)
};
});
}
}
}
}, {
key: 'isAdPlaying',
value: function isAdPlaying(_isAdPlaying) {
this.methodCalls('isAdPlaying', _isAdPlaying);
var onAdPlaying = this.props.onAdPlaying,
isPlayed = this.state.ad.isPlayed;
if (_isAdPlaying !== isPlayed) {
if (onAdPlaying) {
onAdPlaying(_isAdPlaying);
}
if (_isAdPlaying !== this.state.ad.isPlayed) {
this.setState(function (_ref8) {
var ad = _ref8.ad;
return {
ad: (0, _extends3.default)({}, ad, {
isPlayed: _isAdPlaying
})
};
});
}
}
}
}, {
key: 'render',
value: function render() {
var _this7 = this;
return _react2.default.createElement(
'div',
{ className: 'react-video-holder' },
this.state.ad && this.state.ad.isPlayed && _react2.default.createElement(_AdControllers2.default, { onSkip: function onSkip() {
return _this7.adSkip();
}, onLinkClick: function onLinkClick() {
return _this7.adMoreInfo();
}, duration: this.state.ad.time, skipOn: this.state.ad.skipOn, URL: this.state.ad.clickThroughUrl }),
_react2.default.createElement(
'video',
{
className: (0, _classnames2.default)('video-react-video', this.props.className),
id: this.props.videoId,
crossOrigin: this.props.crossOrigin,
ref: function ref(c) {
_this7.video = c;
},
muted: this.props.muted,
preload: this.props.preload,
loop: this.props.loop,
autoPlay: this.state.allowToPlay && this.autoPlay,
poster: this.props.poster,
src: this.state.videoURL,
onLoadStart: this.handleLoadStart,
onWaiting: this.handleWaiting,
onCanPlay: this.handleCanPlay,
onCanPlayThrough: this.handleCanPlayThrough,
onPlaying: this.handlePlaying,
onEnded: this.handleEnded,
onSeeking: this.handleSeeking,
onSeeked: this.handleSeeked,
onPlay: this.handlePlay,
onPause: this.handlePause,
onProgress: this.handleProgress,
onDurationChange: this.handleDurationChange,
onError: this.handleError,
onSuspend: this.handleSuspend,
onAbort: this.handleAbort,
onEmptied: this.handleEmptied,
onStalled: this.handleStalled,
onLoadedMetadata: this.handleLoadedMetaData,
onLoadedData: this.handleLoadedData,
onTimeUpdate: this.handleTimeUpdate,
onRateChange: this.handleRateChange,
onVolumeChange: this.handleVolumeChange
},
this.playerSource
)
);
}
}, {
key: 'isSafe',
get: function get() {
return this.state.videoURL && !!this.video;
}
}, {
key: 'autoPlay',
get: function get() {
return this.state.allowToAutoPlay && this.props.autoPlay;
}
}, {
key: 'playbackRate',
get: function get() {
this.methodCalls('playbackRate');
if (this.isSafe) {
return this.video.playbackRate;
}
},
set: function set(rate) {
this.methodCalls('playbackRate', rate);
if (this.isSafe) {
this.video.playbackRate = rate;
}
}
}, {
key: 'currentTime',
set: function set(time) {
this.methodCalls('currentTime', time);
if (this.isSafe) {
this.video.currentTime = time;
}
}
}, {
key: 'muted',
get: function get() {
this.methodCalls('get muted', this.video.muted);
if (this.isSafe) {
return this.video.muted;
}
},
set: function set(val) {
this.methodCalls('set muted', val);
if (this.isSafe) {
this.video.muted = val;
}
}
}, {
key: 'volume',
get: function get() {
this.methodCalls('get volume', this.video.volume);
if (this.isSafe) {
return this.video.volume;
}
},
set: function set(val) {
if (val > 1) {
val = 1;
}
if (val < 0) {
val = 0;
}
this.methodCalls('set volume', val);
if (this.isSafe) {
this.video.volume = val;
}
}
// video width
}, {
key: 'videoWidth',
get: function get() {
this.methodCalls('get videoWidth', this.video.videoWidth);
if (this.isSafe) {
return this.video.videoWidth;
}
}
// video height
}, {
key: 'videoHeight',
get: function get() {
this.methodCalls('get videoHeight', this.video.videoHeight);
if (this.isSafe) {
return this.video.videoHeight;
}
}
}, {
key: 'allowToPlay',
set: function set(allowToPlay) {
this.methodCalls('set allowToPlay', allowToPlay);
if (allowToPlay !== this.state.allowToPlay) {
this.setState({
allowToPlay: allowToPlay
});
}
}
}, {
key: 'allowToAutoPlay',
set: function set(allowToAutoPlay) {
this.methodCalls('set allowToAutoPlay', allowToAutoPlay);
if (allowToAutoPlay !== this.state.allowToAutoPlay) {
this.setState({
allowToAutoPlay: allowToAutoPlay
});
}
}
}, {
key: 'trackQuality',
get: function get() {
var _props$player = this.props.player,
tracks = _props$player.tracks,
realActiveTrack = _props$player.realActiveTrack;
return tracks && tracks.length > 1 && tracks.filter(function (item) {
return item.id === realActiveTrack;
})[0].label || null;
}
}, {
key: 'playerSource',
get: function get() {
var _this8 = this;
if (!this.isSafe) {
return null;
}
var props = (0, _extends3.default)({}, this.props, {
video: this.video
});
var _state2 = this.state,
source = _state2.ad.source,
videoURL = _state2.videoURL;
this.video.controls = this.video && browser.IS_MOBILE && !source;
this.video.playsInline = this.video && browser.IS_MOBILE;
return _react2.default.Children.toArray(this.props.children).filter(_utils.isVideoChild).map(function () {
return (0, _utils.isHls)(videoURL) && !browser.IS_IOS ? _react2.default.createElement(_HLSSource2.default, (0, _extends3.default)({
key: 2
}, props, {
onError: _this8.handleError,
src: videoURL
})) : _react2.default.createElement('source', { key: 1, src: videoURL });
});
}
}]);
return Video;
}(_react.Component);
exports.default = Video;
Video.propTypes = propTypes;
Video.defaultProps = defaultProps;
Video.displayName = 'Video';