feat: implement default quality setting

This commit is contained in:
Adrian Castro
2024-04-11 20:53:53 +02:00
parent 45d12bbf41
commit 4a3d363bf2
10 changed files with 660 additions and 103 deletions

View File

@@ -2,7 +2,8 @@ import type { AppendToResponse, MovieDetails, TvShowDetails } from "tmdb-ts";
import type { ScrapeMedia } from "@movie-web/providers";
import { providers } from "./video";
import type { HLSTracks } from "./video";
import { constructFullUrl, providers } from "./video";
export function getMetaData() {
return [...providers.listSources(), ...providers.listEmbeds()];
@@ -59,3 +60,31 @@ export function transformSearchResultToScrapeMedia<T extends "tv" | "movie">(
throw new Error("Invalid type parameter");
}
interface AudioTrack {
uri: string;
name: string;
language: string;
active?: boolean;
}
export function filterAudioTracks(tracks: HLSTracks, playlist: string) {
const audioTracks: AudioTrack[] = tracks.audio.map((track) => ({
uri: constructFullUrl(playlist, track.uri),
name: track.properties[0]?.attributes.name?.toString() ?? "Unknown",
language: track.properties[0]?.attributes.language?.toString() ?? "Unknown",
active: Boolean(track.properties[0]?.attributes.default) ?? false,
}));
const uniqueTracks = new Set(audioTracks.map((t) => t.language));
const filteredAudioTracks = audioTracks.filter((track) => {
if (uniqueTracks.has(track.language)) {
uniqueTracks.delete(track.language);
return true;
}
return false;
});
return filteredAudioTracks;
}

View File

@@ -149,8 +149,9 @@ export async function getVideoStreamFromEmbed({
}
}
export function findHighestQuality(
export function findQuality(
stream: FileBasedStream,
highest = true,
): Qualities | undefined {
const qualityOrder: Qualities[] = [
"4k",
@@ -160,6 +161,9 @@ export function findHighestQuality(
"360",
"unknown",
];
if (!highest) {
qualityOrder.reverse();
}
for (const quality of qualityOrder) {
if (stream.qualities[quality]) {
return quality;
@@ -193,9 +197,10 @@ export async function extractTracksFromHLS(
}
}
export async function extractSegmentsFromHLS(
export async function findHLSQuality(
playlistUrl: string,
headers: Record<string, string>,
headers?: Record<string, string>,
highest = true,
) {
try {
const response = await fetch(playlistUrl, { headers }).then((res) =>
@@ -220,17 +225,29 @@ export async function extractSegmentsFromHLS(
return widthB * heightB - widthA * heightA;
});
const highestQuality = sortedStreams[0];
if (!highestQuality) return null;
const chosenQuality = sortedStreams[highest ? 0 : sortedStreams.length - 1];
if (!chosenQuality) return null;
const highestQualityUri = constructFullUrl(playlistUrl, highestQuality.uri);
const highestQualityResponse = await fetch(highestQualityUri, {
headers,
}).then((res) => res.text());
const highestQualityPlaylist = hls.parse(highestQualityResponse);
return chosenQuality.uri;
} catch (e) {
return null;
}
}
return highestQualityPlaylist.segments.map((segment) =>
constructFullUrl(highestQualityUri, segment.uri),
export async function extractSegmentsFromHLS(
playlistUrl: string,
headers: Record<string, string>,
) {
try {
const highestQualityUrl = await findHLSQuality(playlistUrl, headers);
if (!highestQualityUrl) return null;
const response = await fetch(highestQualityUrl, { headers }).then((res) =>
res.text(),
);
const playlist = hls.parse(response);
return playlist.segments.map((segment) =>
constructFullUrl(highestQualityUrl, segment.uri),
);
} catch (e) {
return null;