Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: spotify support latest #1877

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
spotify-support
3stbn committed Jul 18, 2024
commit 8cc935d53172e53e22befff03341adc95a3283cb
7 changes: 7 additions & 0 deletions examples/react/src/App.js
Original file line number Diff line number Diff line change
@@ -356,6 +356,13 @@ class App extends Component {
{this.renderLoadButton('https://cdnapisec.kaltura.com/p/2507381/sp/250738100/embedIframeJs/uiconf_id/44372392/partner_id/2507381?iframeembed=true&playerId=kaltura_player_1605622336&entry_id=1_i1jmzcn3', 'Test B')}
</td>
</tr>
<tr>
<th>Spotify</th>
<td>
{this.renderLoadButton('spotify:episode:7makk4oTQel546B0PZlDM5', 'Test A')}
{this.renderLoadButton('spotify:track:0KhB428j00T8lxKCpHweKw', 'Test B')}
</td>
</tr>
<tr>
<th>Files</th>
<td>
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -2,8 +2,8 @@
"name": "react-player",
"version": "2.16.0",
"description": "A React component for playing a variety of URLs, including file paths, YouTube, Facebook, Twitch, SoundCloud, Streamable, Vimeo, Wistia and DailyMotion",
"main": "lib/index.js",
"typings": "lib/index.d.ts",
"main": "src/index.js",
"typings": "types/lib/index.d.ts",
"scripts": {
"clean": "rimraf lib lazy demo coverage *.d.ts",
"start": "cp -r examples/react/public/ demo & npm run build:lib --watch=forever & builder examples/react/src/index.js --format=iife --bundle --outdir=demo --watch --servedir=demo --livereload",
4 changes: 3 additions & 1 deletion src/patterns.js
Original file line number Diff line number Diff line change
@@ -14,6 +14,7 @@ export const MATCH_URL_TWITCH_CHANNEL = /(?:www\.|go\.)?twitch\.tv\/([a-zA-Z0-9_
export const MATCH_URL_DAILYMOTION = /^(?:(?:https?):)?(?:\/\/)?(?:www\.)?(?:(?:dailymotion\.com(?:\/embed)?\/video)|dai\.ly)\/([a-zA-Z0-9]+)(?:_[\w_-]+)?(?:[\w.#_-]+)?/
export const MATCH_URL_MIXCLOUD = /mixcloud\.com\/([^/]+\/[^/]+)/
export const MATCH_URL_VIDYARD = /vidyard.com\/(?:watch\/)?([a-zA-Z0-9-_]+)/
export const MATCH_URL_SPOTIFY = /spotify.+$/
export const MATCH_URL_KALTURA = /^https?:\/\/[a-zA-Z]+\.kaltura.(com|org)\/p\/([0-9]+)\/sp\/([0-9]+)00\/embedIframeJs\/uiconf_id\/([0-9]+)\/partner_id\/([0-9]+)(.*)entry_id.([a-zA-Z0-9-_].*)$/
export const AUDIO_EXTENSIONS = /\.(m4a|m4b|mp4a|mpga|mp2|mp2a|mp3|m2a|m3a|wav|weba|aac|oga|spx)($|\?)/i
export const VIDEO_EXTENSIONS = /\.(mp4|og[gv]|webm|mov|m4v)(#t=[,\d+]+)?($|\?)/i
@@ -63,5 +64,6 @@ export const canPlay = {
mixcloud: url => MATCH_URL_MIXCLOUD.test(url),
vidyard: url => MATCH_URL_VIDYARD.test(url),
kaltura: url => MATCH_URL_KALTURA.test(url),
file: canPlayFile
file: canPlayFile,
spotify: url => MATCH_URL_SPOTIFY.test(url)
}
137 changes: 137 additions & 0 deletions src/players/Spotify.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import React, { Component } from 'react'
import { getSDK, callPlayer } from '../utils'
import { canPlay } from '../patterns'

const SDK_URL = 'https://open.spotify.com/embed/iframe-api/v1'
const SDK_GLOBAL = 'SpotifyIframeApi'
const SDK_GLOBAL_READY = 'SpotifyIframeApi'

export default class Spotify extends Component {
static displayName = 'Spotify'
static loopOnEnded = true
static canPlay = canPlay.spotify
callPlayer = callPlayer
duration = null
currentTime = null
totalTime = null
player = null

componentDidMount () {
this.props.onMount && this.props.onMount(this)
}

load (url) {
if (window[SDK_GLOBAL] && !this.player) {
this.initializePlayer(window[SDK_GLOBAL], url)
return
} else if (this.player) {
this.callPlayer('loadUri', this.props.url)
return
}

window.onSpotifyIframeApiReady = (IFrameAPI) => this.initializePlayer(IFrameAPI, url)
getSDK(SDK_URL, SDK_GLOBAL, SDK_GLOBAL_READY)
}

initializePlayer = (IFrameAPI, url) => {
if (!this.container) return

const options = {
width: '100%',
height: '100%',
uri: url
}
const callback = (EmbedController) => {
this.player = EmbedController
this.player.addListener('playback_update', this.onStateChange)
this.player.addListener('ready', this.props.onReady)
}
IFrameAPI.createController(this.container, options, callback)
}

onStateChange = (event) => {
const { data } = event
const { onPlay, onPause, onBuffer, onBufferEnd, onEnded } = this.props

if (data.position >= data.duration && data.position && data.duration) {
onEnded()
}
if (data.isPaused === true) onPause()
if (data.isPaused === false && data.isBuffering === false) {
this.currentTime = data.position
this.totalTime = data.duration
onPlay()
onBufferEnd()
}
if (data.isBuffering === true) onBuffer()
}

play () {
this.callPlayer('resume')
}

pause () {
this.callPlayer('pause')
}

stop () {
this.callPlayer('destroy')
}

seekTo (amount) {
this.callPlayer('seek', amount)
if (!this.props.playing) {
this.pause()
} else {
this.play()
}
}

setVolume (fraction) {
// No volume support
}

mute () {
// No volume support
}

unmute () {
// No volume support
}

setPlaybackRate (rate) {
// No playback rate support
}

setLoop (loop) {
// No loop support
}

getDuration () {
return this.totalTime / 1000
}

getCurrentTime () {
return this.currentTime / 1000
}

getSecondsLoaded () {
// No seconds loaded support
}

ref = container => {
this.container = container
}

render () {
const style = {
width: '100%',
height: '100%'
}
return (
<div style={style}>
<div ref={this.ref} />
</div>
)
}
}
6 changes: 6 additions & 0 deletions src/players/index.js
Original file line number Diff line number Diff line change
@@ -74,6 +74,12 @@ export default [
canPlay: canPlay.kaltura,
lazyPlayer: lazy(() => import(/* webpackChunkName: 'reactPlayerKaltura' */'./Kaltura'))
},
{
key: 'spotify',
name: 'Spotify',
canPlay: canPlay.spotify,
lazyPlayer: lazy(() => import(/* webpackChunkName: 'reactPlayerSpotify' */'./Spotify'))
},
{
key: 'file',
name: 'FilePlayer',
5 changes: 5 additions & 0 deletions types/spotify.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import BaseReactPlayer, { BaseReactPlayerProps } from './base'

export interface SpotifyPlayerProps extends BaseReactPlayerProps {}

export default class SpotifyPlayer extends BaseReactPlayer<SpotifyPlayerProps> {}