panjareh
Version:
Panjareh using aparat and phoenix-video-player to play videos on desktops and tvs.
268 lines (245 loc) • 7.22 kB
JavaScript
import React, { useEffect, useRef } from "react";
import { isObject } from "../utils";
import VJSPlayer from "@filmgardi/aparat";
import PropTypes from "prop-types";
import { isMobileSafari } from "react-device-detect";
import "@filmgardi/aparat/dist/aparat.min.css";
import "@filmgardi/videojs-phoenix-theme/dist/videojs-phoenix-theme.css";
import QueryParameter from "../utils/queryParameter";
import cookiesName from "../enums/cookies-name";
const DEFAULT_OPTIONS = {
autoplay: true,
controls: isMobileSafari ? false : true,
fill: true,
playbackRates: [0.5, 1, 1.25, 1.5],
language: "fa",
poster: "",
sources: [],
info: { title: null, subTitle: null },
returnUrl: null,
html5: {
nativeTextTracks: isMobileSafari ? true : false,
hlsjsConfig: {
// Put your hls.js config here
// debug: true,
enableWorker: true,
lowLatencyMode: true,
backBufferLength: 90,
// maxBufferSize: 60 * 1000 * 1000,
// startLevel: 0,
},
},
pluginOptions: {
seekThumbnailSrc: null,
seekButtons: {
forward: 10,
back: 10,
forwardIndex: 1,
backIndex: 1,
},
nextEpisode: {
url: "",
autoAdvance: true,
showAutoAdvanceButton: true,
autoAdvanceButtonText: "قسمت بعدی",
nextEpisodeDisplayTime: null,
nextEpisodeDisplayDuration: 10,
dialogData: {
title: "",
description: "",
url: ``,
},
dialogTemplate: ({ title, description, url }) => {
const container = document.createElement("div");
container.className = "vjs-next-episode-dialog-content";
container.style.flexDirection = "row";
container.style.alignItems = "self-end";
container.style.width = "420px";
container.style.padding = "12px 24px";
const img = document.createElement("img");
img.className = "vjs-next-episode-dialog-poster";
img.src = url;
img.style.width = "140px";
img.style.height = "65px";
img.style.marginLeft = "24px";
container.appendChild(img);
const episodeContent = document.createElement("div");
episodeContent.className = "vjs-next-episode-content";
episodeContent.style.display = "flex";
episodeContent.style.flexDirection = "column";
episodeContent.style.justifyContent = "end";
episodeContent.style.textAlign = "right";
container.appendChild(episodeContent);
const titleEl = document.createElement("span");
titleEl.className = "vjs-next-episode-dialog-title";
titleEl.innerHTML = title;
episodeContent.appendChild(titleEl);
const descriptionEl = document.createElement("span");
descriptionEl.className = "vjs-next-episode-dialog-description";
descriptionEl.innerHTML = description;
episodeContent.appendChild(descriptionEl);
return container;
},
// placementIndex: 9,
},
skipButton: {
text: "skipOpeningCredits",
from: null,
to: null,
position: "bottom-right",
offsetH: 46,
offsetV: 167,
},
trafficUsage: {
title: null,
message: null,
expireTime: 5, // minute
position: "top-right",
offsetH: 30,
offsetV: 15,
},
subtitleSettings: {},
seasonPlaylist: {
seasons: null, // array of number
getEpisode: (season, page, callback) => {
callback({
alias: "",
duration: 0,
link: "",
part: 0,
season: 0,
thumbnail: "",
title: null,
});
},
},
vote: {
submitVote: ({ likeStatus, callback }) => {
return { likeStatus, callback };
}, //Tips: likeStatus returns 1 if liked and 2 if disliked
from: null,
to: null,
position: "bottom-right",
offsetH: 46,
offsetV: 167,
},
collectData: {
token: "",
},
markers: {
markerTip: {
display: false,
skip: true,
},
onMarkerReached: (marker, index) => {
console.log(marker, index);
},
onMarkerSkipZone: (marker, index) => {
console.log("onMarkerSkipZone", marker, index);
},
markers: [{ time: null, duration: null }],
},
},
// initPlugins: {
// seekButtons,
// vttThumbnails
// },
// controlBar: { children: ['playToggle'] },
};
const VideoPlayer = (props) => {
const {
className = "",
options,
onReady = () => {},
videoProgress = () => {},
} = props;
console.log("remote player props 2", options);
const videoRef = useRef(null);
useEffect(() => {
console.log("remote player props", props);
}, [props])
useEffect(() => {
// const observeVideoProgress = setInterval(() => {
// const video = (videoRef && videoRef.current) || null;
// if (video && !video.paused) {
// const { duration, currentTime } = video;
// videoProgress({
// duration,
// currentTime,
// });
// }
// }, 500);
// return () => {
// clearInterval(observeVideoProgress);
// };
});
useEffect(() => {
// assign default plugin options to existing given plugin options
const pluginConfig = {};
for (const [key, value] of Object.entries(options.pluginOptions)) {
pluginConfig[key] = isObject(value)
? Object.assign({}, DEFAULT_OPTIONS.pluginOptions[key], value)
: value;
}
Object.assign(options.pluginOptions, pluginConfig);
const playerOptions = Object.assign(
{},
// consts.PLAYER_CONFIG,
DEFAULT_OPTIONS,
options
);
const onEachRequest = (player) => {
try {
const tech = player.videojs.tech().vhs;
if (tech && tech.xhr) {
tech.xhr.beforeRequest = function (xhrOptions) {
const { extraData } = options;
if(extraData) {
xhrOptions.uri = QueryParameter.append(
cookiesName.UuidUnderLine,
extraData[cookiesName.UuidUnderLine],
xhrOptions.uri
);
}
return xhrOptions;
};
}
} catch {
console.error("Error: error in xhr.beforeRequest on player");
}
};
const player = new VJSPlayer(videoRef.current, playerOptions, (player) => {
// onReady(player);
// onEachRequest(player);
});
return () => {
if (player) {
player.dispose();
}
};
});
return (
<div className={["wrapper", ...className].join(" ")} style={{position: "relative", width: "100%", height: "100%", backgroundColor: "rgb(0, 0, 0)"}}>
<div data-vjs-player>
<video
ref={videoRef}
className={[
"video-js",
"vjs-big-play-centered",
"fullscreen ",
"fullScreen-fixed",
"vjs-fill",
].join(" ")}
autoFocus
/>
</div>
</div>
);
};
VideoPlayer.propTypes = {
className: PropTypes.array,
options: PropTypes.object,
videoProgress: PropTypes.func,
onReady: PropTypes.func,
};
export default VideoPlayer;