console.log('bundle2!') printable = (platform) => { return platform === "WEB"; } parseSetCookie = (headers) => { if (!headers) { return "" } const setCookie = headers['Set-Cookie'] if (!setCookie) { return "" } console.log(`setCookie: ${setCookie}`) let result = {} const needCookieNames = ['ttwid', 'tt_csrf_token', 'tt_chain_token']; for (const i in needCookieNames) { const cookieName = needCookieNames[i]; const regexp = new RegExp(`${cookieName}=([^;,]+)`) const match = setCookie.match(regexp) if (match && match.length === 2) { result[cookieName] = match[1] } } return result; } request = async (method, url, data = null, headers = {}, platform) => { console.log(`request url:${url}`) console.log(`request data:${data}`) console.log(`request method:${method}`) console.log(`request headers:${JSON.stringify((headers))}`) if (platform === "WEB") { const res = await fetch(url, { 'mode': 'cors', 'method': method, 'headers': headers, 'body': data }) const resData = await res.text() return Promise.resolve({ 'data': resData, 'headers': res.headers }); } return new Promise((resolve, reject) => { AF.request(url, method, data, headers, (data, headers, err) => { if (err) { reject(err); } else { console.log(`response headers: ${headers}`); resolve({ 'data': data, 'headers': JSON.parse(headers) }); } }); }) } detail = async (url, platform) => { try { const htmlResp = await request('GET', url, null, { 'Host': 'www.tiktok.com', 'Connection': 'keep-alive', 'User-Agent': 'Mozilla/5.0', 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8', 'Accept-Language': 'en-us,en;q=0.5', 'Sec-Fetch-Mode': 'navigate', 'Accept-Encoding': 'gzip, deflate, br' }, platform); let {data: html, headers: htmlHeaders} = htmlResp; let match = html.match(/({"__DEFAULT_SCOPE__".*?)<\/script>/); if (!match || !match.length) { console.log('can not found JSON: scope'); throw new Error('JSON not found: scope'); } const scope = JSON.parse(match[1]); if (printable(platform)) { console.log(match[1]); console.log(scope); } const setCookie = parseSetCookie(htmlHeaders); const videoDetail = scope["__DEFAULT_SCOPE__"]["webapp.video-detail"]["itemInfo"]["itemStruct"]; const bitrateInfos = videoDetail["video"]["bitrateInfo"]; const formats = []; formats.push({ "url": videoDetail["video"]["playAddr"], "headers": { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.19 Safari/537.36", "Cookie": setCookie } }) for (let bitrateInfo of bitrateInfos) { for (let url of bitrateInfo["PlayAddr"]["UrlList"]) { formats.push({ "url": url, "headers": { "Cookie": setCookie } }) } } const videoDetails = { "title": videoDetail["desc"], "thumbnail": videoDetail["video"]["cover"], "videoId": videoDetail["id"] } const ret = { "code": 200, "msg": "", "data": { "videoDetails": videoDetails, "streamingData": { "formats": formats } }, "id": "DetailViewModel_detail_url" } console.log(`detail result: ${JSON.stringify(ret)}`); return ret; } catch (e) { const ret = { "code": -1, "msg": e.toString() } console.log(`detail result error: ${JSON.stringify(ret)}`); console.log(e); return ret; } }