Skip to content

Commit

Permalink
Combine config into single config prop
Browse files Browse the repository at this point in the history
  • Loading branch information
cookpete committed Jun 1, 2016
1 parent 1e5c9e9 commit db1730d
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 81 deletions.
46 changes: 37 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ Prop | Description | Default
`height` | Sets the height of the player | `360`
`className` | Pass in a `className` to set on the top level element
`progressFrequency` | The time between `onProgress` callbacks, in milliseconds | `1000`
`config` | An object for individual player settings | See [Config prop](#config-prop)

#### Callback props

Expand All @@ -96,20 +97,47 @@ Prop | Description
`onEnded` | Called when media finishes playing
`onError` | Called when an error occurs whilst attempting to play media

#### Config props
#### Config prop

These props allow you to override the parameters for the various players:
Use the `config` prop for individual player settings:

Prop | Description
---- | -----------
`soundcloudConfig` | Configuration object for the SoundCloud player.<br />Set `clientId` to your own SoundCloud app [client ID](https://soundcloud.com/you/apps).
`vimeoConfig` | Configuration object for the Vimeo player.<br />Set `iframeParams` to override the [default params](https://developer.vimeo.com/player/embedding#universal-parameters).<br />Set `preload` for [preloading](#preloading).
`youtubeConfig` | Configuration object for the YouTube player.<br />Set `playerVars` to override the [default player vars](https://developers.google.com/youtube/player_parameters?playerVersion=HTML5).<br />Set `preload` for [preloading](#preloading).
`fileConfig` | Configuration object for the file player.<br />Set `attributes` to apply [element attributes](https://developer.mozilla.org/en/docs/Web/HTML/Element/video#Attributes).
```js
const config = {
youtube: {
preload: false, // See preloading below
params: {
// YouTube player parameters
// https://developers.google.com/youtube/player_parameters?playerVersion=HTML5
}
},
soundcloud: {
clientId: YOUR_CLIENT_ID,
attributes: {
// Attributes for the <audio> element used to play tracks
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio#Attributes
}
},
vimeo: {
preload: false, // See preloading below
params: {
// Vimeo embed parameters
// https://developer.vimeo.com/player/embedding#universal-parameters
}
},
file: {
attributes: {
// Attributes for the <audio> or <video> element used to play media
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video#Attributes
}
}
}
```

All settings are optional and merged with the [default config]() before being passed to the individual players.

##### 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.
If `preload` is `true` for either `youtube` or `vimeo`, a short, silent video will play in the background when `ReactPlayer` first mounts. This fixes a [bug](https://github.com/CookPete/react-player/issues/7) where videos will not play when loaded in a background browser tab.

### Methods

Expand Down
11 changes: 5 additions & 6 deletions src/ReactPlayer.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import 'es6-promise'
import React, { Component } from 'react'

import { propTypes, defaultProps } from './props'
import { propTypes, defaultProps, defaultConfig } from './props'
import players from './players'
import { mergeDeep } from './utils'

export default class ReactPlayer extends Component {
static displayName = 'ReactPlayer'
Expand Down Expand Up @@ -49,14 +50,12 @@ export default class ReactPlayer extends Component {
}
renderPlayer = Player => {
const active = Player.canPlay(this.props.url)
const { youtubeConfig, soundcloudConfig, vimeoConfig, ...activeProps } = this.props
const props = active ? { ...activeProps, ref: 'player' } : {}
const { config, ...activeProps } = this.props
const props = active ? { ref: 'player', ...activeProps } : {}
return (
<Player
key={Player.displayName}
youtubeConfig={youtubeConfig}
soundcloudConfig={soundcloudConfig}
vimeoConfig={vimeoConfig}
config={mergeDeep(defaultConfig, config)}
{...props}
/>
)
Expand Down
12 changes: 3 additions & 9 deletions src/demo/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default class App extends Component {
config = {}
console.error('Error setting config:', error)
}
this.setState(config)
this.setState({ config })
}
renderLoadButton = (url, label) => {
return (
Expand All @@ -71,10 +71,7 @@ export default class App extends Component {
const {
url, playing, volume,
played, loaded, duration,
soundcloudConfig,
vimeoConfig,
youtubeConfig,
fileConfig
config
} = this.state
const SEPARATOR = ' · '

Expand All @@ -90,10 +87,7 @@ export default class App extends Component {
url={url}
playing={playing}
volume={volume}
soundcloudConfig={soundcloudConfig}
vimeoConfig={vimeoConfig}
youtubeConfig={youtubeConfig}
fileConfig={fileConfig}
config={config}
onStart={() => console.log('onStart')}
onPlay={() => this.setState({ playing: true })}
onPause={() => this.setState({ playing: false })}
Expand Down
4 changes: 2 additions & 2 deletions src/players/FilePlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ export default class FilePlayer extends Base {
return this.player.buffered.end(0) / this.getDuration()
}
render () {
const { controls, fileConfig } = this.props
const { controls, config } = this.props
const Media = AUDIO_EXTENSIONS.test(this.props.url) ? 'audio' : 'video'
const style = {
width: '100%',
Expand All @@ -65,7 +65,7 @@ export default class FilePlayer extends Base {
style={style}
preload='auto'
controls={controls}
{...fileConfig.attributes}
{...config.file.attributes}
/>
)
}
Expand Down
7 changes: 4 additions & 3 deletions src/players/SoundCloud.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ export default class SoundCloud extends FilePlayer {
if (songData[url]) {
return Promise.resolve(songData[url])
}
return fetchJSONP(RESOLVE_URL + '?url=' + url + '&client_id=' + this.props.soundcloudConfig.clientId)
return fetchJSONP(RESOLVE_URL + '?url=' + url + '&client_id=' + this.props.config.soundcloud.clientId)
.then(response => {
if (response.ok) {
songData[url] = response.json()
Expand All @@ -50,11 +50,11 @@ export default class SoundCloud extends FilePlayer {
if (image) {
this.setState({ image: image.replace('-large', '-t500x500') })
}
this.player.src = data.stream_url + '?client_id=' + this.props.soundcloudConfig.clientId
this.player.src = data.stream_url + '?client_id=' + this.props.config.soundcloud.clientId
}, this.props.onError)
}
render () {
const { url, controls } = this.props
const { url, controls, config } = this.props
const style = {
display: url ? 'block' : 'none',
height: '100%',
Expand All @@ -70,6 +70,7 @@ export default class SoundCloud extends FilePlayer {
preload='auto'
style={{ width: '100%', height: '100%' }}
controls={controls}
{...config.soundcloud.attributes}
/>
</div>
)
Expand Down
18 changes: 3 additions & 15 deletions src/players/Vimeo.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,6 @@ const IFRAME_SRC = 'https://player.vimeo.com/video/'
const MATCH_URL = /https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)/
const MATCH_MESSAGE_ORIGIN = /^https?:\/\/player.vimeo.com/
const BLANK_VIDEO_URL = 'https://vimeo.com/127250231'
const DEFAULT_IFRAME_PARAMS = {
api: 1,
autoplay: 0,
badge: 0,
byline: 0,
fullscreen: 1,
portrait: 0,
title: 0
}

export default class Vimeo extends Base {
static displayName = 'Vimeo'
Expand All @@ -26,19 +17,16 @@ export default class Vimeo extends Base {
window.addEventListener('message', this.onMessage, false)
this.iframe = this.refs.iframe

if (!this.props.url && this.props.vimeoConfig.preload) {
if (!this.props.url && this.props.config.vimeo.preload) {
this.preloading = true
this.load(BLANK_VIDEO_URL)
}

super.componentDidMount()
}
getIframeParams () {
return { ...DEFAULT_IFRAME_PARAMS, ...this.props.vimeoConfig.iframeParams }
}
load (url) {
const id = url.match(MATCH_URL)[3]
this.iframe.src = IFRAME_SRC + id + '?' + stringify(this.getIframeParams())
this.iframe.src = IFRAME_SRC + id + '?' + stringify(this.props.config.vimeo.params)
}
play () {
this.postMessage('play')
Expand Down Expand Up @@ -93,7 +81,7 @@ export default class Vimeo extends Base {
return this.iframe.contentWindow && this.iframe.contentWindow.postMessage(data, this.origin)
}
render () {
const { fullscreen } = this.getIframeParams()
const { fullscreen } = this.props.config.vimeo.params
const style = {
display: this.props.url ? 'block' : 'none',
width: '100%',
Expand Down
12 changes: 2 additions & 10 deletions src/players/YouTube.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,6 @@ const SDK_GLOBAL_READY = 'onYouTubeIframeAPIReady'
const MATCH_URL = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/
const PLAYER_ID = 'youtube-player'
const BLANK_VIDEO_URL = 'https://www.youtube.com/watch?v=GlCmAC4MHek'
const DEFAULT_PLAYER_VARS = {
autoplay: 0,
playsinline: 1,
showinfo: 0,
rel: 0,
iv_load_policy: 3
}

let playerIdCount = 0

Expand All @@ -27,7 +20,7 @@ export default class YouTube extends Base {
}
playerId = PLAYER_ID + '-' + playerIdCount++
componentDidMount () {
if (!this.props.url && this.props.youtubeConfig.preload) {
if (!this.props.url && this.props.config.youtube.preload) {
this.preloading = true
this.load(BLANK_VIDEO_URL)
}
Expand Down Expand Up @@ -68,9 +61,8 @@ export default class YouTube extends Base {
height: '100%',
videoId: id,
playerVars: {
...DEFAULT_PLAYER_VARS,
controls: this.props.controls ? 1 : 0,
...this.props.youtubeConfig.playerVars,
...this.props.config.youtube.params,
start: parseStartTime(url),
origin: window.location.origin
},
Expand Down
81 changes: 54 additions & 27 deletions src/props.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,21 @@ export const propTypes = {
height: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
className: PropTypes.string,
progressFrequency: PropTypes.number,
soundcloudConfig: PropTypes.shape({
clientId: PropTypes.string
}),
youtubeConfig: PropTypes.shape({
playerVars: PropTypes.object,
preload: PropTypes.bool
}),
vimeoConfig: PropTypes.shape({
iframeParams: PropTypes.object,
preload: PropTypes.bool
}),
fileConfig: PropTypes.shape({
attributes: PropTypes.object
config: PropTypes.shape({
soundcloud: PropTypes.shape({
clientId: PropTypes.string
}),
youtube: PropTypes.shape({
params: PropTypes.object,
preload: PropTypes.bool
}),
vimeo: PropTypes.shape({
params: PropTypes.object,
preload: PropTypes.bool
}),
file: PropTypes.shape({
attributes: PropTypes.object
})
}),
onStart: PropTypes.func,
onPlay: PropTypes.func,
Expand All @@ -42,20 +44,7 @@ export const defaultProps = {
width: 640,
height: 360,
progressFrequency: 1000,
soundcloudConfig: {
clientId: 'e8b6f84fbcad14c301ca1355cae1dea2'
},
youtubeConfig: {
playerVars: {},
preload: false
},
vimeoConfig: {
iframeParams: {},
preload: false
},
fileConfig: {
attributes: {}
},
config: defaultConfig,
onStart: function () {},
onPlay: function () {},
onPause: function () {},
Expand All @@ -65,3 +54,41 @@ export const defaultProps = {
onDuration: function () {},
onProgress: function () {}
}

export const defaultConfig = {
soundcloud: {
clientId: 'e8b6f84fbcad14c301ca1355cae1dea2',
attributes: {
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/audio#Attributes
}
},
youtube: {
preload: false,
params: {
// https://developers.google.com/youtube/player_parameters?playerVersion=HTML5
autoplay: 0,
playsinline: 1,
showinfo: 0,
rel: 0,
iv_load_policy: 3
}
},
vimeo: {
preload: false,
params: {
// https://developer.vimeo.com/player/embedding#universal-parameters
api: 1,
autoplay: 0,
badge: 0,
byline: 0,
fullscreen: 1,
portrait: 0,
title: 0
}
},
file: {
attributes: {
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element/video#Attributes
}
}
}
19 changes: 19 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,22 @@ function parseStartStamp (stamp) {
}
return seconds
}

function isObject (item) {
return (item && typeof item === 'object' && !Array.isArray(item) && item !== null)
}

// http://stackoverflow.com/a/34749873
export function mergeDeep (target, source) {
if (isObject(target) && isObject(source)) {
Object.keys(source).forEach(key => {
if (isObject(source[key])) {
if (!target[key]) Object.assign(target, { [key]: {} })
mergeDeep(target[key], source[key])
} else {
Object.assign(target, { [key]: source[key] })
}
})
}
return target
}

0 comments on commit db1730d

Please sign in to comment.