maestro-react-player
Version:
A React component for playing a variety of URLs, including file paths, YouTube, Facebook, Twitch, SoundCloud, Streamable, Vimeo, Wistia and DailyMotion
360 lines (296 loc) • 11.6 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.VAST = undefined;
var _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; };
var _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; }; }();
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _vastClient = require('vast-client');
var _vastClient2 = _interopRequireDefault(_vastClient);
var _utils = require('../utils');
var _singlePlayer = require('../singlePlayer');
var _singlePlayer2 = _interopRequireDefault(_singlePlayer);
var _FilePlayer = require('./FilePlayer');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _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; }
function _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; }
var MATCH_URL = /^VAST:https:\/\//i;
var VAST = exports.VAST = function (_Component) {
_inherits(VAST, _Component);
function VAST() {
var _ref;
var _temp, _this, _ret;
_classCallCheck(this, VAST);
for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_ref = VAST.__proto__ || Object.getPrototypeOf(VAST)).call.apply(_ref, [this].concat(args))), _this), _this.state = {
sources: [],
tracker: null
}, _this.callPlayer = _utils.callPlayer, _this.mute = function () {
_this.container.mute();
}, _this.unmute = function () {
_this.container.unmute();
}, _this.ref = function (container) {
_this.container = container;
}, _this.onAdClick = function () {
var _this2 = _this,
tracker = _this2.state.tracker;
tracker.click();
}, _this.onEnded = function (event) {
var _this3 = _this,
onEnded = _this3.props.onEnded,
tracker = _this3.state.tracker;
if (tracker) {
tracker.complete();
}
onEnded(event);
}, _this.onError = function (event) {
var _this4 = _this,
onError = _this4.props.onError,
tracker = _this4.state.tracker;
_vastClient2['default'].util.track(tracker.ad.errorURLTemplates, { ERRORCODE: 405 });
onError(event);
}, _this.onPause = function (event) {
var _this5 = _this,
onPause = _this5.props.onPause,
tracker = _this5.state.tracker;
tracker.setPaused(true);
onPause(event);
}, _this.onPlay = function (event) {
var _this6 = _this,
onPlay = _this6.props.onPlay,
tracker = _this6.state.tracker;
tracker.setPaused(false);
onPlay(event);
}, _this.onProgress = function (event) {
var _this7 = _this,
onProgress = _this7.props.onProgress,
tracker = _this7.state.tracker;
tracker.setProgress(event.playedSeconds);
onProgress(event);
}, _this.onReady = function (event) {
var _this8 = _this,
onReady = _this8.props.onReady,
tracker = _this8.state.tracker;
tracker.load();
if (Number.isNaN(tracker.assetDuration)) {
tracker.assetDuration = _this.container.getDuration();
}
onReady(event);
}, _this.onVolumeChange = function (event) {
var _this9 = _this,
onVolumeChange = _this9.props.onVolumeChange,
tracker = _this9.state.tracker;
tracker.setMuted(_this.container.muted);
onVolumeChange(event);
}, _temp), _possibleConstructorReturn(_this, _ret);
}
_createClass(VAST, [{
key: 'createSourceFiles',
value: function createSourceFiles() {
var mediaFiles = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : [];
return mediaFiles.map(function () {
var _ref2 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {},
src = _ref2.fileURL,
type = _ref2.mimeType;
return { src: src, type: type };
}).filter(function (_ref3) {
var src = _ref3.src;
return _FilePlayer.FilePlayer.canPlay(src);
});
}
}, {
key: 'parseResponse',
value: function parseResponse(response) {
var onEnded = this.props.onEnded;
var _response$ads = response.ads,
ads = _response$ads === undefined ? [] : _response$ads;
// find video creatives
// todo: handle companion ads
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = ads[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var ad = _step.value;
var _ad$creatives = ad.creatives,
creatives = _ad$creatives === undefined ? [] : _ad$creatives;
var _iteratorNormalCompletion2 = true;
var _didIteratorError2 = false;
var _iteratorError2 = undefined;
try {
for (var _iterator2 = creatives[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {
var creative = _step2.value;
var _creative$mediaFiles = creative.mediaFiles,
mediaFiles = _creative$mediaFiles === undefined ? [] : _creative$mediaFiles,
type = creative.type;
if (type === 'linear') {
var sources = this.createSourceFiles(mediaFiles);
if (sources.length) {
return this.setState({
sources: sources,
// eslint-disable-next-line new-cap
tracker: new _vastClient2['default'].tracker(ad, creative)
});
}
}
}
// Inform ad server we can't find suitable media file for this ad
} catch (err) {
_didIteratorError2 = true;
_iteratorError2 = err;
} finally {
try {
if (!_iteratorNormalCompletion2 && _iterator2['return']) {
_iterator2['return']();
}
} finally {
if (_didIteratorError2) {
throw _iteratorError2;
}
}
}
_vastClient2['default'].util.track(ad.errorURLTemplates, { ERRORCODE: 403 });
return onEnded();
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator['return']) {
_iterator['return']();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
}
}, {
key: 'load',
value: function load(url) {
var _this10 = this;
_vastClient2['default'].client.get(url.slice('VAST:'.length), { withCredentials: true }, function (response, error) {
if (error) {
return _this10.props.onError(error);
}
_this10.parseResponse(response);
var tracker = _this10.state.tracker;
if (tracker) {
tracker.on('clickthrough', _this10.openAdLink);
}
});
}
// todo: add skip functionality
}, {
key: 'skip',
value: function skip() {
var onEnded = this.props.onEnded,
tracker = this.state.tracker;
if (tracker) {
tracker.skip();
}
onEnded();
}
}, {
key: 'play',
value: function play() {
this.container.play();
}
}, {
key: 'pause',
value: function pause() {
this.container.pause();
}
}, {
key: 'stop',
value: function stop() {
this.container.stop();
}
// only allow rewind
}, {
key: 'seekTo',
value: function seekTo(seconds) {
if (seconds < this.container.getCurrentTime()) {
this.container.seekTo(seconds);
}
}
}, {
key: 'setVolume',
value: function setVolume(fraction) {
this.container.setVolume(fraction);
}
}, {
key: 'getDuration',
value: function getDuration() {
return this.container.getDuration();
}
}, {
key: 'getCurrentTime',
value: function getCurrentTime() {
return this.container.getCurrentTime();
}
}, {
key: 'getSecondsLoaded',
value: function getSecondsLoaded() {
return this.container.getSecondsLoaded();
}
}, {
key: 'openAdLink',
value: function openAdLink(url) {
window.open(url, '_blank');
}
// track ended
// track error
// track pause
// track play
// track load and duration
// track volume change
}, {
key: 'render',
value: function render() {
var _state = this.state,
sources = _state.sources,
clickTrackingURLTemplate = _state.tracker;
var _props = this.props,
width = _props.width,
height = _props.height;
var wrapperStyle = {
cursor: clickTrackingURLTemplate ? 'pointer' : 'default',
height: '100%'
};
var videoStyle = {
width: width === 'auto' ? width : '100%',
height: height === 'auto' ? height : '100%'
};
return sources.length ? _react2['default'].createElement(
'div',
{ onClick: this.onAdClick, style: wrapperStyle },
_react2['default'].createElement(_FilePlayer.FilePlayer, _extends({}, this.props, {
onEnded: this.onEnded,
onError: this.onError,
onPause: this.onPause,
onPlay: this.onPlay,
onProgress: this.onProgress,
onReady: this.onReady,
onVolumeChange: this.onVolumeChange,
ref: this.ref,
style: videoStyle,
url: this.state.sources[0].src
}))
) : null;
}
}]);
return VAST;
}(_react.Component);
VAST.displayName = 'VAST';
VAST.canPlay = function (url) {
return MATCH_URL.test(url);
};
exports['default'] = (0, _singlePlayer2['default'])(VAST);