inferno-youtube
Version:
inferno.js powered YouTube player component
326 lines (258 loc) • 11.6 kB
JavaScript
;
function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; }
var _classCallCheck = _interopDefault(require('@babel/runtime/helpers/classCallCheck'));
var _createClass = _interopDefault(require('@babel/runtime/helpers/createClass'));
var _assertThisInitialized = _interopDefault(require('@babel/runtime/helpers/assertThisInitialized'));
var _inherits = _interopDefault(require('@babel/runtime/helpers/inherits'));
var _possibleConstructorReturn = _interopDefault(require('@babel/runtime/helpers/possibleConstructorReturn'));
var _getPrototypeOf = _interopDefault(require('@babel/runtime/helpers/getPrototypeOf'));
var _defineProperty = _interopDefault(require('@babel/runtime/helpers/defineProperty'));
var inferno = require('inferno');
function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = _getPrototypeOf(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) { symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); } keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
var youTubePlayer = require('youtube-player');
var isEqual = require('fast-deep-equal');
/**
* Check whether a `props` change should result in the video being updated.
*
* @param {Object} prevProps
* @param {Object} props
*/
function shouldUpdateVideo(prevProps, props) {
// A changing video should always trigger an update
if (prevProps.videoId !== props.videoId) {
return true;
} // Otherwise, a change in the start/end time playerVars also requires a player
// update.
var prevVars = prevProps.opts.playerVars || {};
var vars = props.opts.playerVars || {};
return prevVars.start !== vars.start || prevVars.end !== vars.end;
}
/**
* Neutralise API options that only require a video update, leaving only options
* that require a player reset. The results can then be compared to see if a
* player reset is necessary.
*
* @param {Object} opts
*/
function filterResetOptions(opts) {
return _objectSpread(_objectSpread({}, opts), {}, {
playerVars: _objectSpread(_objectSpread({}, opts.playerVars), {}, {
autoplay: 0,
start: 0,
end: 0
})
});
}
/**
* Check whether a `props` change should result in the player being reset.
* The player is reset when the `props.opts` change, except if the only change
* is in the `start` and `end` playerVars, because a video update can deal with
* those.
*
* @param {Object} prevProps
* @param {Object} props
*/
function shouldResetPlayer(prevProps, props) {
return !isEqual(filterResetOptions(prevProps.opts), filterResetOptions(props.opts));
}
/**
* Check whether a props change should result in an id or className update.
*
* @param {Object} prevProps
* @param {Object} props
*/
function shouldUpdatePlayer(prevProps, props) {
return prevProps.id === props.id || prevProps.className === props.className;
}
var YouTube = /*#__PURE__*/function (_Component) {
_inherits(YouTube, _Component);
var _super = _createSuper(YouTube);
/*
static propTypes = {
videoId: PropTypes.string.isRequired,
// custom ID for player element
id: PropTypes.string,
// custom class name for player element
className: PropTypes.string,
// custom class name for player container element
containerClassName: PropTypes.string,
// https://developers.google.com/youtube/iframe_api_reference#Loading_a_Video_Player
opts: PropTypes.objectOf(PropTypes.any),
// event subscriptions
onReady: PropTypes.func,
onError: PropTypes.func,
onPlay: PropTypes.func,
onPause: PropTypes.func,
onEnd: PropTypes.func,
onStateChange: PropTypes.func,
onPlaybackRateChange: PropTypes.func,
onPlaybackQualityChange: PropTypes.func,
};
*/
/**
* Expose PlayerState constants for convenience. These constants can also be
* accessed through the global YT object after the YouTube IFrame API is instantiated.
* https://developers.google.com/youtube/iframe_api_reference#onStateChange
*/
function YouTube(props) {
var _this;
_classCallCheck(this, YouTube);
_this = _super.call(this, props);
_defineProperty(_assertThisInitialized(_this), "onPlayerReady", function (event) {
return _this.props.onReady(event);
});
_defineProperty(_assertThisInitialized(_this), "onPlayerError", function (event) {
return _this.props.onError(event);
});
_defineProperty(_assertThisInitialized(_this), "onPlayerStateChange", function (event) {
_this.props.onStateChange(event);
switch (event.data) {
case YouTube.PlayerState.ENDED:
_this.props.onEnd(event);
break;
case YouTube.PlayerState.PLAYING:
_this.props.onPlay(event);
break;
case YouTube.PlayerState.PAUSED:
_this.props.onPause(event);
break;
}
});
_defineProperty(_assertThisInitialized(_this), "onPlayerPlaybackRateChange", function (event) {
return _this.props.onPlaybackRateChange(event);
});
_defineProperty(_assertThisInitialized(_this), "onPlayerPlaybackQualityChange", function (event) {
return _this.props.onPlaybackQualityChange(event);
});
_defineProperty(_assertThisInitialized(_this), "createPlayer", function () {
// do not attempt to create a player server-side, it won't work
if (typeof document === 'undefined') return; // create player
var playerOpts = _objectSpread(_objectSpread({}, _this.props.opts), {}, {
// preload the `videoId` video if one is already given
videoId: _this.props.videoId
});
_this.internalPlayer = youTubePlayer(_this.container, playerOpts); // attach event handlers
_this.internalPlayer.on('ready', _this.onPlayerReady);
_this.internalPlayer.on('error', _this.onPlayerError);
_this.internalPlayer.on('stateChange', _this.onPlayerStateChange);
_this.internalPlayer.on('playbackRateChange', _this.onPlayerPlaybackRateChange);
_this.internalPlayer.on('playbackQualityChange', _this.onPlayerPlaybackQualityChange);
});
_defineProperty(_assertThisInitialized(_this), "resetPlayer", function () {
return _this.internalPlayer.destroy().then(_this.createPlayer);
});
_defineProperty(_assertThisInitialized(_this), "updatePlayer", function () {
_this.internalPlayer.getIframe().then(function (iframe) {
if (_this.props.id) iframe.setAttribute('id', _this.props.id);else iframe.removeAttribute('id');
if (_this.props.className) iframe.setAttribute('class', _this.props.className);else iframe.removeAttribute('class');
});
});
_defineProperty(_assertThisInitialized(_this), "updateVideo", function () {
if (typeof _this.props.videoId === 'undefined' || _this.props.videoId === null) {
_this.internalPlayer.stopVideo();
return;
} // set queueing options
var autoplay = false;
var opts = {
videoId: _this.props.videoId
};
if ('playerVars' in _this.props.opts) {
autoplay = _this.props.opts.playerVars.autoplay === 1;
if ('start' in _this.props.opts.playerVars) {
opts.startSeconds = _this.props.opts.playerVars.start;
}
if ('end' in _this.props.opts.playerVars) {
opts.endSeconds = _this.props.opts.playerVars.end;
}
} // if autoplay is enabled loadVideoById
if (autoplay) {
_this.internalPlayer.loadVideoById(opts);
return;
} // default behaviour just cues the video
_this.internalPlayer.cueVideoById(opts);
});
_defineProperty(_assertThisInitialized(_this), "refContainer", function (container) {
_this.container = container;
});
_this.container = null;
_this.internalPlayer = null;
return _this;
}
_createClass(YouTube, [{
key: "componentDidMount",
value: function componentDidMount() {
this.createPlayer();
}
}, {
key: "componentDidUpdate",
value: function componentDidUpdate(prevProps) {
if (shouldUpdatePlayer(prevProps, this.props)) {
this.updatePlayer();
}
if (shouldResetPlayer(prevProps, this.props)) {
this.resetPlayer();
}
if (shouldUpdateVideo(prevProps, this.props)) {
this.updateVideo();
}
}
}, {
key: "componentWillUnmount",
value: function componentWillUnmount() {
/**
* Note: The `youtube-player` package that is used promisifies all Youtube
* Player API calls, which introduces a delay of a tick before it actually
* gets destroyed. Since React attempts to remove the element instantly
* this method isn't quick enough to reset the container element.
*/
this.internalPlayer.destroy();
}
/**
* https://developers.google.com/youtube/iframe_api_reference#onReady
*
* @param {Object} event
* @param {Object} target - player object
*/
}, {
key: "render",
value: function render() {
if (this.props.containerClassName || this.props.children) {
return inferno.createVNode(1, "div", this.props.containerClassName, [inferno.createVNode(1, "div", this.props.className, null, 1, {
"id": this.props.id
}, null, this.refContainer), this.props.children], 0);
} else {
return inferno.createVNode(1, "div", this.props.className, null, 1, {
"id": this.props.id
}, null, this.refContainer);
}
}
}]);
return YouTube;
}(inferno.Component);
_defineProperty(YouTube, "defaultProps", {
id: null,
className: null,
opts: {},
containerClassName: '',
onReady: function onReady() {},
onError: function onError() {},
onPlay: function onPlay() {},
onPause: function onPause() {},
onEnd: function onEnd() {},
onStateChange: function onStateChange() {},
onPlaybackRateChange: function onPlaybackRateChange() {},
onPlaybackQualityChange: function onPlaybackQualityChange() {}
});
_defineProperty(YouTube, "PlayerState", {
UNSTARTED: -1,
ENDED: 0,
PLAYING: 1,
PAUSED: 2,
BUFFERING: 3,
CUED: 5
});
module.exports = YouTube;
//# sourceMappingURL=index.cjs.js.map