From 92968cb01249adf190e63e860e1d03ca358d5e93 Mon Sep 17 00:00:00 2001 From: philip-luther Date: Wed, 7 Feb 2018 10:25:35 +0000 Subject: [PATCH] Add support for importing single players Fixes https://github.com/CookPete/react-player/issues/311 --- README.md | 17 +++++++++++++++++ src/ReactPlayer.js | 2 +- src/players/DailyMotion.js | 5 ++++- src/players/Facebook.js | 5 ++++- src/players/FilePlayer.js | 5 ++++- src/players/SoundCloud.js | 5 ++++- src/players/Streamable.js | 5 ++++- src/players/Twitch.js | 5 ++++- src/players/Vimeo.js | 5 ++++- src/players/Wistia.js | 5 ++++- src/players/YouTube.js | 5 ++++- src/players/index.js | 18 +++++++++--------- src/preload.js | 8 ++++---- src/singlePlayer.js | 33 +++++++++++++++++++++++++++++++++ test/specs/canPlay.js | 10 +++++----- 15 files changed, 105 insertions(+), 28 deletions(-) create mode 100644 src/singlePlayer.js diff --git a/README.md b/README.md index ea5f2fc..99c204f 100644 --- a/README.md +++ b/README.md @@ -195,6 +195,23 @@ class ResponsivePlayer extends Component { See [`jsFiddle` example](https://jsfiddle.net/e6w3rtj1/) +#### Single player imports + +If you are only ever playing a single type of URL, you can import individual players to keep your bundle size down: + +```jsx +import YouTubePlayer from 'react-player/lib/players/YouTube' + + +``` + +See a list of available players [here](https://github.com/CookPete/react-player/tree/master/src/players). + #### Standalone player If you aren’t using React, you can still render a player using the standalone library: diff --git a/src/ReactPlayer.js b/src/ReactPlayer.js index f1512d9..63213ed 100644 --- a/src/ReactPlayer.js +++ b/src/ReactPlayer.js @@ -4,7 +4,7 @@ import { propTypes, defaultProps, DEPRECATED_CONFIG_PROPS } from './props' import { getConfig, omit, isEqual } from './utils' import players from './players' import Player from './Player' -import FilePlayer from './players/FilePlayer' +import { FilePlayer } from './players/FilePlayer' import renderPreloadPlayers from './preload' const SUPPORTED_PROPS = Object.keys(propTypes) diff --git a/src/players/DailyMotion.js b/src/players/DailyMotion.js index 0d9d6e0..165400e 100644 --- a/src/players/DailyMotion.js +++ b/src/players/DailyMotion.js @@ -1,13 +1,14 @@ import React, { Component } from 'react' import { callPlayer, getSDK, parseStartTime } from '../utils' +import createSinglePlayer from '../singlePlayer' const SDK_URL = 'https://api.dmcdn.net/all.js' const SDK_GLOBAL = 'DM' const SDK_GLOBAL_READY = 'dmAsyncInit' const MATCH_URL = /dailymotion.com\/(video|hub)\/([^_]+)[^#]*(#video=([^_&]+))?/ -export default class DailyMotion extends Component { +export class DailyMotion extends Component { static displayName = 'DailyMotion' static canPlay = url => MATCH_URL.test(url) static loopOnEnded = true @@ -99,3 +100,5 @@ export default class DailyMotion extends Component { ) } } + +export default createSinglePlayer(DailyMotion) diff --git a/src/players/Facebook.js b/src/players/Facebook.js index 045e0eb..f33d68b 100644 --- a/src/players/Facebook.js +++ b/src/players/Facebook.js @@ -1,6 +1,7 @@ import React, { Component } from 'react' import { callPlayer, getSDK, randomString } from '../utils' +import createSinglePlayer from '../singlePlayer' const SDK_URL = '//connect.facebook.net/en_US/sdk.js' const SDK_GLOBAL = 'FB' @@ -8,7 +9,7 @@ const SDK_GLOBAL_READY = 'fbAsyncInit' const MATCH_URL = /facebook\.com\/([^/?].+\/)?video(s|\.php)[/?].*$/ const PLAYER_ID_PREFIX = 'facebook-player-' -export default class Facebook extends Component { +export class Facebook extends Component { static displayName = 'Facebook' static canPlay = url => MATCH_URL.test(url) static loopOnEnded = true @@ -84,3 +85,5 @@ export default class Facebook extends Component { ) } } + +export default createSinglePlayer(Facebook) diff --git a/src/players/FilePlayer.js b/src/players/FilePlayer.js index f7f4997..102b6c9 100644 --- a/src/players/FilePlayer.js +++ b/src/players/FilePlayer.js @@ -1,6 +1,7 @@ import React, { Component } from 'react' import { getSDK } from '../utils' +import createSinglePlayer from '../singlePlayer' const AUDIO_EXTENSIONS = /\.(m4a|mp4a|mpga|mp2|mp2a|mp3|m2a|m3a|wav|weba|aac|oga|spx)($|\?)/i const VIDEO_EXTENSIONS = /\.(mp4|og[gv]|webm|mov|m4v)($|\?)/i @@ -31,7 +32,7 @@ function canPlay (url) { ) } -export default class FilePlayer extends Component { +export class FilePlayer extends Component { static displayName = 'FilePlayer' static canPlay = canPlay @@ -182,3 +183,5 @@ export default class FilePlayer extends Component { ) } } + +export default createSinglePlayer(FilePlayer) diff --git a/src/players/SoundCloud.js b/src/players/SoundCloud.js index e9be7a4..97795a0 100644 --- a/src/players/SoundCloud.js +++ b/src/players/SoundCloud.js @@ -1,12 +1,13 @@ import React, { Component } from 'react' import { callPlayer, getSDK } from '../utils' +import createSinglePlayer from '../singlePlayer' const SDK_URL = 'https://w.soundcloud.com/player/api.js' const SDK_GLOBAL = 'SC' const MATCH_URL = /(soundcloud.com|snd.sc)\/.+$/ -export default class SoundCloud extends Component { +export class SoundCloud extends Component { static displayName = 'SoundCloud' static canPlay = url => MATCH_URL.test(url) static loopOnEnded = true @@ -84,3 +85,5 @@ export default class SoundCloud extends Component { ) } } + +export default createSinglePlayer(SoundCloud) diff --git a/src/players/Streamable.js b/src/players/Streamable.js index 877dda4..152a27b 100644 --- a/src/players/Streamable.js +++ b/src/players/Streamable.js @@ -1,12 +1,13 @@ import React, { Component } from 'react' import { callPlayer, getSDK } from '../utils' +import createSinglePlayer from '../singlePlayer' const SDK_URL = '//cdn.embed.ly/player-0.1.0.min.js' const SDK_GLOBAL = 'playerjs' const MATCH_URL = /streamable.com\/([a-z0-9]+)$/ -export default class Streamable extends Component { +export class Streamable extends Component { static displayName = 'Streamable' static canPlay = url => MATCH_URL.test(url) @@ -81,3 +82,5 @@ export default class Streamable extends Component { ) } } + +export default createSinglePlayer(Streamable) diff --git a/src/players/Twitch.js b/src/players/Twitch.js index 85aabd9..0078b3a 100644 --- a/src/players/Twitch.js +++ b/src/players/Twitch.js @@ -1,6 +1,7 @@ import React, { Component } from 'react' import { callPlayer, getSDK, randomString } from '../utils' +import createSinglePlayer from '../singlePlayer' const SDK_URL = '//player.twitch.tv/js/embed/v1.js' const SDK_GLOBAL = 'Twitch' @@ -8,7 +9,7 @@ const MATCH_VIDEO_URL = /(?:www\.|go\.)?twitch\.tv\/videos\/(\d+)($|\?)/ const MATCH_CHANNEL_URL = /(?:www\.|go\.)?twitch\.tv\/([a-z0-9_]+)($|\?)/ const PLAYER_ID_PREFIX = 'twitch-player-' -export default class Twitch extends Component { +export class Twitch extends Component { static displayName = 'Twitch' static canPlay = url => MATCH_VIDEO_URL.test(url) || MATCH_CHANNEL_URL.test(url) static loopOnEnded = true @@ -77,3 +78,5 @@ export default class Twitch extends Component { ) } } + +export default createSinglePlayer(Twitch) diff --git a/src/players/Vimeo.js b/src/players/Vimeo.js index 27e17bf..e2597d6 100644 --- a/src/players/Vimeo.js +++ b/src/players/Vimeo.js @@ -1,12 +1,13 @@ import React, { Component } from 'react' import { callPlayer, getSDK } from '../utils' +import createSinglePlayer from '../singlePlayer' const SDK_URL = 'https://player.vimeo.com/api/player.js' const SDK_GLOBAL = 'Vimeo' const MATCH_URL = /(?:www\.|player\.)?vimeo.com\/(?:(?:channels|ondemand)\/(?:\w+\/)?|groups\/([^/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\?)/ -export default class Vimeo extends Component { +export class Vimeo extends Component { static displayName = 'Vimeo' static canPlay = url => MATCH_URL.test(url) @@ -90,3 +91,5 @@ export default class Vimeo extends Component { return
} } + +export default createSinglePlayer(Vimeo) diff --git a/src/players/Wistia.js b/src/players/Wistia.js index de2c663..395dcd1 100644 --- a/src/players/Wistia.js +++ b/src/players/Wistia.js @@ -1,12 +1,13 @@ import React, { Component } from 'react' import { callPlayer, getSDK } from '../utils' +import createSinglePlayer from '../singlePlayer' const SDK_URL = '//fast.wistia.com/assets/external/E-v1.js' const SDK_GLOBAL = 'Wistia' const MATCH_URL = /(?:wistia.com|wi.st)\/(?:medias|embed)\/(.*)$/ -export default class Wistia extends Component { +export class Wistia extends Component { static displayName = 'Wistia' static canPlay = url => MATCH_URL.test(url) static loopOnEnded = true @@ -75,3 +76,5 @@ export default class Wistia extends Component { ) } } + +export default createSinglePlayer(Wistia) diff --git a/src/players/YouTube.js b/src/players/YouTube.js index 06e0666..47a5b4c 100644 --- a/src/players/YouTube.js +++ b/src/players/YouTube.js @@ -1,13 +1,14 @@ import React, { Component } from 'react' import { callPlayer, getSDK, parseStartTime } from '../utils' +import createSinglePlayer from '../singlePlayer' const SDK_URL = 'https://www.youtube.com/iframe_api' const SDK_GLOBAL = 'YT' const SDK_GLOBAL_READY = 'onYouTubeIframeAPIReady' const MATCH_URL = /(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})/ -export default class YouTube extends Component { +export class YouTube extends Component { static displayName = 'YouTube' static canPlay = url => MATCH_URL.test(url) static loopOnEnded = true @@ -97,3 +98,5 @@ export default class YouTube extends Component { ) } } + +export default createSinglePlayer(YouTube) diff --git a/src/players/index.js b/src/players/index.js index d194bfd..047a1e1 100644 --- a/src/players/index.js +++ b/src/players/index.js @@ -1,12 +1,12 @@ -import YouTube from './YouTube' -import SoundCloud from './SoundCloud' -import Vimeo from './Vimeo' -import Facebook from './Facebook' -import Streamable from './Streamable' -import Wistia from './Wistia' -import Twitch from './Twitch' -import DailyMotion from './DailyMotion' -import FilePlayer from './FilePlayer' +import { YouTube } from './YouTube' +import { SoundCloud } from './SoundCloud' +import { Vimeo } from './Vimeo' +import { Facebook } from './Facebook' +import { Streamable } from './Streamable' +import { Wistia } from './Wistia' +import { Twitch } from './Twitch' +import { DailyMotion } from './DailyMotion' +import { FilePlayer } from './FilePlayer' export default [ YouTube, diff --git a/src/preload.js b/src/preload.js index c8be903..43f3236 100644 --- a/src/preload.js +++ b/src/preload.js @@ -1,10 +1,10 @@ import React from 'react' import Player from './Player' -import YouTube from './players/YouTube' -import SoundCloud from './players/SoundCloud' -import Vimeo from './players/Vimeo' -import DailyMotion from './players/DailyMotion' +import { YouTube } from './players/YouTube' +import { SoundCloud } from './players/SoundCloud' +import { Vimeo } from './players/Vimeo' +import { DailyMotion } from './players/DailyMotion' const PRELOAD_PLAYERS = [ { diff --git a/src/singlePlayer.js b/src/singlePlayer.js new file mode 100644 index 0000000..1b4c961 --- /dev/null +++ b/src/singlePlayer.js @@ -0,0 +1,33 @@ +import React, { Component } from 'react' + +import { propTypes, defaultProps } from './props' +import Player from './Player' +import { isEqual, getConfig } from './utils' + +export default function createSinglePlayer (activePlayer) { + return class SinglePlayer extends Component { + static displayName = `${activePlayer.displayName}Player` + static propTypes = propTypes + static defaultProps = defaultProps + static canPlay = activePlayer.canPlay + + shouldComponentUpdate (nextProps) { + return !isEqual(this.props, nextProps) + } + componentWillUpdate (nextProps) { + this.config = getConfig(nextProps, defaultProps) + } + render () { + if (!activePlayer.canPlay(this.props.url)) { + return null + } + return ( + + ) + } + } +} diff --git a/test/specs/canPlay.js b/test/specs/canPlay.js index d26847b..837f519 100644 --- a/test/specs/canPlay.js +++ b/test/specs/canPlay.js @@ -1,10 +1,10 @@ /* eslint-disable no-unused-expressions */ -import SoundCloud from '../../src/players/SoundCloud' -import YouTube from '../../src/players/YouTube' -import Vimeo from '../../src/players/Vimeo' -import Wistia from '../../src/players/Wistia' -import Twitch from '../../src/players/Twitch' +import { SoundCloud } from '../../src/players/SoundCloud' +import { YouTube } from '../../src/players/YouTube' +import { Vimeo } from '../../src/players/Vimeo' +import { Wistia } from '../../src/players/Wistia' +import { Twitch } from '../../src/players/Twitch' const { describe, it, expect } = window