diff --git a/src/modules/processing/match.js b/src/modules/processing/match.js index 3e38c4db..b1378565 100644 --- a/src/modules/processing/match.js +++ b/src/modules/processing/match.js @@ -25,6 +25,7 @@ import twitch from "./services/twitch.js"; import rutube from "./services/rutube.js"; import dailymotion from "./services/dailymotion.js"; import loom from "./services/loom.js"; +import coub from "./services/coub.js"; let freebind; @@ -193,6 +194,11 @@ export default async function(host, patternMatch, lang, obj) { id: patternMatch.id }); break; + case "coub": + r = await coub({ + id: patternMatch.id + }); + break; default: return createResponse("error", { t: loc(lang, 'ErrorUnsupported') diff --git a/src/modules/processing/matchActionDecider.js b/src/modules/processing/matchActionDecider.js index 74f0f8c7..8a169f2f 100644 --- a/src/modules/processing/matchActionDecider.js +++ b/src/modules/processing/matchActionDecider.js @@ -109,6 +109,7 @@ export default function(r, host, userFormat, isAudioOnly, lang, isAudioMuted, di responseType = r.typeId; params = { type: r.type }; break; + case "coub": case "vimeo": if (Array.isArray(r.urls)) { params = { type: "render" } diff --git a/src/modules/processing/services/cobu.js b/src/modules/processing/services/cobu.js new file mode 100644 index 00000000..f5827998 --- /dev/null +++ b/src/modules/processing/services/cobu.js @@ -0,0 +1,31 @@ +async function a(id) { + const req = await fetch(`https://coub.com/view/${id}/`, { + method: "GET", + headers: { + "user-agent": "firefox", + } + }) + .then(request => request.text()) + .catch(() => {return {error:'ClickToCopy'}}); + + if (!req) return { error: 'ErrorEmptyDownload' }; + const infoScript = req?.split('{"flag":')[1] + const downloadLinks = infoScript?.split('"html5":')[1].split(',"mobile"')[0]; + const videoUrl = downloadLinks?.split('"https://')[1].split('"')[0]; + const audioUrl = downloadLinks?.split('"https://')[3].split('"')[0]; + + if (videoUrl?.includes('.mp4') && audioUrl?.includes('.mp3')) { + return { + urls: [ + 'https://' + videoUrl, + 'https://' + audioUrl + ], + filename: `coub_${id}.mp4`, + audioFilename: `coub_${id}_audio` + } + } + + return { error: 'ErrorEmptyDownload' } +} + +a("dhxy").then(console.log) \ No newline at end of file diff --git a/src/modules/processing/services/coub.js b/src/modules/processing/services/coub.js new file mode 100644 index 00000000..de4d5e69 --- /dev/null +++ b/src/modules/processing/services/coub.js @@ -0,0 +1,39 @@ +import { genericUserAgent } from "../../config.js"; + +export default async function({ id }) { + const req = await fetch(`https://coub.com/view/${id}/`, { + method: "GET", + headers: { + "user-agent": genericUserAgent, + } + }) + .then(request => request.text()) + .catch(() => {}); + + if (!req) return { error: 'ErrorEmptyDownload' }; + const infoScript = req?.split("')[0].replace('\n',''); + const infoJSON = JSON.parse(infoScript); + const downloadLinks = infoJSON?.file_versions.html5; + const videoUrl = downloadLinks?.video.high.url; + const audioUrl = downloadLinks?.audio.high.url; + + if (videoUrl?.includes('.mp4') && audioUrl?.includes('.mp3')) { + return { + urls: [ + videoUrl, + audioUrl + ], + filename: `coub_${id}.mp4`, + audioFilename: `coub_${id}_audio`, + filenameAttributes: { + service: 'coub', + id: id, + title: infoJSON?.title, + author: infoJSON?.channel.title, + extension: 'mp4' + }, + } + } + + return { error: 'ErrorEmptyDownload' } +} diff --git a/src/modules/processing/servicesConfig.json b/src/modules/processing/servicesConfig.json index d727b9a5..d04a2317 100644 --- a/src/modules/processing/servicesConfig.json +++ b/src/modules/processing/servicesConfig.json @@ -118,6 +118,11 @@ "alias": "loom videos", "patterns": ["share/:id"], "enabled": true + }, + "coub": { + "alias": "coub videos", + "patterns": ["view/:id", "embed/:id"], + "enabled": true } } } diff --git a/src/modules/processing/servicesPatternTesters.js b/src/modules/processing/servicesPatternTesters.js index ddeea31f..8b0e4cd3 100644 --- a/src/modules/processing/servicesPatternTesters.js +++ b/src/modules/processing/servicesPatternTesters.js @@ -1,4 +1,7 @@ export const testers = { + "coub": (patternMatch) => + patternMatch.id?.length <= 6, + "bilibili": (patternMatch) => patternMatch.comId?.length <= 12 || patternMatch.comShortLink?.length <= 16 || patternMatch.tvId?.length <= 24,