diff --git a/examples/react/src/App.js b/examples/react/src/App.js index 3ba82719..d218414b 100644 --- a/examples/react/src/App.js +++ b/examples/react/src/App.js @@ -356,6 +356,12 @@ 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')} + + Gumlet + + {this.renderLoadButton('https://play.gumlet.io/embed/64bfb0913ed6e5096d66dc1e', 'Test A')} + + Files diff --git a/src/patterns.js b/src/patterns.js index 6f82585b..789b95a6 100644 --- a/src/patterns.js +++ b/src/patterns.js @@ -20,6 +20,7 @@ export const VIDEO_EXTENSIONS = /\.(mp4|og[gv]|webm|mov|m4v)(#t=[,\d+]+)?($|\?)/ export const HLS_EXTENSIONS = /\.(m3u8)($|\?)/i export const DASH_EXTENSIONS = /\.(mpd)($|\?)/i export const FLV_EXTENSIONS = /\.(flv)($|\?)/i +export const MATCH_URL_GUMLET = /play.gumlet.io\/embed\/([a-zA-Z0-9_]+)($|\?)/ const canPlayFile = url => { if (url instanceof Array) { @@ -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), + gumlet: url => MATCH_URL_GUMLET.test(url), file: canPlayFile } diff --git a/src/players/Gumlet.js b/src/players/Gumlet.js new file mode 100644 index 00000000..6986a096 --- /dev/null +++ b/src/players/Gumlet.js @@ -0,0 +1,186 @@ +import React, { Component } from 'react' + +import { callPlayer, getSDK } from '../utils' +import { canPlay } from '../patterns' + +const SDK_URL = 'https://cdn.jsdelivr.net/npm/@gumlet/player.js@2.0/dist/player.min.js' +const SDK_GLOBAL = 'playerjs' + +export default class Gumlet extends Component { + static displayName = 'Gumlet' + static canPlay = canPlay.gumlet + callPlayer = callPlayer + duration = null + currentTime = null + secondsLoaded = null + + componentDidMount () { + this.props.onMount && this.props.onMount(this) + } + + load (url) { + getSDK(SDK_URL, SDK_GLOBAL).then(playerjs => { + if (!this.iframe) return + this.player = new playerjs.Player(this.iframe) + this.player.on('ready', () => { + // An arbitrary timeout is required otherwise + // the event listeners won’t work + setTimeout(() => { + this.player.isReady = true + this.player.setLoop(this.props.loop) + if (this.props.muted) { + this.player.mute() + } + this.addListeners(this.player, this.props) + this.props.onReady() + }, 500) + }) + }, this.props.onError) + } + + addListeners (player, props) { + player.on('play', props.onPlay) + player.on('pause', props.onPause) + player.on('progress', (e) => { + if (this.props.onProgress) this.props.onProgress(e) + }) + player.on('timeupdate', (e) => { + if (this.props.onTimeUpdate) this.props.onTimeUpdate(e) + }) + player.on('ended', props.onEnded) + player.on('onFullScreenChange', (e) => { + props.onFullScreenChange(e) + }) + player.on('onPipChange', (e) => { + props.onPipChange(e) + }) + player.on('onAudioChange', (e) => { + props.onAudioChange(e) + }); + player.on('onQualityChange', (e) => { + props.onQualityChange(e) + }) + player.on('onVolumeChange', (e) => { + props.onVolumeChange(e) + }) + player.on('seeked', (e) => { + props.onSeeked(e) + }) + player.on('error', (e) => { + props.onError(e); + }) + player.on('mute', props.onMute) + } + + play () { + this.callPlayer('play') + } + + pause () { + this.callPlayer('pause') + } + + mute = () => { + this.callPlayer('mute') + } + + unmute = () => { + this.callPlayer('unmute') + } + + setVolume (fraction) { + this.callPlayer('setVolume', fraction) + } + + seekTo (seconds, keepPlaying = true) { + this.callPlayer('setCurrentTime', seconds) + if (!keepPlaying) { + this.pause() + } + } + + setPlaybackRate (rate) { + this.callPlayer('setPlaybackRate', rate) + } + + stop () { + // Nothing to do + } + + setLoop (loop) { + // Nothing to do + } + + getPaused () { + return new Promise((resolve, reject) => { + this.player.getPaused((e)=>{ + resolve(e); + }); + }); + } + + getMuted = () => { + return new Promise((resolve, reject) => { + this.player.getMuted((e)=>{ + resolve(e); + }); + }); + }; + + getVolume = () => { + return new Promise((resolve, reject) => { + this.player.getVolume((e)=>{ + resolve(e); + }); + }); + }; + + getDuration () { + return new Promise((resolve, reject) => { + this.player.getDuration((e)=>{ + resolve(e); + }); + }); + } + + getCurrentTime () { + return new Promise((resolve, reject) => { + this.player.getCurrentTime((e)=>{ + resolve(e); + }); + }); + } + + getSecondsLoaded () { + // Gumlet doesn't provide a way to get the seconds loaded + } + + getPlaybackRate = () => { + return new Promise((resolve, reject) => { + this.player.getPlaybackRate((e)=>{ + resolve(e); + }); + }); + }; + + ref = iframe => { + this.iframe = iframe + } + + render () { + const style = { + width: '100%', + height: '100%' + } + return ( +