24 changed files with 337 additions and 82 deletions
@ -1,37 +1,63 @@ |
|||||||
|
import { proxiedFetch } from "../helpers/fetch"; |
||||||
import { registerProvider } from "../helpers/register"; |
import { registerProvider } from "../helpers/register"; |
||||||
|
import { MWStreamQuality, MWStreamType } from "../helpers/streams"; |
||||||
import { MWMediaType } from "../metadata/types"; |
import { MWMediaType } from "../metadata/types"; |
||||||
|
|
||||||
const timeout = (time: number) => |
const flixHqBase = "https://api.consumet.org/movies/flixhq"; |
||||||
new Promise<void>((resolve) => { |
|
||||||
setTimeout(() => resolve(), time); |
|
||||||
}); |
|
||||||
|
|
||||||
registerProvider({ |
registerProvider({ |
||||||
id: "testprov", |
id: "flixhq", |
||||||
rank: 42, |
displayName: "FlixHQ", |
||||||
|
rank: 100, |
||||||
type: [MWMediaType.MOVIE], |
type: [MWMediaType.MOVIE], |
||||||
disabled: true, |
|
||||||
|
|
||||||
async scrape({ progress }) { |
async scrape({ media, progress }) { |
||||||
await timeout(1000); |
// search for relevant item
|
||||||
|
const searchResults = await proxiedFetch<any>( |
||||||
|
`/${encodeURIComponent(media.meta.title)}`, |
||||||
|
{ |
||||||
|
baseURL: flixHqBase, |
||||||
|
} |
||||||
|
); |
||||||
|
// TODO fuzzy match or normalize title before comparison
|
||||||
|
const foundItem = searchResults.results.find((v: any) => { |
||||||
|
return v.title === media.meta.title && v.releaseDate === media.meta.year; |
||||||
|
}); |
||||||
|
if (!foundItem) throw new Error("No watchable item found"); |
||||||
|
const flixId = foundItem.id; |
||||||
|
|
||||||
|
// get media info
|
||||||
progress(25); |
progress(25); |
||||||
await timeout(1000); |
const mediaInfo = await proxiedFetch<any>("/info", { |
||||||
progress(50); |
baseURL: flixHqBase, |
||||||
await timeout(1000); |
params: { |
||||||
|
id: flixId, |
||||||
|
}, |
||||||
|
}); |
||||||
|
|
||||||
|
// get stream info from media
|
||||||
progress(75); |
progress(75); |
||||||
await timeout(1000); |
const watchInfo = await proxiedFetch<any>("/watch", { |
||||||
|
baseURL: flixHqBase, |
||||||
|
params: { |
||||||
|
episodeId: mediaInfo.episodes[0].id, |
||||||
|
mediaId: flixId, |
||||||
|
}, |
||||||
|
}); |
||||||
|
|
||||||
|
// get best quality source
|
||||||
|
const source = watchInfo.sources.reduce((p: any, c: any) => |
||||||
|
c.quality > p.quality ? c : p |
||||||
|
); |
||||||
|
|
||||||
return { |
return { |
||||||
embeds: [ |
embeds: [], |
||||||
// {
|
stream: { |
||||||
// type: MWEmbedType.OPENLOAD,
|
streamUrl: source.url, |
||||||
// url: "https://google.com",
|
quality: MWStreamQuality.QUNKNOWN, |
||||||
// },
|
type: source.isM3U8 ? MWStreamType.HLS : MWStreamType.MP4, |
||||||
// {
|
captions: [], |
||||||
// type: MWEmbedType.ANOTHER,
|
}, |
||||||
// url: "https://google.com",
|
|
||||||
// },
|
|
||||||
], |
|
||||||
}; |
}; |
||||||
}, |
}, |
||||||
}); |
}); |
||||||
|
@ -1,26 +1,46 @@ |
|||||||
import { useEffect } from "react"; |
import { useEffect, useRef } from "react"; |
||||||
import { useVideoPlayerState } from "../VideoContext"; |
import { useVideoPlayerState } from "../VideoContext"; |
||||||
|
|
||||||
interface ShowControlProps { |
interface ShowControlProps { |
||||||
series?: { |
series?: { |
||||||
episode: number; |
episodeId: string; |
||||||
season: number; |
seasonId: string; |
||||||
}; |
}; |
||||||
title?: string; |
onSelect?: (state: { episodeId?: string; seasonId?: string }) => void; |
||||||
} |
} |
||||||
|
|
||||||
export function ShowControl(props: ShowControlProps) { |
export function ShowControl(props: ShowControlProps) { |
||||||
const { videoState } = useVideoPlayerState(); |
const { videoState } = useVideoPlayerState(); |
||||||
|
const lastState = useRef<{ |
||||||
|
episodeId?: string; |
||||||
|
seasonId?: string; |
||||||
|
} | null>({ |
||||||
|
episodeId: props.series?.episodeId, |
||||||
|
seasonId: props.series?.seasonId, |
||||||
|
}); |
||||||
|
|
||||||
useEffect(() => { |
useEffect(() => { |
||||||
videoState.setShowData({ |
videoState.setShowData({ |
||||||
current: props.series, |
current: props.series, |
||||||
isSeries: !!props.series, |
isSeries: !!props.series, |
||||||
title: props.title, |
|
||||||
}); |
}); |
||||||
// we only want it to run when props change, not when videoState changes
|
// we only want it to run when props change, not when videoState changes
|
||||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, [props]); |
}, [props]); |
||||||
|
|
||||||
|
useEffect(() => { |
||||||
|
const currentState = { |
||||||
|
episodeId: videoState.seasonData.current?.episodeId, |
||||||
|
seasonId: videoState.seasonData.current?.seasonId, |
||||||
|
}; |
||||||
|
if ( |
||||||
|
currentState.episodeId !== lastState.current?.episodeId || |
||||||
|
currentState.seasonId !== lastState.current?.seasonId |
||||||
|
) { |
||||||
|
lastState.current = currentState; |
||||||
|
props.onSelect?.(currentState); |
||||||
|
} |
||||||
|
}, [videoState, props]); |
||||||
|
|
||||||
return null; |
return null; |
||||||
} |
} |
||||||
|
Loading…
Reference in new issue