Skip to content

Commit

Permalink
Add Streamable player
Browse files Browse the repository at this point in the history
  • Loading branch information
cookpete committed Sep 24, 2016
1 parent 2958cd2 commit ff6a300
Show file tree
Hide file tree
Showing 6 changed files with 55 additions and 4 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ReactPlayer
[![Dependency Status](https://img.shields.io/david/CookPete/react-player.svg)](https://david-dm.org/CookPete/react-player)
[![devDependency Status](https://img.shields.io/david/dev/CookPete/react-player.svg)](https://david-dm.org/CookPete/react-player?type=dev)

A react component for playing media from YouTube, SoundCloud and Vimeo, as well as supported media files. Used by [rplayr](http://rplayr.com), an app to generate playlists from Reddit URLs.
A react component for playing media from YouTube, SoundCloud, Streamable or Vimeo, as well as supported media files. Used by [rplayr](http://rplayr.com), an app to generate playlists from Reddit URLs.

The component parses a URL and loads in the appropriate markup and external SDKs to play media from [various sources](#supported-media). [Props](#props) can be passed in to control playback and react to events such as buffering or media ending.

Expand Down Expand Up @@ -121,8 +121,9 @@ To seek to a certain part of the media, there is a `seekTo(fraction)` instance m

* YouTube videos use the [YouTube iFrame Player API](https://developers.google.com/youtube/iframe_api_reference)
* Soundcloud tracks are [resolved](https://developers.soundcloud.com/docs/api/reference#resolve) and played in an [`<audio>`](https://developer.mozilla.org/en/docs/Web/HTML/Element/audio) element using the track’s `stream_url`
* Streamable videos are [resolved](https://streamable.com/documentation#retrieve-video) and played in a [`<video>`](https://developer.mozilla.org/en/docs/Web/HTML/Element/video) element using the track’s `mp4` path
* Vimeo videos use the [Vimeo Player API](https://developer.vimeo.com/player/js-api)
* [Supported file types](https://github.com/CookPete/react-player/blob/master/src/players/FilePlayer.js#L5-L6) are playing using [`<video>`](https://developer.mozilla.org/en/docs/Web/HTML/Element/audio) or [`<audio>`](https://developer.mozilla.org/en/docs/Web/HTML/Element/audio) elements
* [Supported file types](https://github.com/CookPete/react-player/blob/master/src/players/FilePlayer.js#L5-L6) are playing using [`<video>`](https://developer.mozilla.org/en/docs/Web/HTML/Element/video) or [`<audio>`](https://developer.mozilla.org/en/docs/Web/HTML/Element/audio) elements

### Contributing

Expand Down
3 changes: 2 additions & 1 deletion bower.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "react-player",
"description": "A react component for playing a variety of URLs, including file paths, YouTube, SoundCloud and Vimeo",
"description": "A react component for playing a variety of URLs, including file paths, YouTube, SoundCloud, Streamable and Vimeo",
"main": "dist/ReactPlayer.js",
"authors": [
"Pete Cook <pete@cookpete.com> (http://github.com/cookpete)"
Expand All @@ -14,6 +14,7 @@
"audio",
"youtube",
"soundcloud",
"streamable",
"vimeo",
"react-component"
],
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "react-player",
"version": "0.9.0",
"description": "A react component for playing a variety of URLs, including file paths, YouTube, SoundCloud and Vimeo",
"description": "A react component for playing a variety of URLs, including file paths, YouTube, SoundCloud, Streamable and Vimeo",
"main": "lib/ReactPlayer.js",
"scripts": {
"clean": "rimraf lib demo",
Expand Down Expand Up @@ -30,6 +30,7 @@
"audio",
"youtube",
"soundcloud",
"streamable",
"vimeo",
"react-component"
],
Expand Down
6 changes: 6 additions & 0 deletions src/ReactPlayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import YouTube from './players/YouTube'
import SoundCloud from './players/SoundCloud'
import Vimeo from './players/Vimeo'
import FilePlayer from './players/FilePlayer'
import Streamable from './players/Streamable'

export default class ReactPlayer extends Component {
static displayName = 'ReactPlayer'
Expand Down Expand Up @@ -53,6 +54,7 @@ export default class ReactPlayer extends Component {
this.progressTimeout = setTimeout(this.progress, this.props.progressFrequency)
}
renderPlayers () {
// Build array of players to render based on URL and preload config
const { url, youtubeConfig, vimeoConfig } = this.props
const players = []
if (YouTube.canPlay(url)) {
Expand All @@ -61,9 +63,13 @@ export default class ReactPlayer extends Component {
players.push(SoundCloud)
} else if (Vimeo.canPlay(url)) {
players.push(Vimeo)
} else if (Streamable.canPlay(url)) {
players.push(Streamable)
} else if (url) {
// Fall back to FilePlayer if nothing else can play the URL
players.push(FilePlayer)
}
// Render additional players if preload config is set
if (!YouTube.canPlay(url) && youtubeConfig.preload) {
players.push(YouTube)
}
Expand Down
7 changes: 7 additions & 0 deletions src/demo/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,13 @@ export default class App extends Component {
{this.renderLoadButton('https://vimeo.com/94502406', 'Test B')}
</td>
</tr>
<tr>
<th>Streamable</th>
<td>
{this.renderLoadButton('https://streamable.com/moo', 'Test A')}
{this.renderLoadButton('https://streamable.com/ifjh', 'Test B')}
</td>
</tr>
<tr>
<th>Files</th>
<td>
Expand Down
35 changes: 35 additions & 0 deletions src/players/Streamable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import FilePlayer from './FilePlayer'

const RESOLVE_URL = 'https://api.streamable.com/videos/'
const MATCH_URL = /^https?:\/\/streamable.com\/([a-z0-9]+)$/

const cache = {} // Cache song data requests

export default class Streamable extends FilePlayer {
static displayName = 'Streamable'
static canPlay (url) {
return MATCH_URL.test(url)
}
getData (url) {
const id = url.match(MATCH_URL)[1]
if (cache[id]) {
return Promise.resolve(cache[id])
}
return window.fetch(RESOLVE_URL + id)
.then(response => {
if (response.status === 200) {
cache[id] = response.json()
return cache[id]
} else {
this.props.onError(new Error('Streamable track could not be resolved'))
}
})
}
load (url) {
this.stop()
this.getData(url).then(data => {
if (!this.mounted) return
this.player.src = data.files.mp4.url
}, this.props.onError)
}
}

0 comments on commit ff6a300

Please sign in to comment.