diff --git a/README.md b/README.md
index b78b412c..6ac79c18 100644
--- a/README.md
+++ b/README.md
@@ -48,6 +48,9 @@ playing | Set to `true` or `false` to pause or play the media
volume | Sets the volume of the appropriate player
width | Sets the width of the player
height | Sets the height of the player
+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)
onProgress | Callback containing `played` and `loaded` progress as a fraction eg `{ played: 0.12, loaded: 0.34 }`
onPlay | Called when media starts or resumes playing after pausing or buffering
onPause | Called when media is paused
diff --git a/package.json b/package.json
index 7cbb0301..fa17cd2b 100644
--- a/package.json
+++ b/package.json
@@ -53,7 +53,8 @@
},
"dependencies": {
"array.prototype.find": "^1.0.0",
- "load-script": "^1.0.0"
+ "load-script": "^1.0.0",
+ "query-string": "^3.0.0"
},
"standard": {
"parser": "babel-eslint",
diff --git a/src/App.js b/src/App.js
index 97674614..53492411 100644
--- a/src/App.js
+++ b/src/App.js
@@ -38,6 +38,16 @@ export default class App extends Component {
this.setState(state)
}
}
+ onConfigSubmit = () => {
+ let config
+ try {
+ config = JSON.parse(this.refs.config.value)
+ } catch (error) {
+ config = {}
+ console.error('Error setting config:', error)
+ }
+ this.setState(config)
+ }
render () {
return (
@@ -48,6 +58,9 @@ export default class App extends Component {
playing={this.state.playing}
volume={this.state.volume}
onProgress={this.onProgress}
+ soundcloudConfig={this.state.soundcloudConfig}
+ vimeoConfig={this.state.vimeoConfig}
+ youtubeConfig={this.state.youtubeConfig}
onPlay={() => console.log('onPlay')}
onPause={() => console.log('onPause')}
onBuffer={() => console.log('onBuffer')}
@@ -61,20 +74,26 @@ export default class App extends Component {
MP4 video
OGV video
WEBM video
-
+
{ this.load(this.refs.url.value) }}>Load URL
+
+ seek:
-
+ loaded:
+ volume:
- played:
- loaded:
+
+
+
Update Config
)
}
diff --git a/src/players/Base.js b/src/players/Base.js
index 30c65407..ab2c98f9 100644
--- a/src/players/Base.js
+++ b/src/players/Base.js
@@ -45,4 +45,7 @@ export default class Base extends Component {
}
this.updateTimeout = setTimeout(this.update, UPDATE_FREQUENCY)
}
+ onReady = () => {
+ this.setVolume(this.props.volume)
+ }
}
diff --git a/src/players/FilePlayer.js b/src/players/FilePlayer.js
index 71dd2511..9a5c342d 100644
--- a/src/players/FilePlayer.js
+++ b/src/players/FilePlayer.js
@@ -17,6 +17,7 @@ export default class FilePlayer extends Base {
this.player.onplay = this.props.onPlay
this.player.onpause = this.props.onPause
super.componentDidMount()
+ this.onReady();
}
shouldComponentUpdate (nextProps) {
return this.props.url !== nextProps
diff --git a/src/players/SoundCloud.js b/src/players/SoundCloud.js
index d45ee510..f25ceb1e 100644
--- a/src/players/SoundCloud.js
+++ b/src/players/SoundCloud.js
@@ -4,7 +4,7 @@ import loadScript from 'load-script'
import propTypes from '../propTypes'
import Base from './Base'
-const CLIENT_ID = 'e8b6f84fbcad14c301ca1355cae1dea2'
+const DEFAULT_CLIENT_ID = 'e8b6f84fbcad14c301ca1355cae1dea2'
const SDK_URL = '//connect.soundcloud.com/sdk-2.0.0.js'
const SDK_GLOBAL = 'SC'
const RESOLVE_URL = '//api.soundcloud.com/resolve.json'
@@ -12,6 +12,11 @@ const MATCH_URL = /^https?:\/\/(soundcloud.com|snd.sc)\/([a-z0-9-]+\/[a-z0-9-]+)
export default class SoundCloud extends Base {
static propTypes = propTypes
+ static defaultProps = {
+ soundcloudConfig: {
+ clientId: DEFAULT_CLIENT_ID
+ }
+ }
static canPlay (url) {
return MATCH_URL.test(url)
}
@@ -30,14 +35,14 @@ export default class SoundCloud extends Base {
if (err) {
reject(err)
} else {
- window[SDK_GLOBAL].initialize({ client_id: CLIENT_ID })
+ window[SDK_GLOBAL].initialize({ client_id: this.props.soundcloudConfig.clientId })
resolve(window[SDK_GLOBAL])
}
})
})
}
getSongData (url) {
- return fetch(RESOLVE_URL + '?url=' + url + '&client_id=' + CLIENT_ID)
+ return fetch(RESOLVE_URL + '?url=' + url + '&client_id=' + this.props.soundcloudConfig.clientId)
.then(response => response.json())
}
play (url) {
@@ -54,6 +59,7 @@ export default class SoundCloud extends Base {
}
SC.stream(data.uri, this.options, player => {
this.player = player
+ this.onReady()
player.play()
player._player.on('stateChange', this.onStateChange)
})
diff --git a/src/players/Vimeo.js b/src/players/Vimeo.js
index 12f372e5..f5210821 100644
--- a/src/players/Vimeo.js
+++ b/src/players/Vimeo.js
@@ -1,4 +1,5 @@
import React from 'react'
+import queryString from 'query-string'
import propTypes from '../propTypes'
import Base from './Base'
@@ -6,9 +7,20 @@ import Base from './Base'
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 DEFAULT_IFRAME_PARAMS = {
+ api: 1,
+ autoplay: 1,
+ badge: 0,
+ byline: 0,
+ portrait: 0,
+ title: 0
+}
export default class Vimeo extends Base {
static propTypes = propTypes
+ static defaultProps = {
+ vimeoConfig: {}
+ }
static canPlay (url) {
return MATCH_URL.test(url)
}
@@ -55,6 +67,7 @@ export default class Vimeo extends Base {
this.postMessage('addEventListener', 'pause')
this.postMessage('addEventListener', 'finish')
}
+ if (data.event === 'ready') this.onReady()
if (data.event === 'playProgress') this.fractionPlayed = data.data.percent
if (data.event === 'loadProgress') this.fractionLoaded = data.data.percent
if (data.event === 'play') this.props.onPlay()
@@ -73,10 +86,11 @@ export default class Vimeo extends Base {
width: '100%',
height: '100%'
}
+ const iframeParams = { ...DEFAULT_IFRAME_PARAMS, ...this.props.vimeoConfig.iframeParams }
return (
diff --git a/src/players/YouTube.js b/src/players/YouTube.js
index da1e88ef..c3472f5a 100644
--- a/src/players/YouTube.js
+++ b/src/players/YouTube.js
@@ -8,9 +8,17 @@ const SDK_URL = '//www.youtube.com/iframe_api'
const SDK_GLOBAL = 'YT'
const MATCH_URL = /^(?:https?:\/\/)?(?:www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})(?:\S+)?$/
const PLAYER_ID = 'youtube-player'
+const DEFAULT_PLAYER_VARS = {
+ autoplay: 1,
+ controls: 0,
+ showinfo: 0
+}
export default class YouTube extends Base {
static propTypes = propTypes
+ static defaultProps = {
+ youtubeConfig: {}
+ }
static canPlay (url) {
return MATCH_URL.test(url)
}
@@ -45,8 +53,9 @@ export default class YouTube extends Base {
width: '100%',
height: '100%',
videoId: id,
- playerVars: { autoplay: 1, controls: 0, showinfo: 0 },
+ playerVars: { ...DEFAULT_PLAYER_VARS, ...this.props.youtubeConfig.playerVars },
events: {
+ onReady: this.onReady,
onStateChange: this.onStateChange,
onError: this.props.onError
}
diff --git a/src/propTypes.js b/src/propTypes.js
index e205eadb..178c746f 100644
--- a/src/propTypes.js
+++ b/src/propTypes.js
@@ -6,6 +6,15 @@ export default {
volume: PropTypes.number,
width: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
height: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]),
+ soundcloudConfig: PropTypes.shape({
+ clientId: PropTypes.string
+ }),
+ youtubeConfig: PropTypes.shape({
+ playerVars: PropTypes.object
+ }),
+ vimeoConfig: PropTypes.shape({
+ iframeParams: PropTypes.object
+ }),
onPlay: PropTypes.func,
onPause: PropTypes.func,
onBuffer: PropTypes.func,