UNPKG

panjareh

Version:

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

153 lines (143 loc) 4.13 kB
/* eslint-disable react/jsx-no-bind */ import PropTypes from "prop-types"; import React, { Suspense, useEffect, useState } from "react"; import { ProductAPI } from "../api"; import Product from "../api/product"; import consts from "../config/consts"; import useUserContext from "../hooks/useUserContext"; import * as Sentry from "../services/sentry-service"; import DesktopPlayerController from "./desktop/controller"; const VideoPlayer = React.lazy(() => import("../components/desktopPlayer")); const MessageInfo = React.lazy(() => import("../components/messageInfo")); Sentry.init(); const DesktopPlayer = ({ data }) => { const { alias, return_url } = data; const [loading, setLoading] = useState(true); const [error, setError] = useState(false); const [hasTicket, setHasTicket] = useState(false); const [notFound, setNotFound] = useState(false); const [product, setProduct] = useState(null); const [controller, setController] = useState(null); const [playerConfig, setPlayerConfig] = useState(null); const { state: { isAuthenticated, token, uuid }, } = useUserContext(); const playerRef = React.useRef(null); useEffect(() => { ProductAPI.query(alias) .then((response) => { const productData = response?.body || {}; const product = new Product(productData); setController( new DesktopPlayerController({ isAuthenticated, alias, token, uuid, product, return_url, }) ); setProduct(product); }) .catch(function (err) { console.error(`PLAYER : Fetch product data, ${err?.message || err}`); setNotFound(true); }); }, [alias]); const preparePlayer = async (response) => { if (response) { const { config, loading } = await controller.preparePlayerConfig( response ); if (config) { setPlayerConfig(config); setLoading(loading); } } }; useEffect(async () => { if (!product) return; if (product.isEkran()) { const res = await controller.fetchEkranStreamLink(); if (res) { const { hasTicket } = res; setHasTicket(hasTicket); if (hasTicket) { await preparePlayer(res); } else { setError(true); } } } else { if (product.canWatch()) { const res = await controller.fetchStreamLink(); await preparePlayer(res); } else { setError(true); } } }, [product]); const handlePlayerReady = ({ videojs }) => { playerRef.current = videojs; // you can handle player events here videojs.on("waiting", () => {}); videojs.on("dispose", () => { console.log("player will dispose"); }); }; const PlayerElement = () => { return ( <> <Suspense fallback={"loading..."}> <VideoPlayer options={playerConfig} onReady={handlePlayerReady} /> </Suspense> </> ); }; const RenderPlayer = ({ product = null }) => { if (product) { if (product.canWatch()) { return <PlayerElement />; } else if (product.isEkran() && hasTicket) { return <PlayerElement />; } } return null; }; RenderPlayer.propTypes = { product: PropTypes.object, }; return ( <div style={{ display: "flex", justifyContent: "center", alignItems: "center", }} > {playerConfig && <RenderPlayer product={product} />} {notFound && ( <Suspense fallback={<div />}> <MessageInfo productStatus={"unavailable"} /> </Suspense> )} {error && ( <Suspense fallback={<div />}> <MessageInfo productStatus={product.getProductStatus()} url={return_url ? return_url : consts.SITE_URL} /> </Suspense> )} {loading && <div>loading...</div>} </div> ); }; DesktopPlayer.propTypes = { data: PropTypes.shape({ alias: PropTypes.string, return_url: PropTypes.string, }), }; export default DesktopPlayer;