|
@@ -60,14 +60,21 @@ parseSetCookie = (headers) => {
|
|
}
|
|
}
|
|
console.log(`setCookie: ${setCookie}`)
|
|
console.log(`setCookie: ${setCookie}`)
|
|
let result = 'PREF=hl=en&tz=UTC; SOCS=CAI; GPS=1; ';
|
|
let result = 'PREF=hl=en&tz=UTC; SOCS=CAI; GPS=1; ';
|
|
- for (const cookieName of ['YSC', 'VISITOR_INFO1_LIVE', 'VISITOR_PRIVACY_METADATA']) {
|
|
|
|
|
|
+ const needCookieNames = ['YSC', 'VISITOR_INFO1_LIVE', 'VISITOR_PRIVACY_METADATA'];
|
|
|
|
+ for (const i in needCookieNames) {
|
|
|
|
+ const cookieName = needCookieNames[i];
|
|
const regexp = new RegExp(`${cookieName}=([^;,]+)`)
|
|
const regexp = new RegExp(`${cookieName}=([^;,]+)`)
|
|
const match = setCookie.match(regexp)
|
|
const match = setCookie.match(regexp)
|
|
if (match && match.length === 2) {
|
|
if (match && match.length === 2) {
|
|
const cookieValue = match[1]
|
|
const cookieValue = match[1]
|
|
- result += `${cookieName}=${cookieValue}; `
|
|
|
|
|
|
+ if (i != needCookieNames.length - 1) {
|
|
|
|
+ result += `${cookieName}=${cookieValue}; `
|
|
|
|
+ } else {
|
|
|
|
+ result += `${cookieName}=${cookieValue}`
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+ console.log(`current cookie: ${result}`)
|
|
return result;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -177,7 +184,8 @@ detail = async (url, platform) => {
|
|
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
|
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
|
|
'Accept-Language': 'en-us,en;q=0.5',
|
|
'Accept-Language': 'en-us,en;q=0.5',
|
|
'Sec-Fetch-Mode': 'navigate',
|
|
'Sec-Fetch-Mode': 'navigate',
|
|
- 'Cookie': 'PREF=hl=en&tz=UTC; SOCS=CAI',
|
|
|
|
|
|
+ 'Accept-Encoding': 'gzip, deflate, br',
|
|
|
|
+ 'Cookie': 'PREF=hl=en&tz=UTC; SOCS=CAI'
|
|
}, platform);
|
|
}, platform);
|
|
let {data: html, headers: htmlHeaders} = htmlResp;
|
|
let {data: html, headers: htmlHeaders} = htmlResp;
|
|
|
|
|
|
@@ -200,9 +208,20 @@ detail = async (url, platform) => {
|
|
}
|
|
}
|
|
|
|
|
|
let originFormats = [];
|
|
let originFormats = [];
|
|
|
|
+
|
|
|
|
+ const currentFormats = [];
|
|
|
|
+ for (const format of ytInitialPlayerResponse["streamingData"]["formats"].concat(ytInitialPlayerResponse["streamingData"]["adaptiveFormats"])) {
|
|
|
|
+ if (format) {
|
|
|
|
+ format["from"] = "web"
|
|
|
|
+ currentFormats.push(format);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ originFormats = originFormats.concat(currentFormats);
|
|
|
|
+ console.log(`after html, format size:${originFormats.length}`);
|
|
|
|
+
|
|
// android
|
|
// android
|
|
try {
|
|
try {
|
|
- const apiKey = 'AIzaSyA8eiZmM1FaDVjRy-df2KTyQ_vz_yYM39'
|
|
|
|
|
|
+ const apiKey = 'AIzaSyA8eiZmM1FaDVjRy-df2KTyQ_vz_yYM39w'
|
|
const apiUrl = `https://www.youtube.com/youtubei/v1/player?key=${apiKey}&prettyPrint=false`;
|
|
const apiUrl = `https://www.youtube.com/youtubei/v1/player?key=${apiKey}&prettyPrint=false`;
|
|
const apiResp = await request('POST', apiUrl, JSON.stringify({
|
|
const apiResp = await request('POST', apiUrl, JSON.stringify({
|
|
"context": {
|
|
"context": {
|
|
@@ -217,20 +236,27 @@ detail = async (url, platform) => {
|
|
}
|
|
}
|
|
},
|
|
},
|
|
'videoId': url.replace('https://www.youtube.com/watch?v=', ''),
|
|
'videoId': url.replace('https://www.youtube.com/watch?v=', ''),
|
|
|
|
+ "params": "CgIIAQ==",
|
|
"playbackContext": {
|
|
"playbackContext": {
|
|
"contentPlaybackContext": {
|
|
"contentPlaybackContext": {
|
|
"html5Preference": "HTML5_PREF_WANTS"
|
|
"html5Preference": "HTML5_PREF_WANTS"
|
|
}
|
|
}
|
|
},
|
|
},
|
|
- "params": "CgIIAQ==",
|
|
|
|
"contentCheckOk": true,
|
|
"contentCheckOk": true,
|
|
"racyCheckOk": true
|
|
"racyCheckOk": true
|
|
}), {
|
|
}), {
|
|
- 'X-YouTube-Client-Name': '5',
|
|
|
|
- 'X-YouTube-Client-Version': '19.09.3',
|
|
|
|
- 'User-Agent': 'com.google.ios.youtube/19.09.3 (iPhone14,3; U; CPU iOS 15_6 like Mac OS X)',
|
|
|
|
- 'Content-Type': 'application/json',
|
|
|
|
- 'Cookie': parseSetCookie(htmlHeaders)
|
|
|
|
|
|
+ 'Host': 'www.youtube.com',
|
|
|
|
+ 'Connection': 'keep-alive',
|
|
|
|
+ 'User-Agent': 'com.google.android.youtube/19.09.37 (Linux; U; Android 11) gzip',
|
|
|
|
+ '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',
|
|
|
|
+ 'X-YouTube-Client-Name': '3',
|
|
|
|
+ 'X-YouTube-Client-Version': '19.09.37',
|
|
|
|
+ 'Origin': 'https://www.youtube.com',
|
|
|
|
+ 'Accept-Encoding': 'gzip, deflate, br',
|
|
|
|
+ 'Cookie': parseSetCookie(htmlHeaders),
|
|
|
|
+ 'Content-Type': 'application/json'
|
|
}, platform);
|
|
}, platform);
|
|
let {data: apiData, _} = apiResp;
|
|
let {data: apiData, _} = apiResp;
|
|
console.log(`android api result: ${JSON.stringify(apiResp)}`);
|
|
console.log(`android api result: ${JSON.stringify(apiResp)}`);
|
|
@@ -272,11 +298,18 @@ detail = async (url, platform) => {
|
|
"contentCheckOk": true,
|
|
"contentCheckOk": true,
|
|
"racyCheckOk": true
|
|
"racyCheckOk": true
|
|
}), {
|
|
}), {
|
|
|
|
+ 'Host': 'www.youtube.com',
|
|
|
|
+ 'Connection': 'keep-alive',
|
|
|
|
+ 'User-Agent': 'com.google.ios.youtube/19.09.3 (iPhone14,3; U; CPU iOS 15_6 like Mac OS X)',
|
|
|
|
+ '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',
|
|
'X-YouTube-Client-Name': '5',
|
|
'X-YouTube-Client-Name': '5',
|
|
'X-YouTube-Client-Version': '19.09.3',
|
|
'X-YouTube-Client-Version': '19.09.3',
|
|
- 'User-Agent': 'com.google.ios.youtube/19.09.3 (iPhone14,3; U; CPU iOS 15_6 like Mac OS X)',
|
|
|
|
- 'Content-Type': 'application/json',
|
|
|
|
- 'Cookie': parseSetCookie(htmlHeaders)
|
|
|
|
|
|
+ 'Origin': 'https://www.youtube.com',
|
|
|
|
+ 'Accept-Encoding': 'gzip, deflate, br',
|
|
|
|
+ 'Cookie': parseSetCookie(htmlHeaders),
|
|
|
|
+ 'Content-Type': 'application/json'
|
|
}, platform);
|
|
}, platform);
|
|
let {data: apiData, _} = apiResp;
|
|
let {data: apiData, _} = apiResp;
|
|
console.log(`ios api result: ${JSON.stringify(apiResp)}`);
|
|
console.log(`ios api result: ${JSON.stringify(apiResp)}`);
|
|
@@ -294,16 +327,6 @@ detail = async (url, platform) => {
|
|
}
|
|
}
|
|
console.log(`after ios api, format size:${originFormats.length}`);
|
|
console.log(`after ios api, format size:${originFormats.length}`);
|
|
|
|
|
|
- const currentFormats = [];
|
|
|
|
- for (const format of ytInitialPlayerResponse["streamingData"]["formats"].concat(ytInitialPlayerResponse["streamingData"]["adaptiveFormats"])) {
|
|
|
|
- if (format) {
|
|
|
|
- format["from"] = "web"
|
|
|
|
- currentFormats.push(format);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- originFormats = originFormats.concat(currentFormats);
|
|
|
|
- console.log(`after html, format size:${originFormats.length}`);
|
|
|
|
-
|
|
|
|
const baseJsUrl = `https://www.youtube.com${JSON.parse(html.match(/set\(({.+?})\);/)[1])["PLAYER_JS_URL"]}`
|
|
const baseJsUrl = `https://www.youtube.com${JSON.parse(html.match(/set\(({.+?})\);/)[1])["PLAYER_JS_URL"]}`
|
|
let formatIds = [];
|
|
let formatIds = [];
|
|
const formats = [];
|
|
const formats = [];
|