2024-05-16 16:57:48 +02:00
|
|
|
import { env } from "../../config.js";
|
2023-10-12 19:14:54 +02:00
|
|
|
import { cleanString } from '../../sub/utils.js';
|
2023-02-26 17:49:25 +01:00
|
|
|
|
|
|
|
const resolutionMatch = {
|
|
|
|
"3840": "2160",
|
2023-03-15 17:18:31 +01:00
|
|
|
"2732": "1440",
|
2024-01-17 10:54:52 +01:00
|
|
|
"2560": "1440",
|
2023-03-15 17:18:31 +01:00
|
|
|
"2048": "1080",
|
2023-02-26 17:49:25 +01:00
|
|
|
"1920": "1080",
|
2023-03-15 17:18:31 +01:00
|
|
|
"1366": "720",
|
2023-02-26 17:49:25 +01:00
|
|
|
"1280": "720",
|
2023-03-15 17:18:31 +01:00
|
|
|
"960": "480",
|
|
|
|
"640": "360",
|
|
|
|
"426": "240"
|
|
|
|
}
|
|
|
|
|
|
|
|
const qualityMatch = {
|
|
|
|
"2160": "4K",
|
|
|
|
"1440": "2K",
|
|
|
|
"480": "540",
|
|
|
|
|
|
|
|
"4K": "2160",
|
|
|
|
"2K": "1440",
|
|
|
|
"540": "480"
|
2023-02-26 17:49:25 +01:00
|
|
|
}
|
2023-02-12 08:40:49 +01:00
|
|
|
|
|
|
|
export default async function(obj) {
|
2023-03-15 17:18:31 +01:00
|
|
|
let quality = obj.quality === "max" ? "9000" : obj.quality;
|
|
|
|
if (!quality || obj.isAudioOnly) quality = "9000";
|
|
|
|
|
2024-03-05 00:26:14 +01:00
|
|
|
const url = new URL(`https://player.vimeo.com/video/${obj.id}/config`);
|
|
|
|
if (obj.password) {
|
|
|
|
url.searchParams.set('h', obj.password);
|
|
|
|
}
|
|
|
|
|
|
|
|
let api = await fetch(url)
|
|
|
|
.then(r => r.json())
|
|
|
|
.catch(() => {});
|
2023-02-12 08:40:49 +01:00
|
|
|
if (!api) return { error: 'ErrorCouldntFetch' };
|
|
|
|
|
|
|
|
let downloadType = "dash";
|
2024-04-29 20:04:19 +02:00
|
|
|
if (!obj.isAudioOnly && JSON.stringify(api).includes('"progressive":[{')) downloadType = "progressive";
|
2023-02-12 08:40:49 +01:00
|
|
|
|
2023-10-12 19:14:54 +02:00
|
|
|
let fileMetadata = {
|
2023-10-15 10:39:17 +02:00
|
|
|
title: cleanString(api.video.title.trim()),
|
|
|
|
artist: cleanString(api.video.owner.name.trim()),
|
2023-10-12 19:14:54 +02:00
|
|
|
}
|
|
|
|
|
2023-03-15 17:18:31 +01:00
|
|
|
if (downloadType !== "dash") {
|
|
|
|
if (qualityMatch[quality]) quality = qualityMatch[quality];
|
|
|
|
let all = api["request"]["files"]["progressive"].sort((a, b) => Number(b.width) - Number(a.width));
|
|
|
|
let best = all[0];
|
2023-02-12 08:40:49 +01:00
|
|
|
|
2023-03-15 17:18:31 +01:00
|
|
|
let bestQuality = all[0]["quality"].split('p')[0];
|
|
|
|
bestQuality = qualityMatch[bestQuality] ? qualityMatch[bestQuality] : bestQuality;
|
|
|
|
if (Number(quality) < Number(bestQuality)) best = all.find(i => i["quality"].split('p')[0] === quality);
|
2023-02-12 08:40:49 +01:00
|
|
|
|
2023-03-15 17:18:31 +01:00
|
|
|
if (!best) return { error: 'ErrorEmptyDownload' };
|
2023-10-12 19:14:54 +02:00
|
|
|
return {
|
|
|
|
urls: best["url"],
|
|
|
|
audioFilename: `vimeo_${obj.id}_audio`,
|
|
|
|
filename: `vimeo_${obj.id}_${best["width"]}x${best["height"]}.mp4`
|
|
|
|
}
|
2023-03-15 17:18:31 +01:00
|
|
|
}
|
2023-02-12 08:40:49 +01:00
|
|
|
|
2024-05-16 16:57:48 +02:00
|
|
|
if (api.video.duration > env.durationLimit) return { error: ['ErrorLengthLimit', env.durationLimit / 60] };
|
2023-02-12 08:40:49 +01:00
|
|
|
|
2023-03-15 17:18:31 +01:00
|
|
|
let masterJSONURL = api["request"]["files"]["dash"]["cdns"]["akfire_interconnect_quic"]["url"];
|
|
|
|
let masterJSON = await fetch(masterJSONURL).then((r) => { return r.json() }).catch(() => { return false });
|
2023-02-12 08:40:49 +01:00
|
|
|
|
2023-03-15 17:18:31 +01:00
|
|
|
if (!masterJSON) return { error: 'ErrorCouldntFetch' };
|
|
|
|
if (!masterJSON.video) return { error: 'ErrorEmptyDownload' };
|
2023-02-12 08:40:49 +01:00
|
|
|
|
2024-01-17 10:54:52 +01:00
|
|
|
let masterJSON_Video = masterJSON.video.sort((a, b) => Number(b.width) - Number(a.width)).filter(a => ["dash", "mp42"].includes(a['format'])),
|
2023-03-15 17:18:31 +01:00
|
|
|
bestVideo = masterJSON_Video[0];
|
2023-12-02 16:52:38 +01:00
|
|
|
if (Number(quality) < Number(resolutionMatch[bestVideo["width"]])) {
|
|
|
|
bestVideo = masterJSON_Video.find(i => resolutionMatch[i["width"]] === quality)
|
2023-03-15 17:18:31 +01:00
|
|
|
}
|
2023-12-02 16:52:38 +01:00
|
|
|
|
|
|
|
let masterM3U8 = `${masterJSONURL.split("/sep/")[0]}/sep/video/${bestVideo.id}/master.m3u8`;
|
2024-03-05 00:25:46 +01:00
|
|
|
const fallbackResolution = bestVideo.height > bestVideo.width ? bestVideo.width : bestVideo.height;
|
2023-12-02 16:52:38 +01:00
|
|
|
|
|
|
|
return {
|
|
|
|
urls: masterM3U8,
|
|
|
|
isM3U8: true,
|
|
|
|
fileMetadata: fileMetadata,
|
|
|
|
filenameAttributes: {
|
|
|
|
service: "vimeo",
|
|
|
|
id: obj.id,
|
|
|
|
title: fileMetadata.title,
|
|
|
|
author: fileMetadata.artist,
|
2024-03-05 00:25:46 +01:00
|
|
|
resolution: `${bestVideo.width}x${bestVideo.height}`,
|
|
|
|
qualityLabel: `${resolutionMatch[bestVideo.width] || fallbackResolution}p`,
|
2023-12-02 16:52:38 +01:00
|
|
|
extension: "mp4"
|
2023-03-15 17:18:31 +01:00
|
|
|
}
|
2023-02-12 08:40:49 +01:00
|
|
|
}
|
|
|
|
}
|