2023-10-12 20:31:40 +02:00
|
|
|
import { RunOutput } from "@movie-web/providers";
|
|
|
|
import { useCallback } from "react";
|
|
|
|
import { useParams } from "react-router-dom";
|
|
|
|
import { useAsync } from "react-use";
|
2023-10-08 18:16:30 +02:00
|
|
|
|
2023-10-05 22:12:25 +02:00
|
|
|
import { MWStreamType } from "@/backend/helpers/streams";
|
2023-10-12 20:31:40 +02:00
|
|
|
import { getMetaFromId } from "@/backend/metadata/getmeta";
|
|
|
|
import { decodeTMDBId } from "@/backend/metadata/tmdb";
|
2023-09-30 20:57:00 +02:00
|
|
|
import { usePlayer } from "@/components/player/hooks/usePlayer";
|
2023-10-12 20:31:40 +02:00
|
|
|
import { usePlayerMeta } from "@/components/player/hooks/usePlayerMeta";
|
|
|
|
import { PlayerPart } from "@/pages/parts/player/PlayerPart";
|
2023-10-01 21:08:26 +02:00
|
|
|
import { ScrapingPart } from "@/pages/parts/player/ScrapingPart";
|
2023-10-12 20:31:40 +02:00
|
|
|
import { playerStatus } from "@/stores/player/slices/source";
|
2023-07-23 15:00:08 +02:00
|
|
|
|
|
|
|
export function PlayerView() {
|
2023-10-12 20:31:40 +02:00
|
|
|
const params = useParams<{
|
|
|
|
media: string;
|
|
|
|
episode?: string;
|
|
|
|
season?: string;
|
|
|
|
}>();
|
|
|
|
const { status, playMedia } = usePlayer();
|
|
|
|
const { setPlayerMeta, scrapeMedia } = usePlayerMeta();
|
2023-10-11 23:04:41 +02:00
|
|
|
|
2023-10-12 20:31:40 +02:00
|
|
|
const { loading, error } = useAsync(async () => {
|
|
|
|
const data = decodeTMDBId(params.media);
|
|
|
|
if (!data) return;
|
2023-10-11 22:09:28 +02:00
|
|
|
|
2023-10-12 20:31:40 +02:00
|
|
|
const meta = await getMetaFromId(data.type, data.id, params.season);
|
|
|
|
if (!meta) return;
|
2023-10-08 19:35:11 +02:00
|
|
|
|
2023-10-12 20:31:40 +02:00
|
|
|
setPlayerMeta(meta);
|
|
|
|
}, []);
|
2023-10-02 21:04:40 +02:00
|
|
|
|
2023-10-12 20:31:40 +02:00
|
|
|
const playAfterScrape = useCallback(
|
|
|
|
(out: RunOutput | null) => {
|
|
|
|
if (out?.stream.type !== "file") return;
|
|
|
|
const qualities = Object.keys(out.stream.qualities).sort(
|
|
|
|
(a, b) => Number(b) - Number(a)
|
|
|
|
) as (keyof typeof out.stream.qualities)[];
|
2023-10-05 22:12:25 +02:00
|
|
|
|
2023-10-12 20:31:40 +02:00
|
|
|
let file;
|
|
|
|
for (const quality of qualities) {
|
|
|
|
if (out.stream.qualities[quality]?.url) {
|
|
|
|
file = out.stream.qualities[quality];
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-10-05 22:12:25 +02:00
|
|
|
|
2023-10-12 20:31:40 +02:00
|
|
|
if (!file) return;
|
2023-10-11 23:04:41 +02:00
|
|
|
|
2023-10-12 20:31:40 +02:00
|
|
|
playMedia({
|
|
|
|
type: MWStreamType.MP4,
|
|
|
|
url: file.url,
|
|
|
|
});
|
|
|
|
},
|
|
|
|
[playMedia]
|
|
|
|
);
|
2023-10-05 22:12:25 +02:00
|
|
|
|
2023-10-12 20:31:40 +02:00
|
|
|
return (
|
|
|
|
<PlayerPart>
|
|
|
|
{status === playerStatus.IDLE ? (
|
|
|
|
<div className="flex items-center justify-center">
|
|
|
|
{loading ? <p>loading meta...</p> : null}
|
|
|
|
{error ? <p>failed to load meta!</p> : null}
|
2023-10-01 21:08:26 +02:00
|
|
|
</div>
|
2023-10-12 20:31:40 +02:00
|
|
|
) : null}
|
|
|
|
{status === playerStatus.SCRAPING && scrapeMedia ? (
|
|
|
|
<ScrapingPart media={scrapeMedia} onGetStream={playAfterScrape} />
|
|
|
|
) : null}
|
|
|
|
</PlayerPart>
|
2023-07-23 15:00:08 +02:00
|
|
|
);
|
|
|
|
}
|