mirror of
https://github.com/movie-web/providers.git
synced 2025-09-13 10:33:25 +00:00
introduce captions
This commit is contained in:
19
src/providers/captions.ts
Normal file
19
src/providers/captions.ts
Normal file
@@ -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;
|
||||
}
|
@@ -65,6 +65,7 @@ export const febBoxScraper = makeEmbed({
|
||||
return {
|
||||
stream: {
|
||||
type: 'file',
|
||||
captions: [],
|
||||
flags: [flags.NO_CORS],
|
||||
qualities: embedQualities,
|
||||
},
|
||||
|
@@ -36,6 +36,7 @@ export const mixdropScraper = makeEmbed({
|
||||
stream: {
|
||||
type: 'file',
|
||||
flags: [],
|
||||
captions: [],
|
||||
qualities: {
|
||||
unknown: {
|
||||
type: 'mp4',
|
||||
|
@@ -18,6 +18,7 @@ export const mp4uploadScraper = makeEmbed({
|
||||
stream: {
|
||||
type: 'file',
|
||||
flags: [flags.NO_CORS],
|
||||
captions: [],
|
||||
qualities: {
|
||||
'1080': {
|
||||
type: 'mp4',
|
||||
|
@@ -159,6 +159,7 @@ export const streamsbScraper = makeEmbed({
|
||||
type: 'file',
|
||||
flags: [flags.NO_CORS],
|
||||
qualities,
|
||||
captions: [],
|
||||
},
|
||||
};
|
||||
},
|
||||
|
@@ -101,6 +101,7 @@ export const upcloudScraper = makeEmbed({
|
||||
type: 'hls',
|
||||
playlist: sources.file,
|
||||
flags: [flags.NO_CORS],
|
||||
captions: [],
|
||||
},
|
||||
};
|
||||
},
|
||||
|
@@ -25,6 +25,7 @@ export const upstreamScraper = makeEmbed({
|
||||
type: 'hls',
|
||||
playlist: link[1],
|
||||
flags: [flags.NO_CORS],
|
||||
captions: [],
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@@ -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],
|
||||
|
@@ -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<string, StreamFile> = {};
|
||||
@@ -28,5 +30,8 @@ export async function getStreamQualities(ctx: ScrapeContext, apiQuery: object) {
|
||||
}
|
||||
});
|
||||
|
||||
return qualities;
|
||||
return {
|
||||
qualities,
|
||||
fid: mediaRes.list[0]?.fid,
|
||||
};
|
||||
}
|
||||
|
@@ -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],
|
||||
|
37
src/providers/sources/superstream/subtitles.ts
Normal file
37
src/providers/sources/superstream/subtitles.ts
Normal file
@@ -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<Caption[]> {
|
||||
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 [];
|
||||
}
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user