gdq-archive/frontend/components/VideoPlayer.tsx

104 lines
3.1 KiB
TypeScript

/**
* Copyright (C) 2019-2021 Carl Kittelberger <icedream@icedream.pw>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import * as React from 'react';
import { Ratio } from 'react-bootstrap';
import videojs, { VideoJsPlayer, VideoJsPlayerOptions } from 'video.js';
import 'videojs-errors';
// TODO - localization
// import 'videojs-errors/dist/lang/de';
// import 'videojs-errors/dist/lang/en';
// import 'videojs-contrib-dash';
export default class VideoPlayer extends React.Component<{
onReady?: () => void,
onVolumeChange?: (e: Event) => void,
onTimeUpdate?: (e: Event) => void,
} & VideoJsPlayerOptions> {
videoNode: HTMLVideoElement;
player: VideoJsPlayer;
componentDidMount() {
const {
onReady,
onTimeUpdate,
onVolumeChange,
defaultVolume,
...videoJsOptions
} = this.props;
this.player = videojs(this.videoNode, videoJsOptions, onReady);
if (typeof defaultVolume === 'number' && !Number.isNaN(defaultVolume)) {
this.player.volume(defaultVolume);
}
if (onVolumeChange) { this.player.on('volumechange', onVolumeChange); }
if (onTimeUpdate) { this.player.on('timeupdate', onTimeUpdate); }
}
componentWillUnmount() {
if (this.player) {
this.player.dispose();
}
}
render() {
const {
sources,
controls,
autoplay,
onReady,
...videoJsOptions
} = this.props;
return (
<Ratio aspectRatio="16by9" data-vjs-player>
{/* eslint-disable-next-line jsx-a11y/media-has-caption */}
<video
ref={(node) => { this.videoNode = node; }}
className="video-js"
data-setup={
JSON.stringify({
autoplay,
controls,
...videoJsOptions,
})
}
controls={controls}
autoPlay={!!(autoplay === 'true' || autoplay === true)}
>
{sources.map(
({ src, type }) => (
<source
key={`${JSON.stringify({ src, type })}`}
src={src}
type={type}
/>
),
)}
<p className="vjs-no-js">
{/* TODO - localize */}
To view this video please enable JavaScript, and consider upgrading to a
web browser that
<a href="https://videojs.com/html5-video-support/" target="_blank" rel="noreferrer">
supports HTML5 video
</a>
</p>
</video>
</Ratio>
);
}
}