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 { - + +
+ seek: - + loaded: + volume: - played: - loaded: +
+ +
) } 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 (