added support for douyin
- full support for douyin (no watermark) - fixed up some tiktok stuff in the module
This commit is contained in:
parent
89d82f4999
commit
e9a67e1f48
6 changed files with 62 additions and 5 deletions
|
@ -2,6 +2,7 @@
|
||||||
"streamLifespan": 1800000,
|
"streamLifespan": 1800000,
|
||||||
"maxVideoDuration": 1920000,
|
"maxVideoDuration": 1920000,
|
||||||
"genericUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
|
"genericUserAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36",
|
||||||
|
"mobileUserAgent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1",
|
||||||
"authorInfo": {
|
"authorInfo": {
|
||||||
"name": "wukko",
|
"name": "wukko",
|
||||||
"link": "https://wukko.me/",
|
"link": "https://wukko.me/",
|
||||||
|
|
|
@ -9,6 +9,7 @@ version = packageJson.version,
|
||||||
streamLifespan = config.streamLifespan,
|
streamLifespan = config.streamLifespan,
|
||||||
maxVideoDuration = config.maxVideoDuration,
|
maxVideoDuration = config.maxVideoDuration,
|
||||||
genericUserAgent = config.genericUserAgent,
|
genericUserAgent = config.genericUserAgent,
|
||||||
|
mobileUserAgent = config.mobileUserAgent,
|
||||||
repo = packageJson["bugs"]["url"].replace('/issues', ''),
|
repo = packageJson["bugs"]["url"].replace('/issues', ''),
|
||||||
authorInfo = config.authorInfo,
|
authorInfo = config.authorInfo,
|
||||||
supportedLanguages = config.supportedLanguages,
|
supportedLanguages = config.supportedLanguages,
|
||||||
|
|
|
@ -7,6 +7,7 @@ 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 tiktok from "./services/tiktok.js";
|
import tiktok from "./services/tiktok.js";
|
||||||
|
import douyin from "./services/douyin.js";
|
||||||
|
|
||||||
export default async function (host, patternMatch, url, ip, lang, format, quality) {
|
export default async function (host, patternMatch, url, ip, lang, format, quality) {
|
||||||
try {
|
try {
|
||||||
|
@ -87,7 +88,7 @@ export default async function (host, patternMatch, url, ip, lang, format, qualit
|
||||||
}) : apiJSON(0, { t: r.error });
|
}) : apiJSON(0, { t: r.error });
|
||||||
} else throw Error()
|
} else throw Error()
|
||||||
case "tiktok":
|
case "tiktok":
|
||||||
if ((patternMatch["user"] && patternMatch["type"] == "video" && patternMatch["postId"] && patternMatch["postId"].length <= 21) ||
|
if ((patternMatch["user"] && patternMatch["postId"] && patternMatch["postId"].length <= 21) ||
|
||||||
(patternMatch["id"] && patternMatch["id"].length <= 13)) {
|
(patternMatch["id"] && patternMatch["id"].length <= 13)) {
|
||||||
let r = await tiktok({
|
let r = await tiktok({
|
||||||
postId: patternMatch["postId"],
|
postId: patternMatch["postId"],
|
||||||
|
@ -99,6 +100,19 @@ export default async function (host, patternMatch, url, ip, lang, format, qualit
|
||||||
filename: r.filename, salt: process.env.streamSalt
|
filename: r.filename, salt: process.env.streamSalt
|
||||||
}) : apiJSON(0, { t: r.error });
|
}) : apiJSON(0, { t: r.error });
|
||||||
} else throw Error()
|
} else throw Error()
|
||||||
|
case "douyin":
|
||||||
|
if ((patternMatch["postId"] && patternMatch["postId"].length <= 21) ||
|
||||||
|
(patternMatch["id"] && patternMatch["id"].length <= 13)) {
|
||||||
|
let r = await douyin({
|
||||||
|
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:
|
default:
|
||||||
return apiJSON(0, { t: errorUnsupported(lang) })
|
return apiJSON(0, { t: errorUnsupported(lang) })
|
||||||
}
|
}
|
||||||
|
|
|
@ -66,7 +66,11 @@
|
||||||
"enabled": false
|
"enabled": false
|
||||||
},
|
},
|
||||||
"tiktok": {
|
"tiktok": {
|
||||||
"patterns": [":user/:type/:postId", ":id"],
|
"patterns": [":user/video/:postId", ":id"],
|
||||||
|
"enabled": true
|
||||||
|
},
|
||||||
|
"douyin": {
|
||||||
|
"patterns": ["video/:postId", ":id"],
|
||||||
"enabled": true
|
"enabled": true
|
||||||
}
|
}
|
||||||
}
|
}
|
38
src/modules/services/douyin.js
Normal file
38
src/modules/services/douyin.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import got from "got";
|
||||||
|
import loc from "../../localization/manager.js";
|
||||||
|
import { genericUserAgent, mobileUserAgent } from "../config.js";
|
||||||
|
|
||||||
|
export default async function(obj) {
|
||||||
|
try {
|
||||||
|
if (!obj.postId) {
|
||||||
|
let html = await got.get(`https://v.douyin.com/${obj.id}/`, { headers: { "user-agent": genericUserAgent } });
|
||||||
|
html.on('error', (err) => {
|
||||||
|
return { error: loc(obj.lang, 'ErrorCantConnectToServiceAPI', 'tiktok') };
|
||||||
|
});
|
||||||
|
if (html.body.includes('<html><head><meta charset="UTF-8" />')) {
|
||||||
|
obj.postId = html.url.split('video/')[1].split('?')[0]
|
||||||
|
} else {
|
||||||
|
obj.postId = html.body.split('video/')[1].split('/?')[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let iteminfo = await got.get(`https://www.iesdouyin.com/web/api/v2/aweme/iteminfo/?item_ids=${obj.postId}`, {headers: {
|
||||||
|
'authority': 'www.iesdouyin.com',
|
||||||
|
'user-agent': mobileUserAgent,
|
||||||
|
'content-type': 'application/x-www-form-urlencoded',
|
||||||
|
'accept': '*/*',
|
||||||
|
'referer': `https://www.iesdouyin.com/share/video/${obj.postId}/?region=CN&u_code=15b9142gf&titleType=title&utm_source=copy_link&utm_campaign=client_share&utm_medium=android&app=aweme`,
|
||||||
|
'accept-language': 'zh-CN,zh;q=0.9,en-GB;q=0.8,en;q=0.7'
|
||||||
|
}});
|
||||||
|
iteminfo.on('error', (err) => {
|
||||||
|
return { error: loc(obj.lang, 'ErrorCantConnectToServiceAPI', 'douyin') };
|
||||||
|
});
|
||||||
|
iteminfo = JSON.parse(iteminfo.body);
|
||||||
|
if (iteminfo['item_list'][0]['video']['play_addr']['url_list'][0]) {
|
||||||
|
return { urls: iteminfo['item_list'][0]['video']['play_addr']['url_list'][0].replace("playwm", "play"), filename: `douyin_${obj.postId}.mp4` };
|
||||||
|
} else {
|
||||||
|
return { error: loc(obj.lang, 'ErrorEmptyDownload') };
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
return { error: loc(obj.lang, 'ErrorBadFetch') };
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
import got from "got";
|
import got from "got";
|
||||||
import loc from "../../localization/manager.js";
|
import loc from "../../localization/manager.js";
|
||||||
import { genericUserAgent} from "../config.js";
|
import { genericUserAgent } from "../config.js";
|
||||||
import { unicodeDecode } from "../sub/utils.js";
|
import { unicodeDecode } from "../sub/utils.js";
|
||||||
|
|
||||||
export default async function(obj) {
|
export default async function(obj) {
|
||||||
|
@ -17,8 +17,7 @@ export default async function(obj) {
|
||||||
obj.postId = html.split('aweme/detail/')[1].split('?')[0]
|
obj.postId = html.split('aweme/detail/')[1].split('?')[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let url = `https://tiktok.com/@video/video/${obj.postId}`
|
let html = await got.get(`https://tiktok.com/@video/video/${obj.postId}`, { headers: { "user-agent": genericUserAgent } });
|
||||||
let html = await got.get(url, { headers: { "user-agent": genericUserAgent } });
|
|
||||||
html.on('error', (err) => {
|
html.on('error', (err) => {
|
||||||
return { error: loc(obj.lang, 'ErrorCantConnectToServiceAPI', 'tiktok') };
|
return { error: loc(obj.lang, 'ErrorCantConnectToServiceAPI', 'tiktok') };
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue