104 lines
3.1 KiB
TypeScript
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>
|
|
);
|
|
}
|
|
}
|