rutube: add support for private video links

This commit is contained in:
wukko 2024-05-29 13:02:05 +06:00
parent 490bbf82ec
commit 2a2183aa84
No known key found for this signature in database
GPG key ID: 3E30B3F26C7B4AA2
6 changed files with 24 additions and 8 deletions

View file

@ -179,6 +179,7 @@ export default async function(host, patternMatch, lang, obj) {
r = await rutube({ r = await rutube({
id: patternMatch.id, id: patternMatch.id,
yappyId: patternMatch.yappyId, yappyId: patternMatch.yappyId,
key: patternMatch.key,
quality: obj.vQuality, quality: obj.vQuality,
isAudioOnly: isAudioOnly isAudioOnly: isAudioOnly
}); });

View file

@ -12,10 +12,10 @@ async function requestJSON(url) {
export default async function(obj) { export default async function(obj) {
if (obj.yappyId) { if (obj.yappyId) {
let yappy = await requestJSON( const yappy = await requestJSON(
`https://rutube.ru/pangolin/api/web/yappy/yappypage/?client=wdp&videoId=${obj.yappyId}&page=1&page_size=15` `https://rutube.ru/pangolin/api/web/yappy/yappypage/?client=wdp&videoId=${obj.yappyId}&page=1&page_size=15`
) )
let yappyURL = yappy?.results?.find(r => r.id === obj.yappyId)?.link; const yappyURL = yappy?.results?.find(r => r.id === obj.yappyId)?.link;
if (!yappyURL) return { error: 'ErrorEmptyDownload' }; if (!yappyURL) return { error: 'ErrorEmptyDownload' };
return { return {
@ -25,11 +25,12 @@ export default async function(obj) {
} }
} }
let quality = obj.quality === "max" ? "9000" : obj.quality; const quality = obj.quality === "max" ? "9000" : obj.quality;
let play = await requestJSON( const requestURL = new URL(`https://rutube.ru/api/play/options/${obj.id}/?no_404=true&referer&pver=v2`);
`https://rutube.ru/api/play/options/${obj.id}/?no_404=true&referer&pver=v2` if (obj.key) requestURL.searchParams.set('p', obj.key);
)
const play = await requestJSON(requestURL);
if (!play) return { error: 'ErrorCouldntFetch' }; if (!play) return { error: 'ErrorCouldntFetch' };
if (play.detail || !play.video_balancer) return { error: 'ErrorEmptyDownload' }; if (play.detail || !play.video_balancer) return { error: 'ErrorEmptyDownload' };
@ -51,7 +52,7 @@ export default async function(obj) {
bestQuality = m3u8.find((i) => (Number(quality) === i.resolution.height)); bestQuality = m3u8.find((i) => (Number(quality) === i.resolution.height));
} }
let fileMetadata = { const fileMetadata = {
title: cleanString(play.title.trim()), title: cleanString(play.title.trim()),
artist: cleanString(play.author.name.trim()), artist: cleanString(play.author.name.trim()),
} }

View file

@ -105,7 +105,7 @@
"rutube": { "rutube": {
"alias": "rutube videos", "alias": "rutube videos",
"tld": "ru", "tld": "ru",
"patterns": ["video/:id", "play/embed/:id", "shorts/:id", "yappy/:yappyId"], "patterns": ["video/:id", "play/embed/:id", "shorts/:id", "yappy/:yappyId", "video/private/:id?p=:key", "video/private/:id"],
"enabled": true "enabled": true
}, },
"dailymotion": { "dailymotion": {

View file

@ -20,6 +20,7 @@ export const testers = {
|| (patternMatch.user?.length <= 22 && patternMatch.id?.length <= 10), || (patternMatch.user?.length <= 22 && patternMatch.id?.length <= 10),
"rutube": (patternMatch) => "rutube": (patternMatch) =>
(patternMatch.id?.length === 32 && patternMatch.key?.length <= 32) ||
patternMatch.id?.length === 32 || patternMatch.yappyId?.length === 32, patternMatch.id?.length === 32 || patternMatch.yappyId?.length === 32,
"soundcloud": (patternMatch) => "soundcloud": (patternMatch) =>

View file

@ -100,6 +100,11 @@ function cleanURL(url) {
limitQuery('v') limitQuery('v')
} }
break; break;
case "rutube":
if (url.searchParams.get('p')) {
limitQuery('p')
}
break;
} }
if (stripQuery) { if (stripQuery) {

View file

@ -1089,6 +1089,14 @@
"code": 200, "code": 200,
"status": "stream" "status": "stream"
} }
}, {
"name": "private video",
"url": "https://rutube.ru/video/private/1161415be0e686214bb2a498165cab3e/?p=_IL1G8RSnKutunnTYwhZ5A",
"params": {},
"expected": {
"code": 200,
"status": "stream"
}
}], }],
"ok": [{ "ok": [{
"name": "regular video", "name": "regular video",