UNPKG

inferno-youtube

Version:

inferno.js powered YouTube player component

326 lines (258 loc) 11.6 kB
'use strict'; 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