123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- (() => {
- var __webpack_exports__ = {};
- console.log("bundle2!"), printable = e => "WEB" === e, parseCodecs = e => {
- const t = e.mimeType;
- if (!t) return {};
- const n = t.match(/(?<mimetype>[^/]+\/[^;]+)(?:;\s*codecs="?(?<codecs>[^"]+))?/);
- if (!n) return {};
- const o = n.groups.codecs;
- if (!o) return {};
- const s = o.trim().replace(/,$/, "").split(",").map((e => e.trim())).filter(Boolean);
- let i = null, c = null;
- for (const e of s) {
- const t = e.split(".")[0];
- ["avc1", "avc2", "avc3", "avc4", "vp9", "vp8", "hev1", "hev2", "h263", "h264", "mp4v", "hvc1", "av01", "theora"].includes(t) ? i || (i = e) : ["mp4a", "opus", "vorbis", "mp3", "aac", "ac-3", "ec-3", "eac3", "dtsc", "dtse", "dtsh", "dtsl"].includes(t) ? c || (c = e) : console.log(`WARNING: Unknown codec ${e}`)
- }
- return i || c ? {vcodec: i, acodec: c} : 2 === s.length ? {vcodec: s[0], acodec: s[1]} : {}
- }, parseSetCookie = e => {
- if (!e) return "";
- const t = e["Set-Cookie"];
- if (!t) return "";
- console.log(`setCookie: ${t}`);
- let n = "PREF=hl=en&tz=UTC; SOCS=CAI; GPS=1; ";
- const o = ["YSC", "VISITOR_INFO1_LIVE", "VISITOR_PRIVACY_METADATA"];
- for (const e in o) {
- const s = o[e], i = new RegExp(`${s}=([^;,]+)`), c = t.match(i);
- if (c && 2 === c.length) {
- const t = c[1];
- n += e != o.length - 1 ? `${s}=${t}; ` : `${s}=${t}`
- }
- }
- return console.log(`current cookie: ${n}`), n
- }, request = async (e, t, n = null, o = {}, s) => {
- if ("WEB" === s && (t = t.replace("https://www.youtube.com", "http://127.0.0.1")), console.log(`request url:${t}`), console.log(`request data:${n}`), console.log(`request method:${e}`), console.log(`request headers:${JSON.stringify(o)}`), "WEB" === s) {
- const s = await fetch(t, {mode: "cors", method: e, headers: o, body: n}), i = await s.text();
- return Promise.resolve({data: i, headers: s.headers})
- }
- return new Promise(((s, i) => {
- AF.request(t, e, n, o, ((e, t, n) => {
- n ? i(n) : (console.log(`response headers: ${t}`), s({data: e, headers: JSON.parse(t)}))
- }))
- }))
- }, getStringBetween = (e, t, n, o = 0, s = 0) => {
- const i = e.indexOf(t), c = n ? e.indexOf(n, i) : e.length;
- return e.substring(i + t.length + s, c + o)
- }, findFunction = (jsCode, regexp, platform) => {
- const match = jsCode.match(regexp);
- if (!match && match.length <= 1) return null;
- let result = "";
- const dependencyMatches = match[0].match(/([$a-zA-Z0-9]+\.[$a-zA-Z0-9]+)/g), existDependencies = [];
- if (dependencyMatches && dependencyMatches.length >= 1) for (let e of dependencyMatches) {
- const t = e.split(".")[0];
- if (existDependencies.includes(t)) continue;
- const n = jsCode.match(new RegExp(`var \\${t}={(.|\\n)*?};`), "ig");
- n && n.length >= 1 && (result += n[0] + "\n"), existDependencies.push(t)
- }
- return result += `\n${match[0]}`, printable(platform) && console.log("decipherFunction result: " + result), eval(result)
- };
- const cache = {};
- fetchBaseJSContent = async (e, t) => {
- const n = `jsContent:${e}`;
- if (cache[n]) return console.log(`baseContent from cache: ${e}`), cache[n];
- console.log(`extract baseUrl: ${e}`);
- const o = await request("GET", e, null, {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.101 Safari/537.36"}, t), {
- data: s,
- _: i
- } = o;
- return cache[n] = s, s
- }, extractJSSignatureFunction = async (e, t) => {
- const n = `jsSign:${e}`;
- if (cache[n]) return console.log(`jsSign from cache: ${e}`), cache[n];
- const o = await fetchBaseJSContent(e, t),
- s = findFunction(o, /([a-zA-Z0-9]+)=function\([a-zA-Z0-9]+\)\{a=a\.split\(""\).*};/, t);
- return cache[n] = s, s
- }, extractNJSFunction = async (e, t) => {
- const n = `jsN:${e}`;
- if (cache[n]) return console.log(`jsN from cache: ${e}`), cache[n];
- const o = await fetchBaseJSContent(e, t),
- s = findFunction(o, /([a-zA-Z0-9]+)=function\([a-zA-Z0-9]+\)\{var b=a\.split\(""\)[\s\S]*?};/, t);
- return cache[n] = s, s
- }, signUrl = async (e, t, n) => {
- const o = {};
- for (const t of e.split("&")) {
- const [e, n] = t.split("=");
- o[decodeURIComponent(e)] = decodeURIComponent(n)
- }
- const [s, i, c] = [o.url, o.s, o.sp], r = await extractJSSignatureFunction(t, n);
- if (!r) return null;
- printable(n) && console.log(`signatureCipher=${e}, url=${s}, signature=${i}, sp=${c}`);
- let a = `${s}&${c}=${r(i)}`;
- for (const e of s.split("&")) {
- const [t, n] = e.split("=");
- o[decodeURIComponent(t)] = decodeURIComponent(n)
- }
- const l = await extractNJSFunction(t, n), u = o.n;
- if (u && l) {
- return function d(e, t, n) {
- let o = new RegExp(`([?&])${t}=.*?(&|$)`, "i"), s = e.replace(o, `$1${t}=${n}$2`);
- return s === e && -1 === e.indexOf("?") ? s += `?${t}=${n}` : s === e && (s += `&${t}=${n}`), s
- }(a, "n", l(u))
- }
- return a
- }, detail = async (e, t) => {
- try {
- const n = await request("GET", `${e}&bpctr=9999999999&has_verified=1`, null, {
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36",
- 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",
- Cookie: "PREF=hl=en&tz=UTC; SOCS=CAI"
- }, t);
- let {data: o, headers: s} = n, i = /var ytInitialPlayerResponse\s*=\s*({.*?});/, c = o.match(i);
- if (!c || !c.length) throw console.log("can not found JSON: ytInitialPlayerResponse"), new Error("JSON not found: ytInitialPlayerResponse");
- const r = JSON.parse(c[1]);
- printable(t) && console.log(r);
- const a = r.videoDetails, l = [];
- for (const e of a.thumbnail.thumbnails) l.push({url: e.url, width: e.width + "", height: e.height + ""});
- let u = [];
- const d = [];
- for (const e of r.streamingData.formats.concat(r.streamingData.adaptiveFormats)) e && (e.from = "web", d.push(e));
- u = u.concat(d), console.log(`after html, format size:${u.length}`);
- const h = `https://www.youtube.com${JSON.parse(o.match(/set\(({.+?})\);/)[1]).PLAYER_JS_URL}`;
- let p = [];
- const m = [];
- for (let e of u) if (printable(t) && console.log(e), e && -1 === p.indexOf(e.itag) && (e.url || (e.url = await signUrl(e.signatureCipher, h, t)), e.url)) {
- const {vcodec: n, acodec: o} = parseCodecs(e);
- if (n && o) {
- const s = {
- width: e.width + "",
- height: e.height + "",
- type: e.mimeType,
- quality: e.quality,
- itag: e.itag,
- fps: e.fps + "",
- bitrate: e.bitrate + "",
- url: e.url,
- ext: "mp4",
- vcodec: n,
- acodec: o,
- vbr: "0",
- abr: "0",
- container: "mp4_dash",
- from: e.from
- };
- "WEB" === t && (s.source = e), m.push(s), p.push(e.itag)
- }
- }
- const g = o.match(/var ytInitialData\s*=\s*({.*?});/), f = [];
- if (g && 2 === g.length) {
- const e = JSON.parse(g[1]);
- printable(t) && console.log(e);
- for (const t of e.contents?.twoColumnWatchNextResults?.secondaryResults?.secondaryResults?.results || []) if (t.compactVideoRenderer) {
- const e = t.compactVideoRenderer;
- console.log(`recommend video: ${JSON.stringify(e)}`), e.videoId && f.push({
- type: "gridVideoRenderer",
- videoId: e.videoId,
- title: e.title?.simpleText,
- thumbnails: e.thumbnail?.thumbnails,
- channelName: e.longBylineText?.runs?.[0]?.text,
- publishedTimeText: e.publishedTimeText?.simpleText,
- viewCountText: e.viewCountText?.simpleText,
- shortViewCountText: e.shortViewCountText?.simpleText,
- lengthText: e.lengthText?.simpleText
- })
- }
- }
- const x = {
- code: 200,
- msg: "",
- data: {
- videoDetails: {
- isLiveContent: a.isLiveContent,
- title: a.title,
- thumbnails: l,
- description: a.shortDescription,
- lengthSeconds: a.lengthSeconds,
- viewCount: a.viewCount,
- keywords: a.keywords,
- author: a.author,
- channelID: a.channelId,
- recommendInfo: f,
- channelURL: `https://www.youtube.com/channel/${a.channelId}`,
- videoId: a.videoId
- }, streamingData: {formats: m.reverse()}
- },
- id: "MusicDetailViewModel_detail_url"
- };
- return console.log(`detail result: ${JSON.stringify(x)}`), x
- } catch (e) {
- const t = {code: -1, msg: e.toString()};
- return console.log(`detail result error: ${JSON.stringify(t)}`), console.log(e), t
- }
- }, search = async (e, t, n) => {
- try {
- if (console.log(`search keyword: ${e}`), console.log(`search next: ${t}`), t) {
- const e = JSON.parse(t), o = e.key, s = {
- context: {client: {clientName: "WEB", clientVersion: "2.20240506.01.00"}},
- continuation: e.continuation
- };
- let i = await request("POST", `https://www.youtube.com/youtubei/v1/search?key=${o}`, JSON.stringify(s), {}, n);
- const {data: c, _: r} = i;
- i = JSON.parse(c);
- const a = [];
- for (const e of i.onResponseReceivedCommands[0].appendContinuationItemsAction.continuationItems[0].itemSectionRenderer.contents) {
- const t = e.videoRenderer;
- printable(n) && console.log(t), t && t.videoId && a.push({
- type: "videoWithContextRenderer",
- data: {
- videoId: t.videoId,
- title: t.title?.runs?.[0]?.text,
- thumbnails: t.thumbnail?.thumbnails,
- channelName: t.longBylineText?.runs?.[0]?.text,
- publishedTimeText: t.publishedTimeText?.simpleText,
- viewCountText: t.viewCountText?.simpleText,
- shortViewCountText: t.shortViewCountText?.simpleText,
- lengthText: t.lengthText?.simpleText
- }
- })
- }
- const l = {
- code: 200,
- msg: "",
- data: {
- data: a,
- next: JSON.stringify({
- key: e.key,
- continuation: i.onResponseReceivedCommands?.[0]?.appendContinuationItemsAction?.continuationItems?.[1]?.continuationItemRenderer?.continuationEndpoint?.continuationCommand?.token
- })
- },
- id: "MusicSearchResultViewModel_search_result"
- };
- return console.log(`[next] search result: ${JSON.stringify(l)}`), l
- }
- {
- let t = `https://www.youtube.com/results?q=${encodeURIComponent(e)}&sp=EgIQAQ%253D%253D`;
- const o = await request("GET", t, null, {}, n), {data: s, _: i} = o;
- let c = /var ytInitialData\s*=\s*({.*?});/, r = s.match(c);
- if (!r || !r.length) throw console.log("can not found ytInitialData"), new Error("JSON not found: ytInitialData");
- const a = JSON.parse(r[1]), l = [];
- for (const e of a.contents?.twoColumnSearchResultsRenderer?.primaryContents?.sectionListRenderer?.contents?.[0]?.itemSectionRenderer?.contents) if (e.videoRenderer) {
- const t = e.videoRenderer;
- printable(n) && console.log(t), t && t.videoId && l.push({
- type: "videoWithContextRenderer",
- data: {
- videoId: t.videoId,
- title: t.title?.runs?.[0]?.text,
- thumbnails: t.thumbnail?.thumbnails,
- channelName: t.longBylineText?.runs?.[0]?.text,
- publishedTimeText: t.publishedTimeText?.simpleText,
- viewCountText: t.viewCountText?.simpleText,
- shortViewCountText: t.shortViewCountText?.simpleText,
- lengthText: t.lengthText?.simpleText
- }
- })
- }
- let u = {};
- s.split("innertubeApiKey").length > 0 && (u.key = s.split("innertubeApiKey")[1].trim().split(",")[0].split('"')[2]), u.continuation = a.contents?.twoColumnSearchResultsRenderer?.primaryContents?.sectionListRenderer?.contents?.[1]?.continuationItemRenderer?.continuationEndpoint?.continuationCommand?.token;
- const d = {
- code: 200,
- msg: "",
- data: {data: l, next: JSON.stringify(u)},
- id: "MusicSearchResultViewModel_search_result"
- };
- return console.log(`unnext search result: ${JSON.stringify(d)}`), d
- }
- } catch (e) {
- const t = {code: -1, msg: e.toString()};
- return console.log(`search result error: ${JSON.stringify(t)}`), t
- }
- }
- })();
- //# sourceMappingURL=bundle.js.map
|