|
1 | 1 | import React, { Component } from 'react' |
2 | 2 | import 'array.prototype.find' |
3 | 3 |
|
4 | | -import propTypes from './propTypes' |
| 4 | +import { propTypes, defaultProps } from './props' |
5 | 5 | import players from './players' |
6 | 6 |
|
| 7 | +const PROGRESS_FREQUENCY = 500 |
| 8 | + |
7 | 9 | export default class ReactPlayer extends Component { |
8 | 10 | static propTypes = propTypes |
9 | | - static defaultProps = { |
10 | | - volume: 0.8, |
11 | | - width: 640, |
12 | | - height: 360, |
13 | | - onPlay: function () {}, // TODO: Empty func var in react? |
14 | | - onPause: function () {}, |
15 | | - onBuffer: function () {}, |
16 | | - onEnded: function () {} |
17 | | - } |
| 11 | + static defaultProps = defaultProps |
18 | 12 | static canPlay (url) { |
19 | 13 | return players.some(player => player.canPlay(url)) |
20 | 14 | } |
21 | | - state = { |
22 | | - Player: this.getPlayer(this.props.url) |
| 15 | + componentDidMount () { |
| 16 | + this.progress() |
23 | 17 | } |
24 | | - componentWillReceiveProps (nextProps) { |
25 | | - if (this.props.url !== nextProps.url) { |
26 | | - this.setState({ |
27 | | - Player: this.getPlayer(nextProps.url) |
28 | | - }) |
29 | | - } |
| 18 | + componentWillUnmount () { |
| 19 | + clearTimeout(this.progressTimeout) |
30 | 20 | } |
31 | | - getPlayer (url) { |
32 | | - return players.find(Player => Player.canPlay(url)) |
| 21 | + shouldComponentUpdate (nextProps) { |
| 22 | + return ( |
| 23 | + this.props.url !== nextProps.url || |
| 24 | + this.props.playing !== nextProps.playing || |
| 25 | + this.props.volume !== nextProps.volume |
| 26 | + ) |
33 | 27 | } |
34 | 28 | seekTo = fraction => { |
35 | 29 | const player = this.refs.player |
36 | 30 | if (player) { |
37 | 31 | player.seekTo(fraction) |
38 | 32 | } |
39 | 33 | } |
| 34 | + progress = () => { |
| 35 | + if (this.props.url && this.refs.player) { |
| 36 | + let progress = {} |
| 37 | + const loaded = this.refs.player.getFractionLoaded() |
| 38 | + const played = this.refs.player.getFractionPlayed() |
| 39 | + if (!this.prevLoaded || loaded !== this.prevLoaded) { |
| 40 | + progress.loaded = this.prevLoaded = loaded |
| 41 | + } |
| 42 | + if (!this.prevPlayed || played !== this.prevPlayed) { |
| 43 | + progress.played = this.prevPlayed = played |
| 44 | + } |
| 45 | + if (progress.loaded || progress.played) { |
| 46 | + this.props.onProgress(progress) |
| 47 | + } |
| 48 | + } |
| 49 | + this.progressTimeout = setTimeout(this.progress, PROGRESS_FREQUENCY) |
| 50 | + } |
| 51 | + renderPlayer = Player => { |
| 52 | + const active = Player.canPlay(this.props.url) |
| 53 | + const { youtubeConfig, soundcloudConfig, vimeoConfig, ...activeProps } = this.props |
| 54 | + const props = active ? { ...activeProps, ref: 'player' } : {} |
| 55 | + return ( |
| 56 | + <Player |
| 57 | + key={Player.name} |
| 58 | + youtubeConfig={youtubeConfig} |
| 59 | + soundcloudConfig={soundcloudConfig} |
| 60 | + vimeoConfig={vimeoConfig} |
| 61 | + {...props} |
| 62 | + /> |
| 63 | + ) |
| 64 | + } |
40 | 65 | render () { |
41 | | - const Player = this.state.Player |
42 | 66 | const style = { |
43 | 67 | width: this.props.width, |
44 | 68 | height: this.props.height |
45 | 69 | } |
46 | 70 | return ( |
47 | 71 | <div style={style}> |
48 | | - { Player && <Player ref='player' {...this.props} /> } |
| 72 | + { players.map(this.renderPlayer) } |
49 | 73 | </div> |
50 | 74 | ) |
51 | 75 | } |
|
0 commit comments