tiktok is back!
- added support for tiktok (images won't work, they're only accessible through the app) - hopefully main input bar is now not rounded on ios, i fucking hate apple - if service is not supported, a correlating error will appear, not generic one - removed duplicates from config that are present in package json already - tiny bit of clean up
This commit is contained in:
@@ -21,11 +21,12 @@ export async function getJSON(originalURL, ip, lang, format, quality) {
|
||||
if (host && host.length < 20 && host in patterns && patterns[host]["enabled"]) {
|
||||
for (let i in patterns[host]["patterns"]) {
|
||||
patternMatch = new UrlPattern(patterns[host]["patterns"][i]).match(cleanURL(url, host).split(".com/")[1]);
|
||||
if (patternMatch) break;
|
||||
}
|
||||
if (patternMatch) {
|
||||
return await match(host, patternMatch, url, ip, lang, format, quality);
|
||||
} else throw Error()
|
||||
} else throw Error()
|
||||
} return apiJSON(0, { t: errorUnsupported(lang) } )
|
||||
} return apiJSON(0, { t: errorUnsupported(lang) } )
|
||||
} else {
|
||||
return apiJSON(0, { t: errorUnsupported(lang) } )
|
||||
}
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
import loadJson from "./sub/loadJSON.js";
|
||||
const config = loadJson("./src/config.json");
|
||||
const packageJson = loadJson("./package.json");
|
||||
|
||||
export const
|
||||
services = loadJson("./src/modules/services/_config.json"),
|
||||
appName = config.appName,
|
||||
version = config.version,
|
||||
appName = packageJson.name,
|
||||
version = packageJson.version,
|
||||
streamLifespan = config.streamLifespan,
|
||||
maxVideoDuration = config.maxVideoDuration,
|
||||
genericUserAgent = config.genericUserAgent,
|
||||
repo = config.repo,
|
||||
repo = packageJson["bugs"]["url"].replace('/issues', ''),
|
||||
authorInfo = config.authorInfo,
|
||||
supportedLanguages = config.supportedLanguages,
|
||||
quality = config.quality,
|
||||
|
||||
@@ -6,6 +6,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 tiktok from "./services/tiktok.js";
|
||||
|
||||
export default async function (host, patternMatch, url, ip, lang, format, quality) {
|
||||
try {
|
||||
@@ -19,13 +20,16 @@ export default async function (host, patternMatch, url, ip, lang, format, qualit
|
||||
return (!r.error) ? apiJSON(1, { u: r.split('?')[0] }) : apiJSON(0, { t: r.error })
|
||||
} else throw Error()
|
||||
case "vk":
|
||||
if (patternMatch["userId"] && patternMatch["videoId"] && patternMatch["userId"].length <= 10 && patternMatch["videoId"].length == 9) {
|
||||
if (patternMatch["userId"] && patternMatch["videoId"] &&
|
||||
patternMatch["userId"].length <= 10 && patternMatch["videoId"].length == 9) {
|
||||
let r = await vk({
|
||||
userId: patternMatch["userId"],
|
||||
videoId: patternMatch["videoId"],
|
||||
lang: lang, quality: quality
|
||||
});
|
||||
return (!r.error) ? apiJSON(2, { type: "bridge", lang: lang, u: r.url, filename: r.filename, service: host, ip: ip, salt: process.env.streamSalt }) : apiJSON(0, { t: r.error });
|
||||
return (!r.error) ? apiJSON(2,
|
||||
{ type: "bridge", lang: lang, u: r.url, filename:
|
||||
r.filename, service: host, ip: ip, salt: process.env.streamSalt }) : apiJSON(0, { t: r.error });
|
||||
} else throw Error()
|
||||
case "bilibili":
|
||||
if (patternMatch["id"] && patternMatch["id"].length >= 12) {
|
||||
@@ -69,7 +73,8 @@ export default async function (host, patternMatch, url, ip, lang, format, qualit
|
||||
}) : apiJSON(0, { t: r.error });
|
||||
} else throw Error()
|
||||
case "reddit":
|
||||
if (patternMatch["sub"] && patternMatch["id"] && patternMatch["title"] && patternMatch["sub"].length <= 22 && patternMatch["id"].length <= 10 && patternMatch["title"].length <= 96) {
|
||||
if (patternMatch["sub"] && patternMatch["id"] && patternMatch["title"] &&
|
||||
patternMatch["sub"].length <= 22 && patternMatch["id"].length <= 10 && patternMatch["title"].length <= 96) {
|
||||
let r = await reddit({
|
||||
sub: patternMatch["sub"],
|
||||
id: patternMatch["id"],
|
||||
@@ -81,6 +86,19 @@ export default async function (host, patternMatch, url, ip, lang, format, qualit
|
||||
filename: r.filename, salt: process.env.streamSalt
|
||||
}) : apiJSON(0, { t: r.error });
|
||||
} else throw Error()
|
||||
case "tiktok":
|
||||
if ((patternMatch["user"] && patternMatch["type"] == "video" && patternMatch["postId"] && patternMatch["postId"].length <= 21) ||
|
||||
(patternMatch["id"] && patternMatch["id"].length <= 13)) {
|
||||
let r = await tiktok({
|
||||
postId: patternMatch["postId"],
|
||||
id: patternMatch["id"], lang: lang,
|
||||
});
|
||||
return (!r.error) ? apiJSON(2, {
|
||||
type: "bridge", u: r.urls, lang: lang,
|
||||
service: host, ip: ip,
|
||||
filename: r.filename, salt: process.env.streamSalt
|
||||
}) : apiJSON(0, { t: r.error });
|
||||
} else throw Error()
|
||||
default:
|
||||
return apiJSON(0, { t: errorUnsupported(lang) })
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ export default function(obj) {
|
||||
<div id="theme-switcher" class="switch-container small-padding">
|
||||
<div class="subtitle">${loc(obj.lang, 'DownloadPopupDescription')}</div>
|
||||
<div class="switches">
|
||||
<a id="pd-download" class="switch full space-right" target="_blank"">${loc(obj.lang, 'Download')}</a>
|
||||
<a id="pd-download" class="switch full space-right" target="_blank" href="/">${loc(obj.lang, 'Download')}</a>
|
||||
<div id="pd-copy" class="switch full">${loc(obj.lang, 'CopyURL')}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
"enabled": false
|
||||
},
|
||||
"tiktok": {
|
||||
"patterns": [":pageid/:type/:postid", ":id"],
|
||||
"enabled": false
|
||||
"patterns": [":user/:type/:postId", ":id"],
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
30
src/modules/services/tiktok.js
Normal file
30
src/modules/services/tiktok.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import got from "got";
|
||||
import loc from "../../localization/manager.js";
|
||||
import { genericUserAgent} from "../config.js";
|
||||
import { unicodeDecode } from "../sub/utils.js";
|
||||
|
||||
export default async function(obj) {
|
||||
try {
|
||||
if (!obj.postId) {
|
||||
let html = await got.get(`https://vt.tiktok.com/${obj.id}`, { headers: { "user-agent": genericUserAgent } });
|
||||
html.on('error', (err) => {
|
||||
return { error: loc(obj.lang, 'ErrorCantConnectToServiceAPI', 'tiktok') };
|
||||
});
|
||||
html = html.body
|
||||
obj.postId = html.split('video/')[1].split('?')[0]
|
||||
}
|
||||
let url = `https://tiktok.com/@video/video/${obj.postId}`
|
||||
let html = await got.get(url, { headers: { "user-agent": genericUserAgent } });
|
||||
html.on('error', (err) => {
|
||||
return { error: loc(obj.lang, 'ErrorCantConnectToServiceAPI', 'tiktok') };
|
||||
});
|
||||
html = html.body;
|
||||
if (html.includes(',"preloadList":[{"url":"')) {
|
||||
return { urls: unicodeDecode(html.split(',"preloadList":[{"url":"')[1].split('","id":"')[0].trim()), filename: `tiktok_${obj.postId}.mp4` };
|
||||
} else {
|
||||
return { error: loc(obj.lang, 'ErrorEmptyDownload') };
|
||||
}
|
||||
} catch (e) {
|
||||
return { error: loc(obj.lang, 'ErrorBadFetch') };
|
||||
}
|
||||
}
|
||||
@@ -16,10 +16,10 @@ export async function streamDefault(streamInfo, res) {
|
||||
isStream: true
|
||||
});
|
||||
stream.pipe(res).on('error', (err) => {
|
||||
throw Error("File stream pipe error.");
|
||||
internalError(res);
|
||||
});
|
||||
stream.on('error', (err) => {
|
||||
throw Error("File stream error.")
|
||||
internalError(res);
|
||||
});
|
||||
} catch (e) {
|
||||
internalError(res);
|
||||
|
||||
@@ -35,7 +35,7 @@ export function msToTime(d) {
|
||||
return r;
|
||||
}
|
||||
export function cleanURL(url, host) {
|
||||
url = url.replace('}', '').replace('{', '').replace(')', '').replace('(', '').replace(' ', '');
|
||||
url = url.replace('}', '').replace('{', '').replace(')', '').replace('(', '').replace(' ', '').replace('@', '');
|
||||
if (url.includes('youtube.com/shorts/')) {
|
||||
url = url.split('?')[0].replace('shorts/', 'watch?v=');
|
||||
}
|
||||
@@ -51,4 +51,9 @@ export function cleanURL(url, host) {
|
||||
}
|
||||
export function languageCode(req) {
|
||||
return req.header('Accept-Language') ? req.header('Accept-Language').slice(0, 2) : "en"
|
||||
}
|
||||
export function unicodeDecode(str) {
|
||||
return str.replace(/\\u[\dA-F]{4}/gi, (unicode) => {
|
||||
return String.fromCharCode(parseInt(unicode.replace(/\\u/g, ""), 16));
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user