panjareh
Version:
Panjareh using aparat and phoenix-video-player to play videos on desktops and tvs.
153 lines (143 loc) • 4.12 kB
JavaScript
/* 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 useUserContext from "../hooks/useUserContext";
import consts from "../config/consts";
import * as Sentry from "../services/sentry-service";
import DesktopPlayerController from "./desktop/controller";
const VideoPlayer = React.lazy(() => import("../components/tvPlayer"));
const MessageInfo = React.lazy(() => import("../components/messageInfo"));
Sentry.init(true);
const TvPlayer = ({ data }) => {
const { alias, return_url } = data;
const [loading, setLoading] = useState(true);
const [notFound, setNotFound] = useState(false);
const [error, setError] = useState(false);
const [hasTicket, setHasTicket] = 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>
);
};
TvPlayer.propTypes = {
data: PropTypes.shape({
alias: PropTypes.string,
return_url: PropTypes.string,
}),
};
export default TvPlayer;