diff --git a/src/providers/captions.ts b/src/providers/captions.ts new file mode 100644 index 0000000..be3bf81 --- /dev/null +++ b/src/providers/captions.ts @@ -0,0 +1,19 @@ +export const captionTypes = { + srt: 'srt', + vtt: 'vtt', +}; +export type CaptionType = keyof typeof captionTypes; + +export type Caption = { + type: CaptionType; + url: string; + hasCorsRestrictions: boolean; + language: string; +}; + +export function getCaptionTypeFromUrl(url: string): CaptionType | null { + const extensions = Object.keys(captionTypes) as CaptionType[]; + const type = extensions.find((v) => url.endsWith(`.${v}`)); + if (!type) return null; + return type; +} diff --git a/src/providers/embeds/febBox.ts b/src/providers/embeds/febBox.ts index 06a3414..7855745 100644 --- a/src/providers/embeds/febBox.ts +++ b/src/providers/embeds/febBox.ts @@ -65,6 +65,7 @@ export const febBoxScraper = makeEmbed({ return { stream: { type: 'file', + captions: [], flags: [flags.NO_CORS], qualities: embedQualities, }, diff --git a/src/providers/embeds/mixdrop.ts b/src/providers/embeds/mixdrop.ts index e7df2cf..007738a 100644 --- a/src/providers/embeds/mixdrop.ts +++ b/src/providers/embeds/mixdrop.ts @@ -36,6 +36,7 @@ export const mixdropScraper = makeEmbed({ stream: { type: 'file', flags: [], + captions: [], qualities: { unknown: { type: 'mp4', diff --git a/src/providers/embeds/mp4upload.ts b/src/providers/embeds/mp4upload.ts index 4524018..81c2f94 100644 --- a/src/providers/embeds/mp4upload.ts +++ b/src/providers/embeds/mp4upload.ts @@ -18,6 +18,7 @@ export const mp4uploadScraper = makeEmbed({ stream: { type: 'file', flags: [flags.NO_CORS], + captions: [], qualities: { '1080': { type: 'mp4', diff --git a/src/providers/embeds/streamsb.ts b/src/providers/embeds/streamsb.ts index a42355a..d15b320 100644 --- a/src/providers/embeds/streamsb.ts +++ b/src/providers/embeds/streamsb.ts @@ -159,6 +159,7 @@ export const streamsbScraper = makeEmbed({ type: 'file', flags: [flags.NO_CORS], qualities, + captions: [], }, }; }, diff --git a/src/providers/embeds/upcloud.ts b/src/providers/embeds/upcloud.ts index 617c15a..683327f 100644 --- a/src/providers/embeds/upcloud.ts +++ b/src/providers/embeds/upcloud.ts @@ -101,6 +101,7 @@ export const upcloudScraper = makeEmbed({ type: 'hls', playlist: sources.file, flags: [flags.NO_CORS], + captions: [], }, }; }, diff --git a/src/providers/embeds/upstream.ts b/src/providers/embeds/upstream.ts index 62d2f01..852aac7 100644 --- a/src/providers/embeds/upstream.ts +++ b/src/providers/embeds/upstream.ts @@ -25,6 +25,7 @@ export const upstreamScraper = makeEmbed({ type: 'hls', playlist: link[1], flags: [flags.NO_CORS], + captions: [], }, }; } diff --git a/src/providers/sources/remotestream.ts b/src/providers/sources/remotestream.ts index 80a8621..696d897 100644 --- a/src/providers/sources/remotestream.ts +++ b/src/providers/sources/remotestream.ts @@ -23,6 +23,7 @@ export const remotestreamScraper = makeSourcerer({ return { embeds: [], stream: { + captions: [], playlist: playlistLink, type: 'hls', flags: [flags.NO_CORS], @@ -40,6 +41,7 @@ export const remotestreamScraper = makeSourcerer({ return { embeds: [], stream: { + captions: [], playlist: playlistLink, type: 'hls', flags: [flags.NO_CORS], diff --git a/src/providers/sources/superstream/getStreamQualities.ts b/src/providers/sources/superstream/getStreamQualities.ts index f968a18..655964d 100644 --- a/src/providers/sources/superstream/getStreamQualities.ts +++ b/src/providers/sources/superstream/getStreamQualities.ts @@ -6,14 +6,16 @@ import { sendRequest } from './sendRequest'; const allowedQualities = ['360', '480', '720', '1080']; export async function getStreamQualities(ctx: ScrapeContext, apiQuery: object) { - const mediaRes: { list: { path: string; real_quality: string }[] } = (await sendRequest(ctx, apiQuery)).data; + const mediaRes: { list: { path: string; quality: string; fid?: number }[] } = (await sendRequest(ctx, apiQuery)).data; ctx.progress(66); + console.log(mediaRes); + const qualityMap = mediaRes.list - .filter((file) => allowedQualities.includes(file.real_quality.replace('p', ''))) + .filter((file) => allowedQualities.includes(file.quality.replace('p', ''))) .map((file) => ({ url: file.path, - quality: file.real_quality.replace('p', ''), + quality: file.quality.replace('p', ''), })); const qualities: Record = {}; @@ -28,5 +30,8 @@ export async function getStreamQualities(ctx: ScrapeContext, apiQuery: object) { } }); - return qualities; + return { + qualities, + fid: mediaRes.list[0]?.fid, + }; } diff --git a/src/providers/sources/superstream/index.ts b/src/providers/sources/superstream/index.ts index 25286da..8e78167 100644 --- a/src/providers/sources/superstream/index.ts +++ b/src/providers/sources/superstream/index.ts @@ -1,5 +1,6 @@ import { flags } from '@/main/targets'; import { makeSourcerer } from '@/providers/base'; +import { getSubtitles } from '@/providers/sources/superstream/subtitles'; import { compareTitle } from '@/utils/compare'; import { NotFoundError } from '@/utils/errors'; @@ -41,11 +42,19 @@ export const superStreamScraper = makeSourcerer({ group: '', }; - const qualities = await getStreamQualities(ctx, apiQuery); + const { qualities, fid } = await getStreamQualities(ctx, apiQuery); return { embeds: [], stream: { + captions: await getSubtitles( + ctx, + superstreamId, + fid, + 'show', + ctx.media.episode.number, + ctx.media.season.number, + ), qualities, type: 'file', flags: [flags.NO_CORS], @@ -80,11 +89,12 @@ export const superStreamScraper = makeSourcerer({ group: '', }; - const qualities = await getStreamQualities(ctx, apiQuery); + const { qualities, fid } = await getStreamQualities(ctx, apiQuery); return { embeds: [], stream: { + captions: await getSubtitles(ctx, superstreamId, fid, 'movie'), qualities, type: 'file', flags: [flags.NO_CORS], diff --git a/src/providers/sources/superstream/subtitles.ts b/src/providers/sources/superstream/subtitles.ts new file mode 100644 index 0000000..89cdc39 --- /dev/null +++ b/src/providers/sources/superstream/subtitles.ts @@ -0,0 +1,37 @@ +import { Caption } from '@/providers/captions'; +import { sendRequest } from '@/providers/sources/superstream/sendRequest'; +import { ScrapeContext } from '@/utils/context'; + +interface CaptionApiResponse { + data: { + list: { + language: string; + subtitles: { + file_path: string; + }[]; + }[]; + }; +} + +export async function getSubtitles( + ctx: ScrapeContext, + id: string, + fid: number | undefined, + type: 'show' | 'movie', + episodeId?: number, + seasonId?: number, +): Promise { + const module = type === 'movie' ? 'Movie_srt_list_v2' : 'TV_srt_list_v2'; + const subtitleApiQuery = { + fid, + uid: '', + module, + mid: id, + episode: episodeId?.toString(), + season: seasonId?.toString(), + group: episodeId ? '' : undefined, + }; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const _subtitleList = ((await sendRequest(ctx, subtitleApiQuery)) as CaptionApiResponse).data.list; + return []; +} diff --git a/src/providers/streams.ts b/src/providers/streams.ts index 8a4674c..25847b2 100644 --- a/src/providers/streams.ts +++ b/src/providers/streams.ts @@ -1,4 +1,5 @@ import { Flags } from '@/main/targets'; +import { Caption } from '@/providers/captions'; export type StreamFile = { type: 'mp4'; @@ -18,6 +19,7 @@ export type HlsBasedStream = { type: 'hls'; flags: Flags[]; playlist: string; + captions: Caption[]; }; export type Stream = FileBasedStream | HlsBasedStream;