2022-09-07 10:00:28 +03:00
|
|
|
import React, { FC } from 'react';
|
2023-05-07 03:40:42 +03:00
|
|
|
import videojs from 'video.js';
|
|
|
|
import type VideoJsPlayer from 'video.js/dist/types/player';
|
|
|
|
|
2022-09-07 10:00:28 +03:00
|
|
|
import styles from './VideoJS.module.scss';
|
2022-04-27 05:29:13 +03:00
|
|
|
|
|
|
|
require('video.js/dist/video-js.css');
|
|
|
|
|
2022-09-07 10:00:28 +03:00
|
|
|
export type VideoJSProps = {
|
2023-05-07 03:40:42 +03:00
|
|
|
options: any;
|
|
|
|
onReady: (player: VideoJsPlayer, vjsInstance: typeof videojs) => void;
|
2022-09-07 10:00:28 +03:00
|
|
|
};
|
2022-04-27 05:29:13 +03:00
|
|
|
|
2022-09-07 10:00:28 +03:00
|
|
|
export const VideoJS: FC<VideoJSProps> = ({ options, onReady }) => {
|
2023-01-01 03:08:54 +03:00
|
|
|
const videoRef = React.useRef<HTMLVideoElement | null>(null);
|
|
|
|
const playerRef = React.useRef<VideoJsPlayer | null>(null);
|
2022-04-27 05:29:13 +03:00
|
|
|
|
|
|
|
React.useEffect(() => {
|
|
|
|
// Make sure Video.js player is only initialized once
|
|
|
|
if (!playerRef.current) {
|
|
|
|
const videoElement = videoRef.current;
|
|
|
|
|
2022-05-12 09:31:31 +03:00
|
|
|
// eslint-disable-next-line no-multi-assign
|
2023-01-01 03:08:54 +03:00
|
|
|
const player: VideoJsPlayer = (playerRef.current = videojs(videoElement, options, () => {
|
2022-11-13 10:35:53 +03:00
|
|
|
console.debug('player is ready');
|
2022-06-03 00:23:51 +03:00
|
|
|
return onReady && onReady(player, videojs);
|
2022-04-27 05:29:13 +03:00
|
|
|
}));
|
|
|
|
|
|
|
|
player.autoplay(options.autoplay);
|
|
|
|
player.src(options.sources);
|
|
|
|
}
|
2022-11-18 09:10:48 +03:00
|
|
|
|
|
|
|
// Add a cachebuster param to playlist URLs.
|
2023-05-07 06:06:13 +03:00
|
|
|
if (
|
|
|
|
(videojs.getPlayer(videoRef.current).tech({ IWillNotUseThisInPlugins: true }) as any)?.vhs
|
|
|
|
) {
|
|
|
|
(
|
|
|
|
videojs.getPlayer(videoRef.current).tech({ IWillNotUseThisInPlugins: true }) as any
|
|
|
|
).vhs.xhr.beforeRequest = o => {
|
2023-05-07 03:40:42 +03:00
|
|
|
if (o.uri.match('m3u8')) {
|
|
|
|
const cachebuster = Math.random().toString(16).substr(2, 8);
|
|
|
|
// eslint-disable-next-line no-param-reassign
|
|
|
|
o.uri = `${o.uri}?cachebust=${cachebuster}`;
|
|
|
|
}
|
|
|
|
|
|
|
|
return o;
|
|
|
|
};
|
|
|
|
}
|
2022-04-27 05:29:13 +03:00
|
|
|
}, [options, videoRef]);
|
|
|
|
|
|
|
|
return (
|
|
|
|
<div data-vjs-player>
|
2022-05-12 09:31:31 +03:00
|
|
|
{/* eslint-disable-next-line jsx-a11y/media-has-caption */}
|
2022-09-07 10:00:28 +03:00
|
|
|
<video
|
|
|
|
ref={videoRef}
|
2022-10-13 05:24:37 +03:00
|
|
|
className={`video-js vjs-big-play-centered vjs-show-big-play-button-on-pause ${styles.player} vjs-owncast`}
|
2022-09-07 10:00:28 +03:00
|
|
|
/>
|
2022-04-27 05:29:13 +03:00
|
|
|
</div>
|
|
|
|
);
|
2022-09-07 10:00:28 +03:00
|
|
|
};
|