bigbluebutton-Github/bigbluebutton-html5/imports/ui/components/external-video-player/custom-players/peertube.jsx
2021-05-07 08:54:01 -03:00

210 lines
4.3 KiB
JavaScript

import loadScript from 'load-script';
import React, { Component } from 'react'
const MATCH_URL = new RegExp("(https?)://(.*)/videos/watch/(.*)");
const SDK_URL = 'https://unpkg.com/@peertube/embed-api/build/player.min.js';
// Util function to load an external SDK or return the SDK if it is already loaded
// From https://github.com/CookPete/react-player/blob/master/src/utils.js
const resolves = {};
export function getSDK (url, sdkGlobal, sdkReady = null, isLoaded = () => true, fetchScript = loadScript) {
if (window[sdkGlobal] && isLoaded(window[sdkGlobal])) {
return Promise.resolve(window[sdkGlobal])
}
return new Promise((resolve, reject) => {
// If we are already loading the SDK, add the resolve
// function to the existing array of resolve functions
if (resolves[url]) {
resolves[url].push(resolve);
return
}
resolves[url] = [resolve];
const onLoaded = sdk => {
// When loaded, resolve all pending promises
resolves[url].forEach(resolve => resolve(sdk))
};
if (sdkReady) {
const previousOnReady = window[sdkReady];
window[sdkReady] = function () {
if (previousOnReady) previousOnReady();
onLoaded(window[sdkGlobal])
}
}
fetchScript(url, err => {
if (err) {
reject(err);
}
window[sdkGlobal] = url;
if (!sdkReady) {
onLoaded(window[sdkGlobal])
}
})
})
}
export class PeerTubePlayer extends Component {
static displayName = 'PeerTubePlayer';
static canPlay = url => {
return MATCH_URL.test(url)
};
constructor(props) {
super(props);
this.player = this;
this._player = null;
this.currentTime = 0;
this.playbackRate = 1;
this.getCurrentTime = this.getCurrentTime.bind(this);
this.getEmbedUrl = this.getEmbedUrl.bind(this);
this.setupEvents = this.setupEvents.bind(this);
}
componentDidMount () {
this.props.onMount && this.props.onMount(this)
}
getEmbedUrl = () => {
const { config, url } = this.props;
const m = MATCH_URL.exec(url);
return `${m[1]}://${m[2]}/videos/embed/${m[3]}?api=1&controls=${true}`;
};
load() {
new Promise((resolve, reject) => {
this.render();
resolve();
})
.then(() => { return getSDK(SDK_URL, 'PeerTube') })
.then(() => {
this._player = new window['PeerTubePlayer'](this.container);
this.setupEvents();
return this._player.ready.then(() => {
return this.props.onReady();
});
});
}
setupEvents(event) {
const player = this._player;
if (!player) {
return;
}
player.addEventListener("playbackStatusUpdate", (data) => {
this.currentTime = data.position;
});
player.addEventListener("playbackStatusChange", (data) => {
if (data === 'playing') {
this.props.onPlay();
} else {
this.props.onPause();
}
});
}
play() {
if (this._player) {
this._player.play();
}
}
pause() {
if (this._player) {
this._player.pause();
}
}
stop() {
}
seekTo(seconds) {
if (this._player) {
this._player.seek(seconds);
}
}
setVolume(fraction) {
// console.log("SET VOLUME");
}
setLoop(loop) {
// console.log("SET LOOP");
}
mute() {
// console.log("SET MUTE");
}
unmute() {
// console.log("SET UNMUTE");
}
getDuration() {
//console.log("GET DURATION");
}
getCurrentTime () {
return this.currentTime;
}
getSecondsLoaded () {
}
getPlaybackRate () {
if (this._player) {
this._player.getPlaybackRate().then((rate) => {
this.playbackRate = rate;
});
}
return this.playbackRate;
}
setPlaybackRate (rate) {
if (this._player) {
this._player.setPlaybackRate(rate);
}
}
render () {
const style = {
width: '100%',
height: '100%',
margin: 0,
padding: 0,
border: 0,
overflow: 'hidden',
};
const { url } = this.props;
return (
<iframe
key={url}
style={style}
src={this.getEmbedUrl(url)}
id={"peerTubeContainer"}
allow="autoplay; fullscreen"
sandbox="allow-same-origin allow-scripts allow-popups"
ref={(container) => {
this.container = container;
}}
>
</iframe>
)
}
}
export default PeerTubePlayer;