UNPKG

panjareh

Version:

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

262 lines (241 loc) 6.84 kB
import React, { useEffect, useRef } from "react"; import { isObject } from "../utils"; import VJSPlayer from "@filmgardi/phoenix-video-player"; import PropTypes from "prop-types"; import QueryParameter from "../utils/queryParameter"; import cookiesName from "../enums/cookies-name"; import "@filmgardi/phoenix-video-player/dist/phoenix-video-player.min.css"; import "@filmgardi/videojs-phoenix-theme/dist/videojs-phoenix-theme.css"; const DEFAULT_OPTIONS = { autoplay: false, controls: true, playbackRates: [0.5, 1, 1.25, 1.5], language: "fa", // addLanguage: { fa: fa }, poster: "", sources: [], info: { title: null, subTitle: null }, returnUrl: null, html5: { nativeTextTracks: !1, hlsjsConfig: { // Put your hls.js config here // debug: true, enableWorker: false, lowLatencyMode: true, backBufferLength: 60, // 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: 46, offsetV: 46, }, 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 = ({ className = "", options, onReady = () => {}, videoProgress = () => {}, }) => { const videoRef = useRef(null); 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; } DEFAULT_OPTIONS.html5.hlsjsConfig["xhrSetup"] = function (xhr, url) { const { extraData } = options; url = QueryParameter.append( cookiesName.UuidUnderLine, extraData[cookiesName.UuidUnderLine], url ); xhr.open("GET", url, true); }; Object.assign(options.pluginOptions, pluginConfig); const playerOptions = Object.assign( {}, // consts.PLAYER_CONFIG, DEFAULT_OPTIONS, options ); const player = new VJSPlayer(videoRef.current, playerOptions, (player) => { onReady(player); }); return () => { if (player) { player.dispose(); } }; }); return ( <div className={["wrapper", ...className].join(" ")}> <div data-vjs-player> <video ref={videoRef} className={[ "video-js", "vjs-big-play-centered", "fullscreen", "fullScreen-fixed", "vjs-fill", ].join(" ")} /> </div> </div> ); }; VideoPlayer.defaultProps = { className: [], autoplay: false, controls: true, playbackRates: [0.25, 0.5, 0.75, 1, 1.25, 1.5, 1.75, 2], poster: "", sources: [], videoProgress: () => null, onReady: () => null, }; VideoPlayer.propTypes = { className: PropTypes.array, options: PropTypes.object, autoplay: PropTypes.bool, controls: PropTypes.bool, playbackRates: PropTypes.array, poster: PropTypes.string, sources: PropTypes.array, videoProgress: PropTypes.func, onReady: PropTypes.func, }; export default VideoPlayer;