2021-04-16 09:43:34 +00:00
|
|
|
/* eslint-disable no-invalid-this */
|
|
|
|
import React from 'react';
|
|
|
|
import YouTube from 'react-youtube';
|
|
|
|
|
|
|
|
import { connect } from '../../../base/redux';
|
2021-08-02 12:55:52 +00:00
|
|
|
import { PLAYBACK_STATUSES } from '../../constants';
|
2021-04-16 09:43:34 +00:00
|
|
|
|
|
|
|
import AbstractVideoManager, {
|
|
|
|
_mapDispatchToProps,
|
2021-08-02 12:55:52 +00:00
|
|
|
_mapStateToProps
|
2021-04-16 09:43:34 +00:00
|
|
|
} from './AbstractVideoManager';
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Manager of shared video.
|
|
|
|
*
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
2022-02-25 09:52:07 +00:00
|
|
|
class YoutubeVideoManager extends AbstractVideoManager {
|
2021-04-16 09:43:34 +00:00
|
|
|
/**
|
|
|
|
* Initializes a new YoutubeVideoManager instance.
|
|
|
|
*
|
|
|
|
* @param {Object} props - This component's props.
|
|
|
|
*
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
constructor(props) {
|
|
|
|
super(props);
|
|
|
|
|
|
|
|
this.isPlayerAPILoaded = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates the playback state of the video.
|
|
|
|
*
|
|
|
|
* @returns {string}
|
|
|
|
*/
|
2021-08-02 12:55:52 +00:00
|
|
|
getPlaybackStatus() {
|
|
|
|
let status;
|
2021-04-16 09:43:34 +00:00
|
|
|
|
|
|
|
if (!this.player) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
const playerState = this.player.getPlayerState();
|
|
|
|
|
|
|
|
if (playerState === YouTube.PlayerState.PLAYING) {
|
2021-08-02 12:55:52 +00:00
|
|
|
status = PLAYBACK_STATUSES.PLAYING;
|
2021-04-16 09:43:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (playerState === YouTube.PlayerState.PAUSED) {
|
2021-08-02 12:55:52 +00:00
|
|
|
status = PLAYBACK_STATUSES.PAUSED;
|
2021-04-16 09:43:34 +00:00
|
|
|
}
|
|
|
|
|
2021-08-02 12:55:52 +00:00
|
|
|
return status;
|
2021-04-16 09:43:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Indicates whether the video is muted.
|
|
|
|
*
|
|
|
|
* @returns {boolean}
|
|
|
|
*/
|
|
|
|
isMuted() {
|
|
|
|
return this.player?.isMuted();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves current volume.
|
|
|
|
*
|
|
|
|
* @returns {number}
|
|
|
|
*/
|
|
|
|
getVolume() {
|
|
|
|
return this.player?.getVolume();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Retrieves current time.
|
|
|
|
*
|
|
|
|
* @returns {number}
|
|
|
|
*/
|
|
|
|
getTime() {
|
|
|
|
return this.player?.getCurrentTime();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Seeks video to provided time.
|
|
|
|
*
|
|
|
|
* @param {number} time - The time to seek to.
|
|
|
|
*
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
seek(time) {
|
|
|
|
return this.player?.seekTo(time);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Plays video.
|
|
|
|
*
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
play() {
|
|
|
|
return this.player?.playVideo();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Pauses video.
|
|
|
|
*
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
pause() {
|
|
|
|
return this.player?.pauseVideo();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Mutes video.
|
|
|
|
*
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
mute() {
|
|
|
|
return this.player?.mute();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Unmutes video.
|
|
|
|
*
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
unMute() {
|
|
|
|
return this.player?.unMute();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Disposes of the current video player.
|
|
|
|
*
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
dispose() {
|
|
|
|
if (this.player) {
|
|
|
|
this.player.destroy();
|
|
|
|
this.player = null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Fired on play state toggle.
|
|
|
|
*
|
|
|
|
* @param {Object} event - The yt player stateChange event.
|
|
|
|
*
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
onPlayerStateChange = event => {
|
|
|
|
if (event.data === YouTube.PlayerState.PLAYING) {
|
|
|
|
this.onPlay();
|
|
|
|
} else if (event.data === YouTube.PlayerState.PAUSED) {
|
|
|
|
this.onPause();
|
|
|
|
}
|
2021-11-04 21:10:43 +00:00
|
|
|
};
|
2021-04-16 09:43:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Fired when youtube player is ready.
|
|
|
|
*
|
|
|
|
* @param {Object} event - The youtube player event.
|
|
|
|
*
|
|
|
|
* @returns {void}
|
|
|
|
*/
|
|
|
|
onPlayerReady = event => {
|
|
|
|
const { _isOwner } = this.props;
|
|
|
|
|
|
|
|
this.player = event.target;
|
|
|
|
|
|
|
|
this.player.addEventListener('onVolumeChange', () => {
|
|
|
|
this.onVolumeChange();
|
|
|
|
});
|
|
|
|
|
|
|
|
if (_isOwner) {
|
|
|
|
this.player.addEventListener('onVideoProgress', this.throttledFireUpdateSharedVideoEvent);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.play();
|
2021-06-04 21:12:33 +00:00
|
|
|
|
|
|
|
// sometimes youtube can get muted state from previous videos played in the browser
|
|
|
|
// and as we are disabling controls we want to unmute it
|
|
|
|
if (this.isMuted()) {
|
|
|
|
this.unMute();
|
|
|
|
}
|
2021-04-16 09:43:34 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
getPlayerOptions = () => {
|
|
|
|
const { _isOwner, videoId } = this.props;
|
|
|
|
const showControls = _isOwner ? 1 : 0;
|
|
|
|
|
|
|
|
const options = {
|
|
|
|
id: 'sharedVideoPlayer',
|
|
|
|
opts: {
|
|
|
|
height: '100%',
|
|
|
|
width: '100%',
|
|
|
|
playerVars: {
|
|
|
|
'origin': location.origin,
|
|
|
|
'fs': '0',
|
|
|
|
'autoplay': 0,
|
|
|
|
'controls': showControls,
|
|
|
|
'rel': 0
|
|
|
|
}
|
|
|
|
},
|
2022-12-12 14:00:42 +00:00
|
|
|
onError: e => this.onError(e),
|
2021-04-16 09:43:34 +00:00
|
|
|
onReady: this.onPlayerReady,
|
|
|
|
onStateChange: this.onPlayerStateChange,
|
|
|
|
videoId
|
|
|
|
};
|
|
|
|
|
|
|
|
return options;
|
2021-11-04 21:10:43 +00:00
|
|
|
};
|
2021-04-16 09:43:34 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Implements React Component's render.
|
|
|
|
*
|
|
|
|
* @inheritdoc
|
|
|
|
*/
|
|
|
|
render() {
|
|
|
|
return (<YouTube
|
|
|
|
{ ...this.getPlayerOptions() } />);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default connect(_mapStateToProps, _mapDispatchToProps)(YoutubeVideoManager);
|