2023-02-12 13:40:49 +06:00
|
|
|
import { genericUserAgent } from "../../config.js";
|
|
|
|
|
2023-02-13 21:56:52 +06:00
|
|
|
const userAgent = genericUserAgent.split(' Chrome/1')[0],
|
2023-02-12 13:40:49 +06:00
|
|
|
config = {
|
|
|
|
tiktok: {
|
|
|
|
short: "https://vt.tiktok.com/",
|
2024-03-15 16:00:02 +06:00
|
|
|
api: "https://api22-normal-c-useast2a.tiktokv.com/aweme/v1/feed/?aweme_id={postId}&version_code=262&app_name=musical_ly&channel=App&device_id=null&os_version=14.4.2&device_platform=iphone&device_type=iPhone9®ion=US&carrier_region=US",
|
|
|
|
userAgent: "TikTok 26.2.0 rv:262018 (iPhone; iOS 14.4.2; en_US) Cronet"
|
2023-02-12 13:40:49 +06:00
|
|
|
},
|
|
|
|
douyin: {
|
|
|
|
short: "https://v.douyin.com/",
|
2024-03-15 16:00:02 +06:00
|
|
|
api: "https://www.iesdouyin.com/aweme/v1/web/aweme/detail/?aweme_id={postId}",
|
|
|
|
userAgent: "TikTok 26.2.0 rv:262018 (iPhone; iOS 14.4.2; en_US) Cronet"
|
2023-02-12 13:40:49 +06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function selector(j, h, id) {
|
|
|
|
if (!j) return false;
|
|
|
|
let t;
|
|
|
|
switch (h) {
|
|
|
|
case "tiktok":
|
2024-03-15 16:00:02 +06:00
|
|
|
t = j.aweme_list.filter(v => v.aweme_id === id)[0];
|
2023-02-12 13:40:49 +06:00
|
|
|
break;
|
|
|
|
case "douyin":
|
2024-03-15 16:00:02 +06:00
|
|
|
t = j.aweme_detail;
|
2023-02-12 13:40:49 +06:00
|
|
|
break;
|
|
|
|
}
|
2023-12-29 08:16:40 +06:00
|
|
|
if (t?.length < 3) return false;
|
2023-02-13 19:44:58 +06:00
|
|
|
return t;
|
2023-02-12 13:40:49 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
export default async function(obj) {
|
2023-02-13 20:30:57 +06:00
|
|
|
let postId = obj.postId ? obj.postId : false;
|
|
|
|
|
|
|
|
if (!postId) {
|
2024-03-15 16:00:02 +06:00
|
|
|
let html = await fetch(`${config[obj.host].short}${obj.id}`, {
|
2023-02-12 13:40:49 +06:00
|
|
|
redirect: "manual",
|
|
|
|
headers: { "user-agent": userAgent }
|
|
|
|
}).then((r) => { return r.text() }).catch(() => { return false });
|
2024-01-28 13:23:00 +06:00
|
|
|
|
2023-02-12 13:40:49 +06:00
|
|
|
if (!html) return { error: 'ErrorCouldntFetch' };
|
2023-02-13 19:44:58 +06:00
|
|
|
|
2024-01-28 13:23:00 +06:00
|
|
|
if (html.slice(0, 17) === '<a href="https://') {
|
|
|
|
postId = html.split('<a href="https://')[1].split('?')[0].split('/')[3]
|
2023-02-12 13:40:49 +06:00
|
|
|
} else if (html.slice(0, 32) === '<a href="https://m.tiktok.com/v/' && html.includes('/v/')) {
|
2023-02-13 20:30:57 +06:00
|
|
|
postId = html.split('/v/')[1].split('.html')[0].replace("/", '')
|
2023-02-12 13:40:49 +06:00
|
|
|
}
|
|
|
|
}
|
2023-02-13 20:30:57 +06:00
|
|
|
if (!postId) return { error: 'ErrorCantGetID' };
|
2023-02-12 13:40:49 +06:00
|
|
|
|
|
|
|
let detail;
|
2024-03-15 16:00:02 +06:00
|
|
|
detail = await fetch(config[obj.host].api.replace("{postId}", postId), {
|
|
|
|
headers: {
|
|
|
|
"user-agent": config[obj.host].userAgent
|
|
|
|
}
|
2023-02-12 13:40:49 +06:00
|
|
|
}).then((r) => { return r.json() }).catch(() => { return false });
|
|
|
|
|
2023-02-13 20:30:57 +06:00
|
|
|
detail = selector(detail, obj.host, postId);
|
2023-02-12 13:40:49 +06:00
|
|
|
if (!detail) return { error: 'ErrorCouldntFetch' };
|
|
|
|
|
2024-03-16 22:26:04 +06:00
|
|
|
let video, videoFilename, audioFilename, isMp3, audio, images,
|
|
|
|
filenameBase = `${obj.host}_${detail.author.unique_id}_${postId}`;
|
|
|
|
|
2023-02-12 13:40:49 +06:00
|
|
|
if (obj.host === "tiktok") {
|
2024-03-15 16:00:02 +06:00
|
|
|
images = detail.image_post_info ? detail.image_post_info.images : false
|
2023-02-12 13:40:49 +06:00
|
|
|
} else {
|
2024-03-15 16:00:02 +06:00
|
|
|
images = detail.images ? detail.images : false
|
2023-02-12 13:40:49 +06:00
|
|
|
}
|
|
|
|
|
|
|
|
if (!obj.isAudioOnly && !images) {
|
2024-03-16 18:42:28 +01:00
|
|
|
video = detail.video.play_addr.url_list[0];
|
2024-03-16 22:26:04 +06:00
|
|
|
videoFilename = `${filenameBase}.mp4`;
|
2023-02-12 13:40:49 +06:00
|
|
|
} else {
|
2024-03-16 22:26:04 +06:00
|
|
|
let fallback = detail.video.play_addr.url_list[0];
|
2023-02-12 13:40:49 +06:00
|
|
|
audio = fallback;
|
|
|
|
audioFilename = `${filenameBase}_audio_fv`; // fv - from video
|
|
|
|
if (obj.fullAudio || fallback.includes("music")) {
|
2024-03-15 16:00:02 +06:00
|
|
|
audio = detail.music.play_url.url_list[0]
|
2023-02-12 13:40:49 +06:00
|
|
|
audioFilename = `${filenameBase}_audio`
|
|
|
|
}
|
|
|
|
if (audio.slice(-4) === ".mp3") isMp3 = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (video) return {
|
|
|
|
urls: video,
|
|
|
|
filename: videoFilename
|
|
|
|
}
|
2023-02-13 19:44:58 +06:00
|
|
|
if (images && obj.isAudioOnly) return {
|
|
|
|
urls: audio,
|
|
|
|
audioFilename: audioFilename,
|
|
|
|
isAudioOnly: true,
|
|
|
|
isMp3: isMp3
|
2023-02-12 13:40:49 +06:00
|
|
|
}
|
|
|
|
if (images) {
|
|
|
|
let imageLinks = [];
|
|
|
|
for (let i in images) {
|
2024-03-15 16:00:02 +06:00
|
|
|
let sel = obj.host === "tiktok" ? images[i].display_image.url_list : images[i].url_list;
|
2023-08-23 01:03:31 +06:00
|
|
|
sel = sel.filter(p => p.includes(".jpeg?"))
|
2023-02-12 13:40:49 +06:00
|
|
|
imageLinks.push({url: sel[0]})
|
|
|
|
}
|
|
|
|
return {
|
|
|
|
picker: imageLinks,
|
|
|
|
urls: audio,
|
|
|
|
audioFilename: audioFilename,
|
|
|
|
isAudioOnly: true,
|
2023-02-13 19:44:58 +06:00
|
|
|
isMp3: isMp3
|
2023-02-12 13:40:49 +06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (audio) return {
|
|
|
|
urls: audio,
|
|
|
|
audioFilename: audioFilename,
|
|
|
|
isAudioOnly: true,
|
2023-02-13 19:44:58 +06:00
|
|
|
isMp3: isMp3
|
2023-02-12 13:40:49 +06:00
|
|
|
}
|
|
|
|
}
|