UNPKG

panjareh

Version:

Panjareh using aparat and phoenix-video-player to play videos on desktops and tvs.

268 lines (245 loc) 7.22 kB
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;