add support for ok videos & clean up

This commit is contained in:
wukko 2024-01-17 13:02:52 +06:00
parent a63a35c74d
commit 5b1e9f1fa6
5 changed files with 94 additions and 22 deletions

View file

@ -13,6 +13,7 @@ import reddit from "./services/reddit.js";
import twitter from "./services/twitter.js";
import youtube from "./services/youtube.js";
import vk from "./services/vk.js";
import ok from "./services/ok.js";
import tiktok from "./services/tiktok.js";
import tumblr from "./services/tumblr.js";
import vimeo from "./services/vimeo.js";
@ -43,19 +44,25 @@ export default async function(host, patternMatch, url, lang, obj) {
break;
case "vk":
r = await vk({
userId: patternMatch["userId"],
videoId: patternMatch["videoId"],
userId: patternMatch.userId,
videoId: patternMatch.videoId,
quality: obj.vQuality
});
break;
case "ok":
r = await ok({
id: patternMatch.id,
quality: obj.vQuality
});
break;
case "bilibili":
r = await bilibili({
id: patternMatch["id"].slice(0, 12)
id: patternMatch.id.slice(0, 12)
});
break;
case "youtube":
let fetchInfo = {
id: patternMatch["id"].slice(0, 11),
id: patternMatch.id.slice(0, 11),
quality: obj.vQuality,
format: obj.vCodec,
isAudioOnly: isAudioOnly,
@ -73,16 +80,16 @@ export default async function(host, patternMatch, url, lang, obj) {
break;
case "reddit":
r = await reddit({
sub: patternMatch["sub"],
id: patternMatch["id"]
sub: patternMatch.sub,
id: patternMatch.id
});
break;
case "douyin":
case "tiktok":
r = await tiktok({
host: host,
postId: patternMatch["postId"],
id: patternMatch["id"],
postId: patternMatch.postId,
id: patternMatch.id,
noWatermark: obj.isNoTTWatermark,
fullAudio: obj.isTTFullAudio,
isAudioOnly: isAudioOnly
@ -97,7 +104,7 @@ export default async function(host, patternMatch, url, lang, obj) {
break;
case "vimeo":
r = await vimeo({
id: patternMatch["id"].slice(0, 11),
id: patternMatch.id.slice(0, 11),
quality: obj.vQuality,
isAudioOnly: isAudioOnly,
forceDash: isAudioOnly ? true : obj.vimeoDash
@ -107,10 +114,10 @@ export default async function(host, patternMatch, url, lang, obj) {
isAudioOnly = true;
r = await soundcloud({
url,
author: patternMatch["author"],
song: patternMatch["song"],
shortLink: patternMatch["shortLink"] || false,
accessKey: patternMatch["accessKey"] || false
author: patternMatch.author,
song: patternMatch.song,
shortLink: patternMatch.shortLink || false,
accessKey: patternMatch.accessKey || false
});
break;
case "instagram":
@ -121,31 +128,31 @@ export default async function(host, patternMatch, url, lang, obj) {
break;
case "vine":
r = await vine({
id: patternMatch["id"]
id: patternMatch.id
});
break;
case "pinterest":
r = await pinterest({
id: patternMatch["id"]
id: patternMatch.id
});
break;
case "streamable":
r = await streamable({
id: patternMatch["id"],
id: patternMatch.id,
quality: obj.vQuality,
isAudioOnly: isAudioOnly,
});
break;
case "twitch":
r = await twitch({
clipId: patternMatch["clip"] || false,
clipId: patternMatch.clip || false,
quality: obj.vQuality,
isAudioOnly: obj.isAudioOnly
});
break;
case "rutube":
r = await rutube({
id: patternMatch["id"],
id: patternMatch.id,
quality: obj.vQuality,
isAudioOnly: isAudioOnly
});

View file

@ -0,0 +1,56 @@
import { genericUserAgent, maxVideoDuration } from "../../config.js";
import { cleanString } from "../../sub/utils.js";
const resolutions = {
"ultra": "2160",
"quad": "1440",
"full": "1080",
"hd": "720",
"sd": "480",
"low": "360",
"lowest": "240",
"mobile": "144"
}
export default async function(o) {
let quality = o.quality === "max" ? "2160" : o.quality;
let html = await fetch(`https://ok.ru/video/${o.id}`, {
headers: { "user-agent": genericUserAgent }
}).then((r) => { return r.text() }).catch(() => { return false });
if (!html) return { error: 'ErrorCouldntFetch' };
if (!html.includes(`<div data-module="OKVideo" data-options="{`)) {
return { error: 'ErrorEmptyDownload' };
}
let videoData = html.split(`<div data-module="OKVideo" data-options="`)[1].split('" data-')[0].replaceAll("&quot;", '"');
videoData = JSON.parse(JSON.parse(videoData).flashvars.metadata);
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] };
let videos = videoData.videos.filter(v => !v.disallowed);
let bestVideo = videos.find(v => resolutions[v.name] === quality) || videos[videos.length - 1];
let fileMetadata = {
title: cleanString(videoData.movie.title.trim()),
author: cleanString(videoData.author.name.trim()),
}
if (bestVideo) return {
urls: bestVideo.url,
filenameAttributes: {
service: "ok",
id: o.id,
title: fileMetadata.title,
author: fileMetadata.author,
resolution: `${resolutions[bestVideo.name]}p`,
qualityLabel: `${resolutions[bestVideo.name]}p`,
extension: "mp4"
}
}
return { error: 'ErrorEmptyDownload' }
}

View file

@ -12,7 +12,7 @@ export default async function(o) {
if (!html) return { error: 'ErrorCouldntFetch' };
// decode cyrillic from windows-1251 because vk still uses apis from prehistoring times
// decode cyrillic from windows-1251 because vk still uses apis from prehistoric times
let decoder = new TextDecoder('windows-1251');
html = decoder.decode(html);
@ -35,7 +35,7 @@ export default async function(o) {
let fileMetadata = {
title: cleanString(js.player.params[0].md_title.trim()),
artist: cleanString(js.player.params[0].md_author.trim()),
author: cleanString(js.player.params[0].md_author.trim()),
}
if (url) return {
@ -44,7 +44,7 @@ export default async function(o) {
service: "vk",
id: `${o.userId}_${o.videoId}`,
title: fileMetadata.title,
author: fileMetadata.artist,
author: fileMetadata.author,
resolution: `${quality}p`,
qualityLabel: `${quality}p`,
extension: "mp4"

View file

@ -1,5 +1,5 @@
{
"audioIgnore": ["vk"],
"audioIgnore": ["vk", "ok"],
"config": {
"bilibili": {
"alias": "bilibili.com videos",
@ -28,6 +28,12 @@
"patterns": ["video:userId_:videoId", "clip:userId_:videoId", "clips:duplicate?z=clip:userId_:videoId"],
"enabled": true
},
"ok": {
"alias": "ok video",
"tld": "ru",
"patterns": ["video/:id"],
"enabled": true
},
"youtube": {
"alias": "youtube videos, shorts & music",
"patterns": ["watch?v=:id", "embed/:id", "watch/:id"],

View file

@ -5,6 +5,9 @@ export const testers = {
"instagram": (patternMatch) =>
patternMatch.postId?.length <= 12
|| (patternMatch.username?.length <= 30 && patternMatch.storyId?.length <= 24),
"ok": (patternMatch) =>
patternMatch.id?.length <= 16,
"pinterest": (patternMatch) =>
patternMatch.id?.length <= 128,