api: add DURATION_LIMIT env variable

duration limit is now in seconds and customizable across instances
This commit is contained in:
wukko 2024-05-16 20:57:48 +06:00
parent b5c81084c8
commit d1e8929ee2
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2
12 changed files with 29 additions and 29 deletions

View file

@ -1,6 +1,5 @@
{
"streamLifespan": 90000,
"maxVideoDuration": 10800000,
"genericUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36",
"authorInfo": {
"support": {

View file

@ -44,6 +44,8 @@ const
rateLimitWindow: (process.env.RATELIMIT_WINDOW && parseInt(process.env.RATELIMIT_WINDOW)) || 60,
rateLimitMax: (process.env.RATELIMIT_MAX && parseInt(process.env.RATELIMIT_MAX)) || 20,
durationLimit: (process.env.DURATION_LIMIT && parseInt(process.env.DURATION_LIMIT)) || 10800,
processingPriority: process.platform !== 'win32'
&& process.env.PROCESSING_PRIORITY
&& parseInt(process.env.PROCESSING_PRIORITY)
@ -54,7 +56,6 @@ export const
audioIgnore = servicesConfigJson.audioIgnore,
version = packageJson.version,
streamLifespan = config.streamLifespan,
maxVideoDuration = config.maxVideoDuration,
genericUserAgent = config.genericUserAgent,
repo = packageJson.bugs.url.replace('/issues', ''),
authorInfo = config.authorInfo,

View file

@ -1,4 +1,4 @@
import { genericUserAgent, maxVideoDuration } from "../../config.js";
import { genericUserAgent, env } from "../../config.js";
// TO-DO: higher quality downloads (currently requires an account)
@ -39,8 +39,8 @@ async function com_download(id) {
}
let streamData = JSON.parse(html.split('<script>window.__playinfo__=')[1].split('</script>')[0]);
if (streamData.data.timelength > maxVideoDuration) {
return { error: ['ErrorLengthLimit', maxVideoDuration / 60000] };
if (streamData.data.timelength > env.durationLimit * 1000) {
return { error: ['ErrorLengthLimit', env.durationLimit / 60] };
}
const [ video, audio ] = extractBestQuality(streamData.data.dash);
@ -79,8 +79,8 @@ async function tv_download(id) {
return { error: 'ErrorEmptyDownload' };
}
if (video.duration > maxVideoDuration) {
return { error: ['ErrorLengthLimit', maxVideoDuration / 60000] };
if (video.duration > env.durationLimit * 1000) {
return { error: ['ErrorLengthLimit', env.durationLimit / 60] };
}
return {

View file

@ -1,5 +1,5 @@
import HLSParser from 'hls-parser';
import { maxVideoDuration } from '../../config.js';
import { env } from '../../config.js';
let _token;
@ -73,8 +73,8 @@ export default async function({ id }) {
return { error: 'ErrorEmptyDownload' }
}
if (media.duration * 1000 > maxVideoDuration) {
return { error: ['ErrorLengthLimit', maxVideoDuration / 60000] };
if (media.duration > env.durationLimit) {
return { error: ['ErrorLengthLimit', env.durationLimit / 60] };
}
const manifest = await fetch(media.hlsURL).then(r => r.text()).catch(() => {});

View file

@ -1,4 +1,4 @@
import { genericUserAgent, maxVideoDuration } from "../../config.js";
import { genericUserAgent, env } from "../../config.js";
import { cleanString } from "../../sub/utils.js";
const resolutions = {
@ -29,7 +29,7 @@ export default async function(o) {
if (videoData.provider !== "UPLOADED_ODKL") return { error: 'ErrorUnsupported' };
if (videoData.movie.is_live) return { error: 'ErrorLiveVideo' };
if (videoData.movie.duration > maxVideoDuration / 1000) return { error: ['ErrorLengthLimit', maxVideoDuration / 60000] };
if (videoData.movie.duration > env.durationLimit) return { error: ['ErrorLengthLimit', env.durationLimit / 60] };
let videos = videoData.videos.filter(v => !v.disallowed);
let bestVideo = videos.find(v => resolutions[v.name] === quality) || videos[videos.length - 1];

View file

@ -1,4 +1,4 @@
import { genericUserAgent, maxVideoDuration } from "../../config.js";
import { genericUserAgent, env } from "../../config.js";
import { getCookie, updateCookieValues } from "../cookie/manager.js";
async function getAccessToken() {
@ -79,8 +79,8 @@ export default async function(obj) {
if (!data.secure_media?.reddit_video)
return { error: 'ErrorEmptyDownload' };
if (data.secure_media?.reddit_video?.duration * 1000 > maxVideoDuration)
return { error: ['ErrorLengthLimit', maxVideoDuration / 60000] };
if (data.secure_media?.reddit_video?.duration > env.durationLimit)
return { error: ['ErrorLengthLimit', env.durationLimit / 60] };
let audio = false,
video = data.secure_media?.reddit_video?.fallback_url?.split('?')[0],

View file

@ -1,6 +1,6 @@
import HLS from 'hls-parser';
import { maxVideoDuration } from "../../config.js";
import { env } from "../../config.js";
import { cleanString } from '../../sub/utils.js';
async function requestJSON(url) {
@ -35,8 +35,8 @@ export default async function(obj) {
if (play.detail || !play.video_balancer) return { error: 'ErrorEmptyDownload' };
if (play.live_streams?.hls) return { error: 'ErrorLiveVideo' };
if (play.duration > maxVideoDuration)
return { error: ['ErrorLengthLimit', maxVideoDuration / 60000] };
if (play.duration > env.durationLimit * 1000)
return { error: ['ErrorLengthLimit', env.durationLimit / 60] };
let m3u8 = await fetch(play.video_balancer.m3u8)
.then(r => r.text())

View file

@ -1,4 +1,4 @@
import { maxVideoDuration } from "../../config.js";
import { env } from "../../config.js";
import { cleanString } from "../../sub/utils.js";
const cachedID = {
@ -77,8 +77,8 @@ export default async function(obj) {
if (fileUrl.substring(0, 54) !== "https://api-v2.soundcloud.com/media/soundcloud:tracks:") return { error: 'ErrorEmptyDownload' };
if (json.duration > maxVideoDuration)
return { error: ['ErrorLengthAudioConvert', maxVideoDuration / 60000] };
if (json.duration > env.durationLimit * 1000)
return { error: ['ErrorLengthAudioConvert', env.durationLimit / 60] };
let file = await fetch(fileUrl).then(async (r) => { return (await r.json()).url }).catch(() => {});
if (!file) return { error: 'ErrorCouldntFetch' };

View file

@ -1,4 +1,4 @@
import { maxVideoDuration } from "../../config.js";
import { env } from "../../config.js";
import { cleanString } from '../../sub/utils.js';
const gqlURL = "https://gql.twitch.tv/gql";
@ -34,7 +34,7 @@ export default async function (obj) {
let clipMetadata = req_metadata.data.clip;
if (clipMetadata.durationSeconds > maxVideoDuration / 1000) return { error: ['ErrorLengthLimit', maxVideoDuration / 60000] };
if (clipMetadata.durationSeconds > env.durationLimit) return { error: ['ErrorLengthLimit', env.durationLimit / 60] };
if (!clipMetadata.videoQualities || !clipMetadata.broadcaster) return { error: 'ErrorEmptyDownload' };
let req_token = await fetch(gqlURL, {

View file

@ -1,4 +1,4 @@
import { maxVideoDuration } from "../../config.js";
import { env } from "../../config.js";
import { cleanString } from '../../sub/utils.js';
const resolutionMatch = {
@ -63,7 +63,7 @@ export default async function(obj) {
}
}
if (api.video.duration > maxVideoDuration / 1000) return { error: ['ErrorLengthLimit', maxVideoDuration / 60000] };
if (api.video.duration > env.durationLimit) return { error: ['ErrorLengthLimit', env.durationLimit / 60] };
let masterJSONURL = api["request"]["files"]["dash"]["cdns"]["akfire_interconnect_quic"]["url"];
let masterJSON = await fetch(masterJSONURL).then((r) => { return r.json() }).catch(() => { return false });

View file

@ -1,4 +1,4 @@
import { genericUserAgent, maxVideoDuration } from "../../config.js";
import { genericUserAgent, env } from "../../config.js";
import { cleanString } from "../../sub/utils.js";
const resolutions = ["2160", "1440", "1080", "720", "480", "360", "240"];
@ -21,7 +21,7 @@ export default async function(o) {
let js = JSON.parse('{"lang":' + html.split(`{"lang":`)[1].split(']);')[0]);
if (Number(js.mvData.is_active_live) !== 0) return { error: 'ErrorLiveVideo' };
if (js.mvData.duration > maxVideoDuration / 1000) return { error: ['ErrorLengthLimit', maxVideoDuration / 60000] };
if (js.mvData.duration > env.durationLimit) return { error: ['ErrorLengthLimit', env.durationLimit / 60] };
for (let i in resolutions) {
if (js.player.params[0][`url${resolutions[i]}`]) {

View file

@ -1,5 +1,5 @@
import { Innertube, Session } from 'youtubei.js';
import { maxVideoDuration } from '../../config.js';
import { env } from '../../config.js';
import { cleanString } from '../../sub/utils.js';
import { fetch } from 'undici'
@ -92,7 +92,7 @@ export default async function(o) {
if (bestQuality) bestQuality = qual(bestQuality);
if (!bestQuality && !o.isAudioOnly || !hasAudio) return { error: 'ErrorYTTryOtherCodec' };
if (info.basic_info.duration > maxVideoDuration / 1000) return { error: ['ErrorLengthLimit', maxVideoDuration / 60000] };
if (info.basic_info.duration > env.durationLimit) return { error: ['ErrorLengthLimit', env.durationLimit / 60] };
let checkBestAudio = (i) => (i.has_audio && !i.has_video),
audio = adaptive_formats.find(i => checkBestAudio(i) && !i.is_dubbed);