react-player
Advanced tools
Comparing version 0.2.1 to 0.3.0
@@ -7,5 +7,13 @@ # Change Log | ||
* [Full commit list](https://github.com/CookPete/react-player/compare/v0.2.1...master) | ||
* [Full commit list](https://github.com/CookPete/react-player/compare/v0.3.0...master) | ||
### 0.3.0 | ||
* Released on **25 December 2015** 🎄 | ||
* Enable [multiple YouTube players](https://github.com/CookPete/react-player/issues/15) | ||
* Fix [YouTube and Vimeo autoplay bug](https://github.com/CookPete/react-player/issues/7) | ||
* [Full commit list](https://github.com/CookPete/react-player/compare/v0.2.1...0.3.0) | ||
### 0.2.1 | ||
@@ -12,0 +20,0 @@ |
@@ -11,4 +11,2 @@ 'use strict'; | ||
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'); } } | ||
@@ -20,8 +18,4 @@ | ||
var _propTypes = require('../propTypes'); | ||
var _props = require('../props'); | ||
var _propTypes2 = _interopRequireDefault(_propTypes); | ||
var UPDATE_FREQUENCY = 500; | ||
var Base = (function (_Component) { | ||
@@ -37,21 +31,6 @@ _inherits(Base, _Component); | ||
this.update = function () { | ||
var progress = {}; | ||
var loaded = _this.getFractionLoaded(); | ||
var played = _this.getFractionPlayed(); | ||
if (!_this.prevLoaded || loaded !== _this.prevLoaded) { | ||
progress.loaded = _this.prevLoaded = loaded; | ||
} | ||
if (!_this.prevPlayed || played !== _this.prevPlayed) { | ||
progress.played = _this.prevPlayed = played; | ||
} | ||
if (progress.loaded || progress.played) { | ||
_this.props.onProgress(progress); | ||
} | ||
_this.updateTimeout = setTimeout(_this.update, UPDATE_FREQUENCY); | ||
}; | ||
this.onReady = function () { | ||
_this.setVolume(_this.props.volume); | ||
if (_this.props.playing) { | ||
if (_this.props.playing || _this.preloading) { | ||
_this.preloading = false; | ||
_this.play(); | ||
@@ -65,4 +44,5 @@ } | ||
value: function componentDidMount() { | ||
this.play(this.props.url); | ||
this.update(); | ||
if (this.props.url) { | ||
this.load(this.props.url); | ||
} | ||
} | ||
@@ -73,3 +53,2 @@ }, { | ||
this.stop(); | ||
clearTimeout(this.updateTimeout); | ||
} | ||
@@ -80,22 +59,28 @@ }, { | ||
// Invoke player methods based on incoming props | ||
if (this.props.url !== nextProps.url) { | ||
this.play(nextProps.url); | ||
this.props.onProgress({ played: 0, loaded: 0 }); | ||
} else if (!this.props.playing && nextProps.playing) { | ||
this.play(); | ||
} else if (this.props.playing && !nextProps.playing) { | ||
this.pause(); | ||
} else if (this.props.volume !== nextProps.volume) { | ||
this.setVolume(nextProps.volume); | ||
} | ||
if (this.props.url !== nextProps.url && nextProps.url) { | ||
this.load(nextProps.url, nextProps.playing); | ||
this.props.onProgress({ played: 0, loaded: 0 }); // Needed? | ||
} else if (this.props.url && !nextProps.url) { | ||
this.stop(); | ||
clearTimeout(this.updateTimeout); | ||
} else if (!this.props.playing && nextProps.playing) { | ||
this.play(); | ||
} else if (this.props.playing && !nextProps.playing) { | ||
this.pause(); | ||
} else if (this.props.volume !== nextProps.volume) { | ||
this.setVolume(nextProps.volume); | ||
} | ||
} | ||
}, { | ||
key: 'shouldComponentUpdate', | ||
value: function shouldComponentUpdate(nextProps) { | ||
return this.props.url !== nextProps.url; | ||
} | ||
}], [{ | ||
key: 'propTypes', | ||
value: _propTypes2['default'], | ||
value: _props.propTypes, | ||
enumerable: true | ||
}, { | ||
key: 'defaultProps', | ||
value: { | ||
onProgress: function onProgress() {} | ||
}, | ||
value: _props.defaultProps, | ||
enumerable: true | ||
@@ -102,0 +87,0 @@ }]); |
@@ -21,6 +21,4 @@ 'use strict'; | ||
var _propTypes = require('../propTypes'); | ||
var _props = require('../props'); | ||
var _propTypes2 = _interopRequireDefault(_propTypes); | ||
var _Base2 = require('./Base'); | ||
@@ -51,12 +49,11 @@ | ||
this.player.onerror = this.props.onError; | ||
_get(Object.getPrototypeOf(FilePlayer.prototype), 'componentDidMount', this).call(this); | ||
} | ||
}, { | ||
key: 'shouldComponentUpdate', | ||
value: function shouldComponentUpdate(nextProps) { | ||
return this.props.url !== nextProps; | ||
key: 'load', | ||
value: function load(url) { | ||
this.player.src = url; | ||
} | ||
}, { | ||
key: 'play', | ||
value: function play(url) { | ||
value: function play() { | ||
this.player.play(); | ||
@@ -72,3 +69,3 @@ } | ||
value: function stop() { | ||
// No need to stop | ||
this.player.src = ''; | ||
} | ||
@@ -101,5 +98,6 @@ }, { | ||
var Media = AUDIO_EXTENSIONS.test(this.props.url) ? 'audio' : 'video'; | ||
var style = { display: this.props.url ? 'block' : 'none' }; | ||
return _react2['default'].createElement(Media, { | ||
ref: 'player', | ||
src: this.props.url, | ||
style: style, | ||
width: this.props.width, | ||
@@ -116,4 +114,8 @@ height: this.props.height | ||
key: 'propTypes', | ||
value: _propTypes2['default'], | ||
value: _props.propTypes, | ||
enumerable: true | ||
}, { | ||
key: 'defaultProps', | ||
value: _props.defaultProps, | ||
enumerable: true | ||
}]); | ||
@@ -120,0 +122,0 @@ |
@@ -25,6 +25,4 @@ 'use strict'; | ||
var _propTypes = require('../propTypes'); | ||
var _props = require('../props'); | ||
var _propTypes2 = _interopRequireDefault(_propTypes); | ||
var _Base2 = require('./Base'); | ||
@@ -34,3 +32,2 @@ | ||
var DEFAULT_CLIENT_ID = 'e8b6f84fbcad14c301ca1355cae1dea2'; | ||
var SDK_URL = '//connect.soundcloud.com/sdk-2.0.0.js'; | ||
@@ -76,3 +73,3 @@ var SDK_GLOBAL = 'SC'; | ||
value: function shouldComponentUpdate(nextProps, nextState) { | ||
return this.state.image !== nextState.image; | ||
return _get(Object.getPrototypeOf(SoundCloud.prototype), 'shouldComponentUpdate', this).call(this, nextProps, nextState) || this.state.image !== nextState.image; | ||
} | ||
@@ -106,10 +103,6 @@ }, { | ||
}, { | ||
key: 'play', | ||
value: function play(url) { | ||
key: 'load', | ||
value: function load(url) { | ||
var _this3 = this; | ||
if (!url && this.player) { | ||
this.player.play(); | ||
return; | ||
} | ||
this.stop(); | ||
@@ -132,2 +125,8 @@ this.getSDK().then(function (SC) { | ||
}, { | ||
key: 'play', | ||
value: function play() { | ||
if (!this.player) return; | ||
this.player.play(); | ||
} | ||
}, { | ||
key: 'pause', | ||
@@ -172,2 +171,3 @@ value: function pause() { | ||
var style = { | ||
display: this.props.url ? 'block' : 'none', | ||
height: '100%', | ||
@@ -187,11 +187,7 @@ backgroundImage: this.state.image ? 'url(' + this.state.image + ')' : null, | ||
key: 'propTypes', | ||
value: _propTypes2['default'], | ||
value: _props.propTypes, | ||
enumerable: true | ||
}, { | ||
key: 'defaultProps', | ||
value: { | ||
soundcloudConfig: { | ||
clientId: DEFAULT_CLIENT_ID | ||
} | ||
}, | ||
value: _props.defaultProps, | ||
enumerable: true | ||
@@ -198,0 +194,0 @@ }]); |
@@ -25,8 +25,4 @@ 'use strict'; | ||
var _queryString2 = _interopRequireDefault(_queryString); | ||
var _props = require('../props'); | ||
var _propTypes = require('../propTypes'); | ||
var _propTypes2 = _interopRequireDefault(_propTypes); | ||
var _Base2 = require('./Base'); | ||
@@ -39,2 +35,3 @@ | ||
var MATCH_MESSAGE_ORIGIN = /^https?:\/\/player.vimeo.com/; | ||
var BLANK_VIDEO_URL = 'https://vimeo.com/127250231'; | ||
var DEFAULT_IFRAME_PARAMS = { | ||
@@ -92,15 +89,21 @@ api: 1, | ||
this.iframe = this.refs.iframe; | ||
if (!this.props.url && this.props.vimeoConfig.preload) { | ||
this.preloading = true; | ||
this.load(BLANK_VIDEO_URL); | ||
} | ||
_get(Object.getPrototypeOf(Vimeo.prototype), 'componentDidMount', this).call(this); | ||
} | ||
}, { | ||
key: 'shouldComponentUpdate', | ||
value: function shouldComponentUpdate(nextProps) { | ||
return this.props.url !== nextProps.url; | ||
key: 'load', | ||
value: function load(url) { | ||
var id = url.match(MATCH_URL)[3]; | ||
var iframeParams = _extends({}, DEFAULT_IFRAME_PARAMS, this.props.vimeoConfig.iframeParams); | ||
this.iframe.src = IFRAME_SRC + id + '?' + (0, _queryString.stringify)(iframeParams); | ||
} | ||
}, { | ||
key: 'play', | ||
value: function play(url) { | ||
if (!url) { | ||
this.postMessage('play'); | ||
} | ||
value: function play() { | ||
this.postMessage('play'); | ||
} | ||
@@ -115,3 +118,3 @@ }, { | ||
value: function stop() { | ||
// No need | ||
this.iframe.src = ''; | ||
} | ||
@@ -141,14 +144,8 @@ }, { | ||
value: function render() { | ||
var id = this.props.url.match(MATCH_URL)[3]; | ||
var style = { | ||
display: this.props.url ? 'block' : 'none', | ||
width: '100%', | ||
height: '100%' | ||
}; | ||
var iframeParams = _extends({}, DEFAULT_IFRAME_PARAMS, this.props.vimeoConfig.iframeParams); | ||
return _react2['default'].createElement('iframe', { | ||
ref: 'iframe', | ||
src: IFRAME_SRC + id + '?' + _queryString2['default'].stringify(iframeParams), | ||
style: style, | ||
frameBorder: '0' | ||
}); | ||
return _react2['default'].createElement('iframe', { ref: 'iframe', frameBorder: '0', style: style }); | ||
} | ||
@@ -162,9 +159,7 @@ }], [{ | ||
key: 'propTypes', | ||
value: _propTypes2['default'], | ||
value: _props.propTypes, | ||
enumerable: true | ||
}, { | ||
key: 'defaultProps', | ||
value: { | ||
vimeoConfig: {} | ||
}, | ||
value: _props.defaultProps, | ||
enumerable: true | ||
@@ -171,0 +166,0 @@ }]); |
@@ -27,6 +27,4 @@ 'use strict'; | ||
var _propTypes = require('../propTypes'); | ||
var _props = require('../props'); | ||
var _propTypes2 = _interopRequireDefault(_propTypes); | ||
var _Base2 = require('./Base'); | ||
@@ -40,2 +38,3 @@ | ||
var PLAYER_ID = 'youtube-player'; | ||
var BLANK_VIDEO_URL = 'https://www.youtube.com/watch?v=GlCmAC4MHek'; | ||
var DEFAULT_PLAYER_VARS = { | ||
@@ -47,2 +46,4 @@ autoplay: 0, | ||
var count = 0; | ||
var YouTube = (function (_Base) { | ||
@@ -58,2 +59,4 @@ _inherits(YouTube, _Base); | ||
this.playerId = PLAYER_ID + '-' + count++; | ||
this.onStateChange = function (state) { | ||
@@ -69,5 +72,9 @@ var YT = window[SDK_GLOBAL]; | ||
_createClass(YouTube, [{ | ||
key: 'shouldComponentUpdate', | ||
value: function shouldComponentUpdate() { | ||
return false; | ||
key: 'componentDidMount', | ||
value: function componentDidMount() { | ||
if (!this.props.url && this.props.youtubeConfig.preload) { | ||
this.preloading = true; | ||
this.load(BLANK_VIDEO_URL); | ||
} | ||
_get(Object.getPrototypeOf(YouTube.prototype), 'componentDidMount', this).call(this); | ||
} | ||
@@ -81,3 +88,5 @@ }, { | ||
return new Promise(function (resolve, reject) { | ||
var previousOnReady = window.onYouTubeIframeAPIReady; | ||
window.onYouTubeIframeAPIReady = function () { | ||
if (previousOnReady) previousOnReady(); | ||
resolve(window[SDK_GLOBAL]); | ||
@@ -91,4 +100,4 @@ }; | ||
}, { | ||
key: 'play', | ||
value: function play(url) { | ||
key: 'load', | ||
value: function load(url, playing) { | ||
var _this2 = this; | ||
@@ -98,6 +107,7 @@ | ||
if (this.player) { | ||
if (id) { | ||
this.stop(); | ||
if (playing) { | ||
this.player.loadVideoById(id); | ||
} else { | ||
this.player.playVideo(); | ||
this.player.cueVideoById(id); | ||
} | ||
@@ -107,3 +117,3 @@ return; | ||
this.getSDK().then(function (YT) { | ||
_this2.player = new YT.Player(PLAYER_ID, { | ||
_this2.player = new YT.Player(_this2.playerId, { | ||
width: '100%', | ||
@@ -122,2 +132,8 @@ height: '100%', | ||
}, { | ||
key: 'play', | ||
value: function play() { | ||
if (!this.player) return; | ||
this.player.playVideo(); | ||
} | ||
}, { | ||
key: 'pause', | ||
@@ -161,3 +177,4 @@ value: function pause() { | ||
value: function render() { | ||
return _react2['default'].createElement('div', { id: PLAYER_ID }); | ||
var style = { display: this.props.url ? 'block' : 'none' }; | ||
return _react2['default'].createElement('div', { id: this.playerId, style: style }); | ||
} | ||
@@ -171,9 +188,7 @@ }], [{ | ||
key: 'propTypes', | ||
value: _propTypes2['default'], | ||
value: _props.propTypes, | ||
enumerable: true | ||
}, { | ||
key: 'defaultProps', | ||
value: { | ||
youtubeConfig: {} | ||
}, | ||
value: _props.defaultProps, | ||
enumerable: true | ||
@@ -180,0 +195,0 @@ }]); |
@@ -15,2 +15,4 @@ 'use strict'; | ||
function _objectWithoutProperties(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } | ||
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } | ||
@@ -26,6 +28,4 @@ | ||
var _propTypes = require('./propTypes'); | ||
var _props2 = require('./props'); | ||
var _propTypes2 = _interopRequireDefault(_propTypes); | ||
var _players = require('./players'); | ||
@@ -35,2 +35,4 @@ | ||
var PROGRESS_FREQUENCY = 500; | ||
var ReactPlayer = (function (_Component) { | ||
@@ -46,6 +48,2 @@ _inherits(ReactPlayer, _Component); | ||
this.state = { | ||
Player: this.getPlayer(this.props.url) | ||
}; | ||
this.seekTo = function (fraction) { | ||
@@ -57,24 +55,58 @@ var player = _this.refs.player; | ||
}; | ||
this.progress = function () { | ||
if (_this.props.url && _this.refs.player) { | ||
var progress = {}; | ||
var loaded = _this.refs.player.getFractionLoaded(); | ||
var played = _this.refs.player.getFractionPlayed(); | ||
if (!_this.prevLoaded || loaded !== _this.prevLoaded) { | ||
progress.loaded = _this.prevLoaded = loaded; | ||
} | ||
if (!_this.prevPlayed || played !== _this.prevPlayed) { | ||
progress.played = _this.prevPlayed = played; | ||
} | ||
if (progress.loaded || progress.played) { | ||
_this.props.onProgress(progress); | ||
} | ||
} | ||
_this.progressTimeout = setTimeout(_this.progress, PROGRESS_FREQUENCY); | ||
}; | ||
this.renderPlayer = function (Player) { | ||
var active = Player.canPlay(_this.props.url); | ||
var _props = _this.props; | ||
var youtubeConfig = _props.youtubeConfig; | ||
var soundcloudConfig = _props.soundcloudConfig; | ||
var vimeoConfig = _props.vimeoConfig; | ||
var activeProps = _objectWithoutProperties(_props, ['youtubeConfig', 'soundcloudConfig', 'vimeoConfig']); | ||
var props = active ? _extends({}, activeProps, { ref: 'player' }) : {}; | ||
return _react2['default'].createElement(Player, _extends({ | ||
key: Player.name, | ||
youtubeConfig: youtubeConfig, | ||
soundcloudConfig: soundcloudConfig, | ||
vimeoConfig: vimeoConfig | ||
}, props)); | ||
}; | ||
} | ||
_createClass(ReactPlayer, [{ | ||
key: 'componentWillReceiveProps', | ||
value: function componentWillReceiveProps(nextProps) { | ||
if (this.props.url !== nextProps.url) { | ||
this.setState({ | ||
Player: this.getPlayer(nextProps.url) | ||
}); | ||
} | ||
key: 'componentDidMount', | ||
value: function componentDidMount() { | ||
this.progress(); | ||
} | ||
}, { | ||
key: 'getPlayer', | ||
value: function getPlayer(url) { | ||
return _players2['default'].find(function (Player) { | ||
return Player.canPlay(url); | ||
}); | ||
key: 'componentWillUnmount', | ||
value: function componentWillUnmount() { | ||
clearTimeout(this.progressTimeout); | ||
} | ||
}, { | ||
key: 'shouldComponentUpdate', | ||
value: function shouldComponentUpdate(nextProps) { | ||
return this.props.url !== nextProps.url || this.props.playing !== nextProps.playing || this.props.volume !== nextProps.volume; | ||
} | ||
}, { | ||
key: 'render', | ||
value: function render() { | ||
var Player = this.state.Player; | ||
var style = { | ||
@@ -87,3 +119,3 @@ width: this.props.width, | ||
{ style: style }, | ||
Player && _react2['default'].createElement(Player, _extends({ ref: 'player' }, this.props)) | ||
_players2['default'].map(this.renderPlayer) | ||
); | ||
@@ -100,15 +132,7 @@ } | ||
key: 'propTypes', | ||
value: _propTypes2['default'], | ||
value: _props2.propTypes, | ||
enumerable: true | ||
}, { | ||
key: 'defaultProps', | ||
value: { | ||
volume: 0.8, | ||
width: 640, | ||
height: 360, | ||
onPlay: function onPlay() {}, // TODO: Empty func var in react? | ||
onPause: function onPause() {}, | ||
onBuffer: function onBuffer() {}, | ||
onEnded: function onEnded() {} | ||
}, | ||
value: _props2.defaultProps, | ||
enumerable: true | ||
@@ -115,0 +139,0 @@ }]); |
{ | ||
"name": "react-player", | ||
"version": "0.2.1", | ||
"version": "0.3.0", | ||
"description": "A react component for playing a variety of URLs, including file paths, YouTube, SoundCloud and Vimeo", | ||
@@ -5,0 +5,0 @@ "main": "lib/ReactPlayer.js", |
@@ -68,6 +68,10 @@ ReactPlayer | ||
---- | ----------- | ||
soundcloudConfig | An object containing configuration for the SoundCloud player. Includes `clientId`, which can be used to override the default `client_id` | ||
vimeoConfig | An object containing configuration for the Vimeo player. Includes `iframeParams`, which maps to the [parameters accepted by the Vimeo iframe player](https://developer.vimeo.com/player/embedding#universal-parameters) | ||
youtubeConfig | An object containing configuration for the YouTube player. Includes `playerVars`, which maps to the [parameters accepted by the YouTube iframe player](https://developers.google.com/youtube/player_parameters?playerVersion=HTML5) | ||
soundcloudConfig | Configuration object for the SoundCloud player. Set `clientId`, to your own SoundCloud app [client ID](https://soundcloud.com/you/apps) | ||
vimeoConfig | Configuration object for the Vimeo player. Set `iframeParams`, to override the [default params](https://developer.vimeo.com/player/embedding#universal-parameters). Set `preload` for [preloading](#preloading) | ||
youtubeConfig | Configuration object for the YouTube player. Set `playerVars`, to override the [default player vars](https://developers.google.com/youtube/player_parameters?playerVersion=HTML5). Set `preload` for [preloading](#preloading) | ||
##### Preloading | ||
Both `youtubeConfig` and `vimeoConfig` props can take a `preload` value. Setting this to `true` will play a short, silent video in the background when `ReactPlayer` first mounts. This fixes a [bug](https://github.com/CookPete/react-player/issues/7) where videos would not play when loaded in a background browser tab. | ||
### Methods | ||
@@ -74,0 +78,0 @@ |
@@ -27,3 +27,4 @@ import React from 'react' | ||
const result = shallowRenderer.getRenderOutput() | ||
expect(result.props.children.type).to.equal(YouTube) | ||
const activePlayer = getActivePlayer(result) | ||
expect(activePlayer.type).to.equal(YouTube) | ||
}) | ||
@@ -34,3 +35,4 @@ | ||
const result = shallowRenderer.getRenderOutput() | ||
expect(result.props.children.type).to.equal(SoundCloud) | ||
const activePlayer = getActivePlayer(result) | ||
expect(activePlayer.type).to.equal(SoundCloud) | ||
}) | ||
@@ -41,3 +43,4 @@ | ||
const result = shallowRenderer.getRenderOutput() | ||
expect(result.props.children.type).to.equal(Vimeo) | ||
const activePlayer = getActivePlayer(result) | ||
expect(activePlayer.type).to.equal(Vimeo) | ||
}) | ||
@@ -48,4 +51,9 @@ | ||
const result = shallowRenderer.getRenderOutput() | ||
expect(result.props.children.type).to.equal(FilePlayer) | ||
const activePlayer = getActivePlayer(result) | ||
expect(activePlayer.type).to.equal(FilePlayer) | ||
}) | ||
}) | ||
function getActivePlayer (result) { | ||
return result.props.children.find(player => player.ref === 'player') | ||
} |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
61762
1177
110