From f4569a329520f4c03f8753a798b8f610ff144aaa Mon Sep 17 00:00:00 2001 From: Travis Arnold Date: Sun, 28 Feb 2016 22:16:54 -0800 Subject: [PATCH] 0.2.0 release --- CHANGELOG.md | 3 + README.md | 35 +- bower.json | 2 +- dist/react-media-player.js | 2218 ++++++++++++++++-------------- dist/react-media-player.min.js | 3 +- lib/Media.js | 220 +++ lib/controls/CurrentTime.js | 54 + lib/controls/Duration.js | 54 + lib/controls/Fullscreen.js | 63 + lib/controls/MuteUnmute.js | 63 + lib/controls/PlayPause.js | 63 + lib/controls/Progress.js | 48 + lib/controls/SeekBar.js | 78 ++ lib/controls/Volume.js | 65 + lib/controls/exports.js | 49 + lib/react-media-player.js | 26 + lib/utils/exit-fullscreen.js | 12 + lib/utils/exports.js | 14 + lib/utils/format-time.js | 21 + lib/utils/get-file-extension.js | 12 + lib/utils/get-vendor.js | 48 + lib/utils/get-vimeo-id.js | 17 + lib/utils/get-youtube-id.js | 16 + lib/utils/load-api.js | 25 + lib/utils/request-fullscreen.js | 12 + lib/vendors/Audio.js | 59 + lib/vendors/HTML5.js | 114 ++ lib/vendors/Video.js | 59 + lib/vendors/Vimeo.js | 180 +++ lib/vendors/Youtube.js | 205 +++ lib/vendors/vendor-prop-types.js | 16 + package.json | 2 +- 32 files changed, 2853 insertions(+), 1003 deletions(-) create mode 100644 CHANGELOG.md create mode 100644 lib/Media.js create mode 100644 lib/controls/CurrentTime.js create mode 100644 lib/controls/Duration.js create mode 100644 lib/controls/Fullscreen.js create mode 100644 lib/controls/MuteUnmute.js create mode 100644 lib/controls/PlayPause.js create mode 100644 lib/controls/Progress.js create mode 100644 lib/controls/SeekBar.js create mode 100644 lib/controls/Volume.js create mode 100644 lib/controls/exports.js create mode 100644 lib/react-media-player.js create mode 100644 lib/utils/exit-fullscreen.js create mode 100644 lib/utils/exports.js create mode 100644 lib/utils/format-time.js create mode 100644 lib/utils/get-file-extension.js create mode 100644 lib/utils/get-vendor.js create mode 100644 lib/utils/get-vimeo-id.js create mode 100644 lib/utils/get-youtube-id.js create mode 100644 lib/utils/load-api.js create mode 100644 lib/utils/request-fullscreen.js create mode 100644 lib/vendors/Audio.js create mode 100644 lib/vendors/HTML5.js create mode 100644 lib/vendors/Video.js create mode 100644 lib/vendors/Vimeo.js create mode 100644 lib/vendors/Youtube.js create mode 100644 lib/vendors/vendor-prop-types.js diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..eee4e6d --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,3 @@ +## CHANGELOG +### 0.2.0 +Complete rewrite, better API, use of context in place of spreading props. diff --git a/README.md b/README.md index 31ef790..acaa7db 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,43 @@ -## React Media Player 0.1.0 +## React Media Player 0.2.0 React media container component to help build video & audio players. +## Docs Coming Soon + +Please refer to `example/index.jsx` until then. + +## Warning + +This library makes heavy use of [context](https://facebook.github.io/react/docs/context.html), please be advised that with new releases of React the way context is handled in this library is subject to change. + +## Running Locally + +clone repo + +`git clone git@github.com:souporserious/react-media-player.git` + +move into folder + +`cd ~/react-media-player` + +install dependencies + +`npm install` + +run dev mode + +`npm run dev` + +open your browser and visit: `http://localhost:8080/` + ## TODOS -- [ ] Loading new videos for Youtube/Vimeo -- [ ] Loading state to allow loaders for loading big/new media - [ ] Show time/thumbnail preview when hovering seekbar - [ ] Subtitle support - [ ] Forward / Rewind public methods - [ ] Playback speed option - [ ] Keyboard friendly - [ ] ARIA a11y ready -- [ ] Move controls into addons - [ ] Add tests - [ ] Check browser support -- [ ] Add SoundCloud API support \ No newline at end of file +- [ ] Add SoundCloud API support diff --git a/bower.json b/bower.json index 55770a0..ffea4f8 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "react-media-player", - "version": "0.1.0", + "version": "0.2.0", "homepage": "https://github.com/souporserious/react-media-player", "authors": [ "Travis Arnold " diff --git a/dist/react-media-player.js b/dist/react-media-player.js index b9d311b..f206c46 100644 --- a/dist/react-media-player.js +++ b/dist/react-media-player.js @@ -7,7 +7,7 @@ exports["ReactMediaPlayer"] = factory(require("React"), require("ReactDOM")); else root["ReactMediaPlayer"] = factory(root["React"], root["ReactDOM"]); -})(this, function(__WEBPACK_EXTERNAL_MODULE_4__, __WEBPACK_EXTERNAL_MODULE_5__) { +})(this, function(__WEBPACK_EXTERNAL_MODULE_2__, __WEBPACK_EXTERNAL_MODULE_3__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; @@ -56,1317 +56,1370 @@ return /******/ (function(modules) { // webpackBootstrap 'use strict'; - Object.defineProperty(exports, '__esModule', { + Object.defineProperty(exports, "__esModule", { value: true }); + exports.utils = exports.controls = exports.Media = undefined; - 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; } } + var _Media2 = __webpack_require__(1); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + var _Media3 = _interopRequireDefault(_Media2); - var _formatTime = __webpack_require__(1); + var _exports = __webpack_require__(17); - var _formatTime2 = _interopRequireDefault(_formatTime); + var _controls = _interopRequireWildcard(_exports); - var _Media2 = __webpack_require__(2); + var _exports2 = __webpack_require__(27); - var _Media3 = _interopRequireDefault(_Media2); + var _utils = _interopRequireWildcard(_exports2); - exports.Media = _Media3['default']; + 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; } } - var _controlsControlsJs = __webpack_require__(13); - - var _controls = _interopRequireWildcard(_controlsControlsJs); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + exports.Media = _Media3.default; exports.controls = _controls; - var utils = { - formatTime: _formatTime2['default'] - }; - exports.utils = utils; + exports.utils = _utils; /***/ }, /* 1 */ -/***/ function(module, exports) { +/***/ function(module, exports, __webpack_require__) { 'use strict'; - Object.defineProperty(exports, '__esModule', { + Object.defineProperty(exports, "__esModule", { value: true }); - exports['default'] = formatTime; - function formatTime(current) { - var minutes = Math.floor(current / 60); - var seconds = Math.floor(current % 60); + 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; }; - seconds = seconds >= 10 ? seconds : '0' + seconds; - minutes = minutes >= 10 ? minutes : minutes; + 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; }; }(); - return minutes + ':' + seconds; - } + var _react = __webpack_require__(2); - module.exports = exports['default']; + var _react2 = _interopRequireDefault(_react); -/***/ }, -/* 2 */ -/***/ function(module, exports, __webpack_require__) { + var _reactDom = __webpack_require__(3); - 'use strict'; + var _reactDom2 = _interopRequireDefault(_reactDom); - Object.defineProperty(exports, '__esModule', { - value: true - }); + var _getVendor = __webpack_require__(4); - 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 _getVendor2 = _interopRequireDefault(_getVendor); - var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; desc = parent = getter = undefined; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + var _requestFullscreen = __webpack_require__(15); - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + var _requestFullscreen2 = _interopRequireDefault(_requestFullscreen); - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + var _exitFullscreen = __webpack_require__(16); - 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) subClass.__proto__ = superClass; } + var _exitFullscreen2 = _interopRequireDefault(_exitFullscreen); - var _react = __webpack_require__(4); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - var _react2 = _interopRequireDefault(_react); + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - var _reactDom = __webpack_require__(5); + 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; } - var _reactDom2 = _interopRequireDefault(_reactDom); + 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 _reactLibShallowCompare = __webpack_require__(6); + var Media = function (_Component) { + _inherits(Media, _Component); - var _reactLibShallowCompare2 = _interopRequireDefault(_reactLibShallowCompare); + function Media() { + var _Object$getPrototypeO; - var _loadApi = __webpack_require__(8); + var _temp, _this, _ret; - var _loadApi2 = _interopRequireDefault(_loadApi); + _classCallCheck(this, Media); - var _getVendor = __webpack_require__(3); + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } - var _getVendor2 = _interopRequireDefault(_getVendor); + return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(Media)).call.apply(_Object$getPrototypeO, [this].concat(args))), _this), _this.state = { + currentTime: 0, + progress: 0, + duration: 0, + volume: 1, + isLoading: true, + isPlaying: false, + isMuted: false, + isFullscreen: false + }, _this._lastVolume = 0, _this._handlePlay = function () { + _this._player.play(); + }, _this._handlePause = function () { + _this._player.pause(); + }, _this._handlePlayPause = function () { + if (!_this.state.isPlaying) { + _this._player.play(); + } else { + _this._player.pause(); + } + }, _this._handleStop = function () { + _this._player.stop(); + }, _this._handleSeekTo = function (currentTime) { + _this._player.seekTo(currentTime); + }, _this._handleMute = function (isMuted) { + if (isMuted) { + _this._lastVolume = _this.state.volume; + _this._player.setVolume(0); + } else { + var volume = _this._lastVolume > 0 ? _this._lastVolume : 0.1; + _this._player.setVolume(volume); + } + _this._player.mute(isMuted); + }, _this._handleMuteUnmute = function () { + _this._handleMute(!_this.state.isMuted); + }, _this._handleSetVolume = function (volume) { + var isMuted = false; - var _getYoutubeId = __webpack_require__(9); + if (volume <= 0) { + isMuted = true; + } - var _getYoutubeId2 = _interopRequireDefault(_getYoutubeId); + if (isMuted !== _this.state.isMuted) { + _this._handleMute(isMuted); + } else { + _this._lastVolume = volume; + } - var _getVimeoId = __webpack_require__(10); + _this._player.setVolume(volume); + }, _this._handleFullscreen = function () { + var isFullscreen = _this.state.isFullscreen; - var _getVimeoId2 = _interopRequireDefault(_getVimeoId); - var _Player = __webpack_require__(11); + if (!isFullscreen) { + _reactDom2.default.findDOMNode(_this._player)[_requestFullscreen2.default](); + } else { + document[_exitFullscreen2.default](); + } - var _Player2 = _interopRequireDefault(_Player); + _this.setState({ isFullscreen: !isFullscreen }); + }, _temp), _possibleConstructorReturn(_this, _ret); + } - var apiFlags = { - youtube: false, - vimeo: false + _createClass(Media, [{ + key: 'getChildContext', + value: function getChildContext() { + return _extends({}, this.state, { + play: this._handlePlay, + pause: this._handlePause, + playPause: this._handlePlayPause, + stop: this._handleStop, + seekTo: this._handleSeekTo, + mute: this._handleMute, + muteUnmute: this._handleMuteUnmute, + setVolume: this._handleSetVolume, + fullscreen: this._handleFullscreen + }); + } + }, { + key: 'componentWillUpdate', + value: function componentWillUpdate(nextProps) { + // clean state if the video has changed + if (this.props.src !== nextProps.src) { + this.setState({ + currentTime: 0, + progress: 0, + duration: 0, + isPlaying: false, + + // TODO: figure out how to keep these settings + // getting error because element isn't available when trying to set them + // this occurs on componentDidUpdate + volume: 1, + isMuted: false, + isFullscreen: false + }); + } + } + }, { + key: 'render', + value: function render() { + var _this2 = this; + + var _props = this.props; + var src = _props.src; + var children = _props.children; + + var Player = (0, _getVendor2.default)(src); + + return Player && children((0, _react.createElement)(Player, { + ref: function ref(c) { + return _this2._player = c; + }, + src: src, + onReady: function onReady() { + return _this2.setState({ isLoading: false }); + }, + onPlaying: function onPlaying(isPlaying) { + return _this2.setState({ isPlaying: isPlaying }); + }, + onDuration: function onDuration(duration) { + return _this2.setState({ duration: duration }); + }, + onProgress: function onProgress(progress) { + return _this2.setState({ progress: progress }); + }, + onTimeUpdate: function onTimeUpdate(currentTime) { + return _this2.setState({ currentTime: currentTime }); + }, + onMute: function onMute(isMuted) { + return _this2.setState({ isMuted: isMuted }); + }, + onVolumeChange: function onVolumeChange(volume) { + return _this2.setState({ volume: volume }); + } + })); + } + }]); + + return Media; + }(_react.Component); + + Media.propTypes = { + src: _react.PropTypes.string, + children: _react.PropTypes.func + }; + Media.childContextTypes = { + // State + currentTime: _react.PropTypes.number, + progress: _react.PropTypes.number, + duration: _react.PropTypes.number, + volume: _react.PropTypes.number, + isLoading: _react.PropTypes.bool, + isPlaying: _react.PropTypes.bool, + isMuted: _react.PropTypes.bool, + isFullscreen: _react.PropTypes.bool, + + // Methods + play: _react.PropTypes.func, + pause: _react.PropTypes.func, + playPause: _react.PropTypes.func, + stop: _react.PropTypes.func, + seekTo: _react.PropTypes.func, + mute: _react.PropTypes.func, + muteUnmute: _react.PropTypes.func, + setVolume: _react.PropTypes.func, + fullscreen: _react.PropTypes.func }; + exports.default = Media; - var Media = (function (_Component) { - _inherits(Media, _Component); +/***/ }, +/* 2 */ +/***/ function(module, exports) { - function Media() { - var _this = this; + module.exports = __WEBPACK_EXTERNAL_MODULE_2__; - _classCallCheck(this, Media); +/***/ }, +/* 3 */ +/***/ function(module, exports) { - _get(Object.getPrototypeOf(Media.prototype), 'constructor', this).apply(this, arguments); + module.exports = __WEBPACK_EXTERNAL_MODULE_3__; - this.state = { - player: null, - vendor: null, - playing: false, - duration: 0, - current: 0, - progress: 0, - muted: false, - volume: 1, - fullscreen: false - }; - this._src = null; - this._currentProgressID = null; - this._currentYTProgressID = null; - this._currentTimeID = null; - this._lastVolume = 0; - - this.play = function () { - var _state = _this.state; - var player = _state.player; - var vendor = _state.vendor; - - switch (vendor) { - case 'youtube': - player.playVideo(); - _this._currentTimeID = requestAnimationFrame(_this._getCurrentTime); - break; - case 'vimeo': - player.api('play'); - break; - default: - player.play(); - } - }; +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { - this.pause = function () { - var _state2 = _this.state; - var player = _state2.player; - var vendor = _state2.vendor; + 'use strict'; - switch (vendor) { - case 'youtube': - player.pauseVideo(); - cancelAnimationFrame(_this._currentTimeID); - break; - case 'vimeo': - player.api('pause'); - break; - default: - player.pause(); - } - }; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = getVendor; - this.playPause = function () { - var playing = _this.state.playing; + var _getFileExtension = __webpack_require__(5); - if (!playing) { - _this.play(); - } else { - _this.pause(); - } - }; + var _getFileExtension2 = _interopRequireDefault(_getFileExtension); - this.stop = function () { - var player = _this.state.player; + var _Youtube = __webpack_require__(6); - player.pause(); - player.currentTime = 0; - }; + var _Youtube2 = _interopRequireDefault(_Youtube); - this.setCurrentTime = function (current) { - var _state3 = _this.state; - var player = _state3.player; - var vendor = _state3.vendor; + var _Vimeo = __webpack_require__(10); - if (vendor === 'youtube') { - player.seekTo(current); - } else if (vendor === 'vimeo') { - player.api('seekTo', current); - } else { - player.currentTime = current; - } + var _Vimeo2 = _interopRequireDefault(_Vimeo); - _this._setCurrentTime(current); - }; - - this.muteUnmute = function () { - var _state4 = _this.state; - var player = _state4.player; - var vendor = _state4.vendor; - var muted = _state4.muted; - var volume = _state4.volume; - - if (!muted) { - switch (vendor) { - case 'youtube': - player.mute(); - break; - default: - player.muted = true; - } + var _Video = __webpack_require__(12); - // store volume for un-mute - _this._lastVolume = volume; + var _Video2 = _interopRequireDefault(_Video); - // if muted the volume should be set to 0 - _this.setVolume(0); + var _Audio = __webpack_require__(14); - _this._setMute(true); - } else { + var _Audio2 = _interopRequireDefault(_Audio); - switch (vendor) { - case 'youtube': - player.unMute(); - break; - default: - player.muted = false; - } + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - // if unmuted set to last volume - _this.setVolume(_this._lastVolume); + var VIDEO_EXTENSIONS = ['mp4', 'm4v', 'webm', 'ogv']; + var AUDIO_EXTENSIONS = ['mp3', 'm4a', 'wav', 'ogg']; - _this._setMute(false); - } - }; + function getVendor(src) { + var ext = (0, _getFileExtension2.default)(src); + + if (src.indexOf('youtube.com') > -1 || src.indexOf('youtu.be') > -1) { + return _Youtube2.default; + } else if (src.indexOf('vimeo.com') > -1) { + return _Vimeo2.default; + } else if (VIDEO_EXTENSIONS.indexOf(ext) > -1) { + return _Video2.default; + } else if (AUDIO_EXTENSIONS.indexOf(ext) > -1) { + return _Audio2.default; + } else { + console.warn('Warning: Player was not rendered. Source could not be determined.'); + return null; + } + } - this.setVolume = function (volume) { - var _state5 = _this.state; - var player = _state5.player; - var vendor = _state5.vendor; +/***/ }, +/* 5 */ +/***/ function(module, exports) { - var muted = false; + 'use strict'; - if (volume <= 0) { - muted = true; - } + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = getFileExtension; + // thanks to: http://stackoverflow.com/a/6997591/1461204 + function getFileExtension(url) { + var file = url.substr(url.lastIndexOf('/') + 1).split('?')[0]; + var extPos = file.lastIndexOf('.'); + return extPos > -1 && file.substr(extPos + 1); + } - if (vendor === 'youtube') { - player.setVolume(volume * 100); - } else if (vendor === 'vimeo') { - player.api('setVolume', volume); - } else { - player.volume = volume; - } +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { - _this._setVolume(volume); - _this._setMute(muted); + 'use strict'; - if (muted) { - switch (vendor) { - case 'youtube': - player.mute(); - break; - default: - player.muted = true; - } - } else { - switch (vendor) { - case 'youtube': - player.unMute(); - break; - default: - player.muted = false; - } - } - }; - - this.toggleFullscreen = function () { - if (!_this.state.fullscreen) { - var n = _this.state.playerNode; - - if (n.requestFullscreen) { - n.requestFullscreen(); - } else if (n.webkitRequestFullscreen) { - n.webkitRequestFullscreen(); - } else if (n.mozRequestFullScreen) { - n.mozRequestFullScreen(); - } else if (n.msRequestFullscreen) { - n.msRequestFullscreen(); - } - } else { - var d = document; - - if (d.exitFullscreen) { - d.exitFullscreen(); - } else if (d.webkitExitFullscreen) { - d.webkitExitFullscreen(); - } else if (d.mozCancelFullScreen) { - d.mozCancelFullScreen(); - } else if (d.msExitFullscreen) { - d.msExitFullscreen(); - } - } - }; + Object.defineProperty(exports, "__esModule", { + value: true + }); - this.load = function (src) { - var player = _this.state.player; + 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 vendor = (0, _getVendor2['default'])(src); + var _react = __webpack_require__(2); - if (['youtube', 'vimeo'].indexOf(vendor)) { - console.log('fug'); - } + var _react2 = _interopRequireDefault(_react); - // pause player - player.pause(); - - // test support - // !!!! need to check canPlayType on init - if (player.canPlayType('video/mp4')) { - player.setAttribute('src', src); - } else if (player.canPlayType('video/webm')) { - player.setAttribute('src', setupURL(src, 'webm')); - } else if (player.canPlayType('video/ogg')) { - player.setAttribute('src', setupURL(src, 'ogv')); - } + var _loadApi = __webpack_require__(7); - // load new media - player.load(); + var _loadApi2 = _interopRequireDefault(_loadApi); - // play new media - player.play(); - }; + var _getYoutubeId = __webpack_require__(8); - this._getCurrentProgress = function () { - var player = _this.state.player; + var _getYoutubeId2 = _interopRequireDefault(_getYoutubeId); - var progress = 0; + var _vendorPropTypes = __webpack_require__(9); - if (player.buffered.length > 0) { - progress = player.buffered.end(0) / player.duration; - } + var _vendorPropTypes2 = _interopRequireDefault(_vendorPropTypes); - _this._setProgress(progress); + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } - if (progress < 1) { - _this._currentProgressID = requestAnimationFrame(_this._getCurrentProgress); - } - }; + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } - this._getCurrentYTProgress = function () { - var player = _this.state.player; + 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; } - var progress = player.getVideoLoadedFraction(); + 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; } - _this._setProgress(progress); + var isAPILoaded = false; - if (progress < 1) { - _this._currentYTProgressID = requestAnimationFrame(_this._getCurrentYTProgress); - } - }; + var Youtube = function (_Component) { + _inherits(Youtube, _Component); + + function Youtube() { + var _Object$getPrototypeO; - this._getCurrentTime = function () { - var player = _this.state.player; + var _temp, _this, _ret; - _this._setCurrentTime(player.getCurrentTime()); + _classCallCheck(this, Youtube); - _this._currentTimeID = requestAnimationFrame(_this._getCurrentTime); - }; + for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { + args[_key] = arguments[_key]; + } + + return _ret = (_temp = (_this = _possibleConstructorReturn(this, (_Object$getPrototypeO = Object.getPrototypeOf(Youtube)).call.apply(_Object$getPrototypeO, [this].concat(args))), _this), _this._progressId = null, _this._timeUpdateId = null, _this._handleProgress = function () { + var progress = _this._player.getVideoLoadedFraction() || 0; + + _this.props.onProgress(progress); + + if (_this._progressId && progress < 1) { + _this._progressId = requestAnimationFrame(_this._handleProgress); + } + }, _this._handleTimeUpdate = function () { + _this.props.onTimeUpdate(_this._player.getCurrentTime() || 0); + + if (_this._timeUpdateId) { + _this._timeUpdateId = requestAnimationFrame(_this._handleTimeUpdate); + } + }, _temp), _possibleConstructorReturn(_this, _ret); } - _createClass(Media, [{ + _createClass(Youtube, [{ key: 'componentDidMount', value: function componentDidMount() { - this._setPlayer(this._setupAPI); + var _this2 = this; + + if (!isAPILoaded) { + (0, _loadApi2.default)('http://www.youtube.com/player_api'); + + window.onYouTubeIframeAPIReady = function () { + _this2._createPlayer(); + isAPILoaded = true; + }; + } else { + this._createPlayer(); + } } }, { - key: 'shouldComponentUpdate', - value: function shouldComponentUpdate(nextProps, nextState) { - return (0, _reactLibShallowCompare2['default'])(this, nextProps, nextState); + key: 'componentWillReceiveProps', + value: function componentWillReceiveProps(nextProps) { + if (nextProps.src !== this.props.src) { + var videoId = (0, _getYoutubeId2.default)(nextProps.src); + this._player.cueVideoById(videoId); + } } }, { key: 'componentWillUnmount', - value: function componentWillUnmount() {} - }, { - key: '_setPlaying', + value: function componentWillUnmount() { + if (this._progressId) { + cancelAnimationFrame(this._progressId); + } - // Props API - value: function _setPlaying(playing) { - var _this2 = this; + if (this._timeUpdateId) { + cancelAnimationFrame(this._timeUpdateId); + } - if (playing === this.state.playing) return; - this.setState({ playing: playing }, function () { - _this2.props.onPlaying(playing); - }); + if (this._player) { + this._player.destroy(); + } } }, { - key: '_setProgress', - value: function _setProgress(progress) { - var _this3 = this; + key: '_createPlayer', + value: function _createPlayer() { + var videoId = (0, _getYoutubeId2.default)(this.props.src); - if (progress === this.state.progress) return; - this.setState({ progress: progress }, function () { - _this3.props.getProgress(progress); + this._player = new YT.Player(this._node, { + videoId: videoId, + events: this._events(), + playerVars: { + controls: 0, + showinfo: 0, + modestbranding: 1 + } }); } }, { - key: '_setCurrentTime', - value: function _setCurrentTime(current) { - var _this4 = this; + key: '_events', + value: function _events() { + var _this3 = this; - if (current === this.state.current) return; - this.setState({ current: current }, function () { - _this4.props.getCurrentTime(current); - }); + return { + onReady: function onReady() { + _this3.props.onDuration(_this3._player.getDuration()); + _this3.props.onReady(); + }, + onStateChange: function onStateChange(_ref) { + var data = _ref.data; + + var isPlaying = data === 1; + + if (isPlaying) { + _this3._timeUpdateId = requestAnimationFrame(_this3._handleTimeUpdate); + } else { + cancelAnimationFrame(_this3._timeUpdateId); + _this3._timeUpdateId = null; + + cancelAnimationFrame(_this3._progressId); + _this3._progressId = null; + } + + // start fetching progress when playing or buffering + if (isPlaying || data === 3) { + _this3._progressId = requestAnimationFrame(_this3._handleProgress); + } + + _this3.props.onPlaying(isPlaying); + } + }; } }, { - key: '_setDuration', - value: function _setDuration(duration) { - var _this5 = this; - - if (duration === this.state.duration) return; - this.setState({ duration: duration }, function () { - _this5.props.getDuration(duration); - }); + key: 'play', + value: function play() { + this._player.playVideo(); } }, { - key: '_setMute', - value: function _setMute(muted) { - var _this6 = this; - - if (muted === this.state.muted) return; - this.setState({ muted: muted }, function () { - _this6.props.onMute(muted); - }); + key: 'pause', + value: function pause() { + this._player.pauseVideo(); } }, { - key: '_setVolume', - value: function _setVolume(volume) { - var _this7 = this; - - if (volume === this.state.volume) return; - this.setState({ volume: volume }, function () { - _this7.props.onVolumeChange(volume); - }); + key: 'stop', + value: function stop() { + this._player.stopVideo(); } }, { - key: '_setFullscreen', - value: function _setFullscreen(fullscreen) { - var _this8 = this; - - if (fullscreen === this.state.fullscreen) return; - this.setState({ fullscreen: fullscreen }, function () { - _this8.props.onFullscreen(fullscreen); - }); + key: 'seekTo', + value: function seekTo(currentTime) { + this._player.seekTo(currentTime); } }, { - key: '_handleLoad', - - // need todo - value: function _handleLoad(src) { - var _this9 = this; - - this.setState({ src: src }, function () { - _this9.props.onChange(src); - }); + key: 'mute', + value: function mute(muted) { + if (muted) { + this._player.mute(); + } else { + this._player.unMute(); + } + this.props.onMute(muted); } }, { - key: '_setupYoutubeAPI', + key: 'setVolume', + value: function setVolume(volume) { + this._player.setVolume(+volume * 100); + this.props.onVolumeChange(+volume); + } + }, { + key: 'render', + value: function render() { + var _this4 = this; - // Private Methods - value: function _setupYoutubeAPI() { - var _this10 = this; + return _react2.default.createElement('div', { ref: function ref(c) { + return _this4._node = c; + } }); + } + }]); - var vendor = 'youtube'; - var api = 'http://www.youtube.com/player_api'; + return Youtube; + }(_react.Component); - // load the api if it hasn't been yet - if (!apiFlags[vendor]) { - (0, _loadApi2['default'])(api); + Youtube.propTypes = _vendorPropTypes2.default; + exports.default = Youtube; - // update flag - apiFlags[vendor] = true; - } +/***/ }, +/* 7 */ +/***/ function(module, exports) { - // create player when API is ready - window.onYouTubeIframeAPIReady = function () { - return _this10._createYoutubePlayer(); - }; - } - }, { - key: '_createYoutubePlayer', + 'use strict'; - // use youtube api to create player - value: function _createYoutubePlayer() { - var _this11 = this; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = loadAPI; + // load api asynchronously + function loadAPI(url, cb) { + // create script to be injected + var api = document.createElement('script'); - var videoId = (0, _getYoutubeId2['default'])(this._src); - var player = new YT.Player(this.state.player, { - videoId: videoId, - playerVars: { - controls: 0, - showinfo: 0, - modestbranding: 1 - } - }); + // load async + api.async = true; - this.setState({ player: player }, function () { - _this11._init(); - }); - } - }, { - key: '_setupVimeoAPI', - value: function _setupVimeoAPI() { - var vendor = 'vimeo'; - var api = 'https://f.vimeocdn.com/js/froogaloop2.min.js'; + // set source to vendors api + api.src = url; - // load the api if it hasn't been yet - if (!apiFlags[vendor]) { - (0, _loadApi2['default'])(api, vendor); + // append script to document head + document.head.appendChild(api); - // update flag - apiFlags[vendor] = true; - } + // callback after loaded + if (typeof cb === 'function') { + cb(); + } + } - // create player when API is ready - this._createVimeoPlayer(); - } - }, { - key: '_getVimeoPlayer', - value: function _getVimeoPlayer(id, cb) { - var request = new XMLHttpRequest(); +/***/ }, +/* 8 */ +/***/ function(module, exports) { - request.open('GET', 'https://vimeo.com/api/oembed.json?url=https%3A//vimeo.com/' + id, true); + 'use strict'; - request.onload = function () { - if (request.status >= 200 && request.status < 400) { - cb(JSON.parse(request.responseText)); - } - }; + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = getYoutubeId; + function getYoutubeId(url) { + var regExp = /.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=)([^#\&\?]*).*/; + var match = url.match(regExp); - request.send(); - } - }, { - key: '_createVimeoPlayer', - value: function _createVimeoPlayer() { - var _this12 = this; + if (match && match[1].length === 11) { + return match[1]; + } else { + throw 'Invalid Youtube ID provided'; + } + } - var player = this.state.player; +/***/ }, +/* 9 */ +/***/ function(module, exports, __webpack_require__) { - var videoId = (0, _getVimeoId2['default'])(this._src); + 'use strict'; - this._getVimeoPlayer(videoId, function (data) { - var parentNode = player.parentNode; + Object.defineProperty(exports, "__esModule", { + value: true + }); - // enable javascirpt API on the data html - data.html = data.html.replace(/(