mirror of
https://github.com/wukko/cobalt.git
synced 2024-11-18 06:09:58 +00:00
add support for ok videos & clean up
This commit is contained in:
parent
a63a35c74d
commit
5b1e9f1fa6
5 changed files with 94 additions and 22 deletions
|
@ -13,6 +13,7 @@ import reddit from "./services/reddit.js";
|
||||||
import twitter from "./services/twitter.js";
|
import twitter from "./services/twitter.js";
|
||||||
import youtube from "./services/youtube.js";
|
import youtube from "./services/youtube.js";
|
||||||
import vk from "./services/vk.js";
|
import vk from "./services/vk.js";
|
||||||
|
import ok from "./services/ok.js";
|
||||||
import tiktok from "./services/tiktok.js";
|
import tiktok from "./services/tiktok.js";
|
||||||
import tumblr from "./services/tumblr.js";
|
import tumblr from "./services/tumblr.js";
|
||||||
import vimeo from "./services/vimeo.js";
|
import vimeo from "./services/vimeo.js";
|
||||||
|
@ -43,19 +44,25 @@ export default async function(host, patternMatch, url, lang, obj) {
|
||||||
break;
|
break;
|
||||||
case "vk":
|
case "vk":
|
||||||
r = await vk({
|
r = await vk({
|
||||||
userId: patternMatch["userId"],
|
userId: patternMatch.userId,
|
||||||
videoId: patternMatch["videoId"],
|
videoId: patternMatch.videoId,
|
||||||
|
quality: obj.vQuality
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case "ok":
|
||||||
|
r = await ok({
|
||||||
|
id: patternMatch.id,
|
||||||
quality: obj.vQuality
|
quality: obj.vQuality
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "bilibili":
|
case "bilibili":
|
||||||
r = await bilibili({
|
r = await bilibili({
|
||||||
id: patternMatch["id"].slice(0, 12)
|
id: patternMatch.id.slice(0, 12)
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "youtube":
|
case "youtube":
|
||||||
let fetchInfo = {
|
let fetchInfo = {
|
||||||
id: patternMatch["id"].slice(0, 11),
|
id: patternMatch.id.slice(0, 11),
|
||||||
quality: obj.vQuality,
|
quality: obj.vQuality,
|
||||||
format: obj.vCodec,
|
format: obj.vCodec,
|
||||||
isAudioOnly: isAudioOnly,
|
isAudioOnly: isAudioOnly,
|
||||||
|
@ -73,16 +80,16 @@ export default async function(host, patternMatch, url, lang, obj) {
|
||||||
break;
|
break;
|
||||||
case "reddit":
|
case "reddit":
|
||||||
r = await reddit({
|
r = await reddit({
|
||||||
sub: patternMatch["sub"],
|
sub: patternMatch.sub,
|
||||||
id: patternMatch["id"]
|
id: patternMatch.id
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "douyin":
|
case "douyin":
|
||||||
case "tiktok":
|
case "tiktok":
|
||||||
r = await tiktok({
|
r = await tiktok({
|
||||||
host: host,
|
host: host,
|
||||||
postId: patternMatch["postId"],
|
postId: patternMatch.postId,
|
||||||
id: patternMatch["id"],
|
id: patternMatch.id,
|
||||||
noWatermark: obj.isNoTTWatermark,
|
noWatermark: obj.isNoTTWatermark,
|
||||||
fullAudio: obj.isTTFullAudio,
|
fullAudio: obj.isTTFullAudio,
|
||||||
isAudioOnly: isAudioOnly
|
isAudioOnly: isAudioOnly
|
||||||
|
@ -97,7 +104,7 @@ export default async function(host, patternMatch, url, lang, obj) {
|
||||||
break;
|
break;
|
||||||
case "vimeo":
|
case "vimeo":
|
||||||
r = await vimeo({
|
r = await vimeo({
|
||||||
id: patternMatch["id"].slice(0, 11),
|
id: patternMatch.id.slice(0, 11),
|
||||||
quality: obj.vQuality,
|
quality: obj.vQuality,
|
||||||
isAudioOnly: isAudioOnly,
|
isAudioOnly: isAudioOnly,
|
||||||
forceDash: isAudioOnly ? true : obj.vimeoDash
|
forceDash: isAudioOnly ? true : obj.vimeoDash
|
||||||
|
@ -107,10 +114,10 @@ export default async function(host, patternMatch, url, lang, obj) {
|
||||||
isAudioOnly = true;
|
isAudioOnly = true;
|
||||||
r = await soundcloud({
|
r = await soundcloud({
|
||||||
url,
|
url,
|
||||||
author: patternMatch["author"],
|
author: patternMatch.author,
|
||||||
song: patternMatch["song"],
|
song: patternMatch.song,
|
||||||
shortLink: patternMatch["shortLink"] || false,
|
shortLink: patternMatch.shortLink || false,
|
||||||
accessKey: patternMatch["accessKey"] || false
|
accessKey: patternMatch.accessKey || false
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "instagram":
|
case "instagram":
|
||||||
|
@ -121,31 +128,31 @@ export default async function(host, patternMatch, url, lang, obj) {
|
||||||
break;
|
break;
|
||||||
case "vine":
|
case "vine":
|
||||||
r = await vine({
|
r = await vine({
|
||||||
id: patternMatch["id"]
|
id: patternMatch.id
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "pinterest":
|
case "pinterest":
|
||||||
r = await pinterest({
|
r = await pinterest({
|
||||||
id: patternMatch["id"]
|
id: patternMatch.id
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "streamable":
|
case "streamable":
|
||||||
r = await streamable({
|
r = await streamable({
|
||||||
id: patternMatch["id"],
|
id: patternMatch.id,
|
||||||
quality: obj.vQuality,
|
quality: obj.vQuality,
|
||||||
isAudioOnly: isAudioOnly,
|
isAudioOnly: isAudioOnly,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "twitch":
|
case "twitch":
|
||||||
r = await twitch({
|
r = await twitch({
|
||||||
clipId: patternMatch["clip"] || false,
|
clipId: patternMatch.clip || false,
|
||||||
quality: obj.vQuality,
|
quality: obj.vQuality,
|
||||||
isAudioOnly: obj.isAudioOnly
|
isAudioOnly: obj.isAudioOnly
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case "rutube":
|
case "rutube":
|
||||||
r = await rutube({
|
r = await rutube({
|
||||||
id: patternMatch["id"],
|
id: patternMatch.id,
|
||||||
quality: obj.vQuality,
|
quality: obj.vQuality,
|
||||||
isAudioOnly: isAudioOnly
|
isAudioOnly: isAudioOnly
|
||||||
});
|
});
|
||||||
|
|
56
src/modules/processing/services/ok.js
Normal file
56
src/modules/processing/services/ok.js
Normal 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(""", '"');
|
||||||
|
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' }
|
||||||
|
}
|
|
@ -12,7 +12,7 @@ export default async function(o) {
|
||||||
|
|
||||||
if (!html) return { error: 'ErrorCouldntFetch' };
|
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');
|
let decoder = new TextDecoder('windows-1251');
|
||||||
html = decoder.decode(html);
|
html = decoder.decode(html);
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ export default async function(o) {
|
||||||
|
|
||||||
let fileMetadata = {
|
let fileMetadata = {
|
||||||
title: cleanString(js.player.params[0].md_title.trim()),
|
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 {
|
if (url) return {
|
||||||
|
@ -44,7 +44,7 @@ export default async function(o) {
|
||||||
service: "vk",
|
service: "vk",
|
||||||
id: `${o.userId}_${o.videoId}`,
|
id: `${o.userId}_${o.videoId}`,
|
||||||
title: fileMetadata.title,
|
title: fileMetadata.title,
|
||||||
author: fileMetadata.artist,
|
author: fileMetadata.author,
|
||||||
resolution: `${quality}p`,
|
resolution: `${quality}p`,
|
||||||
qualityLabel: `${quality}p`,
|
qualityLabel: `${quality}p`,
|
||||||
extension: "mp4"
|
extension: "mp4"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"audioIgnore": ["vk"],
|
"audioIgnore": ["vk", "ok"],
|
||||||
"config": {
|
"config": {
|
||||||
"bilibili": {
|
"bilibili": {
|
||||||
"alias": "bilibili.com videos",
|
"alias": "bilibili.com videos",
|
||||||
|
@ -28,6 +28,12 @@
|
||||||
"patterns": ["video:userId_:videoId", "clip:userId_:videoId", "clips:duplicate?z=clip:userId_:videoId"],
|
"patterns": ["video:userId_:videoId", "clip:userId_:videoId", "clips:duplicate?z=clip:userId_:videoId"],
|
||||||
"enabled": true
|
"enabled": true
|
||||||
},
|
},
|
||||||
|
"ok": {
|
||||||
|
"alias": "ok video",
|
||||||
|
"tld": "ru",
|
||||||
|
"patterns": ["video/:id"],
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
"youtube": {
|
"youtube": {
|
||||||
"alias": "youtube videos, shorts & music",
|
"alias": "youtube videos, shorts & music",
|
||||||
"patterns": ["watch?v=:id", "embed/:id", "watch/:id"],
|
"patterns": ["watch?v=:id", "embed/:id", "watch/:id"],
|
||||||
|
|
|
@ -6,6 +6,9 @@ export const testers = {
|
||||||
patternMatch.postId?.length <= 12
|
patternMatch.postId?.length <= 12
|
||||||
|| (patternMatch.username?.length <= 30 && patternMatch.storyId?.length <= 24),
|
|| (patternMatch.username?.length <= 30 && patternMatch.storyId?.length <= 24),
|
||||||
|
|
||||||
|
"ok": (patternMatch) =>
|
||||||
|
patternMatch.id?.length <= 16,
|
||||||
|
|
||||||
"pinterest": (patternMatch) =>
|
"pinterest": (patternMatch) =>
|
||||||
patternMatch.id?.length <= 128,
|
patternMatch.id?.length <= 128,
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue