diff --git a/src/backend/index.ts b/src/backend/index.ts index eb0ad897..d62f557b 100644 --- a/src/backend/index.ts +++ b/src/backend/index.ts @@ -9,6 +9,7 @@ import "./providers/m4ufree"; import "./providers/hdwatched"; import "./providers/2embed"; import "./providers/sflix"; +import "./providers/remotestream"; // embeds import "./embeds/streamm4u"; diff --git a/src/backend/providers/remotestream.ts b/src/backend/providers/remotestream.ts new file mode 100644 index 00000000..02c0f199 --- /dev/null +++ b/src/backend/providers/remotestream.ts @@ -0,0 +1,49 @@ +import { mwFetch } from "@/backend/helpers/fetch"; +import { registerProvider } from "@/backend/helpers/register"; +import { MWStreamQuality, MWStreamType } from "@/backend/helpers/streams"; +import { MWMediaType } from "@/backend/metadata/types"; + +const remotestreamBase = `https://fsa.remotestre.am`; + +registerProvider({ + id: "remotestream", + displayName: "Remote Stream", + disabled: false, + rank: 55, + type: [MWMediaType.MOVIE, MWMediaType.SERIES], + + async scrape({ media, episode, progress }) { + if (!this.type.includes(media.meta.type)) { + throw new Error("Unsupported type"); + } + + progress(30); + const type = media.meta.type === MWMediaType.MOVIE ? "Movies" : "Shows"; + let playlistLink = `${remotestreamBase}/${type}/${media.tmdbId}`; + + if (media.meta.type === MWMediaType.SERIES) { + const seasonNumber = media.meta.seasonData.number; + const episodeNumber = media.meta.seasonData.episodes.find( + (e) => e.id === episode + )?.number; + + playlistLink += `/${seasonNumber}/${episodeNumber}/${episodeNumber}.m3u8`; + } else { + playlistLink += `/${media.tmdbId}.m3u8`; + } + + const streamRes = await mwFetch(playlistLink); + if (streamRes.type !== "application/x-mpegurl") + throw new Error("No watchable item found"); + progress(90); + return { + embeds: [], + stream: { + streamUrl: playlistLink, + quality: MWStreamQuality.QUNKNOWN, + type: MWStreamType.HLS, + captions: [], + }, + }; + }, +});