|
@@ -28,107 +28,106 @@ getVideoDetail = async (url) => {
|
|
const headers = {
|
|
const headers = {
|
|
'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',
|
|
'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',
|
|
}
|
|
}
|
|
- return request('GET', url, null, headers)
|
|
|
|
- .then(res => {
|
|
|
|
- let regex = /var ytInitialPlayerResponse\s*=\s*({.*?});/;
|
|
|
|
- let match = res.match(regex);
|
|
|
|
- if (!match || !match.length) {
|
|
|
|
- throw new Error('JSON not found.');
|
|
|
|
- }
|
|
|
|
- const ytInitialPlayerResponse = JSON.parse(match[1]);
|
|
|
|
- console.log(ytInitialPlayerResponse);
|
|
|
|
- const originVideoDetails = ytInitialPlayerResponse["videoDetails"];
|
|
|
|
- const thumbnails = []
|
|
|
|
- for (const item of originVideoDetails["thumbnail"]["thumbnails"]) {
|
|
|
|
- thumbnails.push({
|
|
|
|
- "url": item["url"],
|
|
|
|
- "width": item["width"] + "",
|
|
|
|
- "height": item["height"] + ""
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
|
|
+ const res = await request('GET', url, null, headers)
|
|
|
|
|
|
- const formats = []
|
|
|
|
- for (const item of ytInitialPlayerResponse["streamingData"]["formats"].concat(ytInitialPlayerResponse["streamingData"]["adaptiveFormats"])) {
|
|
|
|
- if (item && item["signatureCipher"] && item["mimeType"]) {
|
|
|
|
- let urlRegex = /url=([^&]+)/;
|
|
|
|
- let match = item["signatureCipher"].match(urlRegex);
|
|
|
|
- if (!match) {
|
|
|
|
- continue;
|
|
|
|
- }
|
|
|
|
- const encodedUrl = match[1];
|
|
|
|
- const decodedUrl = decodeURIComponent(encodedUrl);
|
|
|
|
|
|
+ let regex = /var ytInitialPlayerResponse\s*=\s*({.*?});/;
|
|
|
|
+ let match = res.match(regex);
|
|
|
|
+ if (!match || !match.length) {
|
|
|
|
+ throw new Error('JSON not found.');
|
|
|
|
+ }
|
|
|
|
+ const ytInitialPlayerResponse = JSON.parse(match[1]);
|
|
|
|
+ console.log(ytInitialPlayerResponse);
|
|
|
|
+ const originVideoDetails = ytInitialPlayerResponse["videoDetails"];
|
|
|
|
+ const thumbnails = []
|
|
|
|
+ for (const item of originVideoDetails["thumbnail"]["thumbnails"]) {
|
|
|
|
+ thumbnails.push({
|
|
|
|
+ "url": item["url"],
|
|
|
|
+ "width": item["width"] + "",
|
|
|
|
+ "height": item["height"] + ""
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
|
|
- formats.push({
|
|
|
|
- "width": item["width"] + "",
|
|
|
|
- "height": item["height"] + "",
|
|
|
|
- "type": item["mimeType"],
|
|
|
|
- "quality": item["quality"],
|
|
|
|
- "itag": item["itag"],
|
|
|
|
- "fps": item["fps"] + "",
|
|
|
|
- "bitrate": item["bitrate"] + "",
|
|
|
|
- "url": decodedUrl,
|
|
|
|
- "ext": "mp4",
|
|
|
|
- "vcodec": item["mimeType"],
|
|
|
|
- "acodec": item["mimeType"],
|
|
|
|
- "vbr": "0",
|
|
|
|
- "abr": "0",
|
|
|
|
- "container": "mp4_dash"
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
|
|
+ const formats = []
|
|
|
|
+ for (const item of ytInitialPlayerResponse["streamingData"]["formats"].concat(ytInitialPlayerResponse["streamingData"]["adaptiveFormats"])) {
|
|
|
|
+ if (item && item["signatureCipher"] && item["mimeType"]) {
|
|
|
|
+ let urlRegex = /url=([^&]+)/;
|
|
|
|
+ let match = item["signatureCipher"].match(urlRegex);
|
|
|
|
+ if (!match) {
|
|
|
|
+ continue;
|
|
}
|
|
}
|
|
|
|
+ const encodedUrl = match[1];
|
|
|
|
+ const decodedUrl = decodeURIComponent(encodedUrl);
|
|
|
|
|
|
- regex = /var ytInitialData\s*=\s*({.*?});/;
|
|
|
|
- match = res.match(regex);
|
|
|
|
- if (!match || !match.length) {
|
|
|
|
- throw new Error('JSON not found.');
|
|
|
|
- }
|
|
|
|
- if (!match || !match.length) {
|
|
|
|
- throw new Error('JSON not found.');
|
|
|
|
- }
|
|
|
|
- const ytInitialData = JSON.parse(match[1]);
|
|
|
|
- console.log(ytInitialData);
|
|
|
|
- const recommendInfo = [];
|
|
|
|
- for (const item of ytInitialData["contents"]["twoColumnWatchNextResults"]["secondaryResults"]["secondaryResults"]["results"]) {
|
|
|
|
- if (item["compactVideoRenderer"]) {
|
|
|
|
- const recommendVideo = item["compactVideoRenderer"];
|
|
|
|
- recommendInfo.push({
|
|
|
|
- "type": "gridVideoRenderer",
|
|
|
|
- "videoId": recommendVideo["videoId"],
|
|
|
|
- "title": recommendVideo["title"]["simpleText"],
|
|
|
|
- "thumbnails": recommendVideo["thumbnail"]["thumbnails"],
|
|
|
|
- "channelName": recommendVideo["longBylineText"]["runs"][0]["text"],
|
|
|
|
- "publishedTimeText": recommendVideo["publishedTimeText"]["simpleText"],
|
|
|
|
- "viewCountText": recommendVideo["viewCountText"]["simpleText"],
|
|
|
|
- "shortViewCountText": recommendVideo["shortViewCountText"]["simpleText"],
|
|
|
|
- "lengthText": recommendVideo["lengthText"]["simpleText"]
|
|
|
|
- })
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ formats.push({
|
|
|
|
+ "width": item["width"] + "",
|
|
|
|
+ "height": item["height"] + "",
|
|
|
|
+ "type": item["mimeType"],
|
|
|
|
+ "quality": item["quality"],
|
|
|
|
+ "itag": item["itag"],
|
|
|
|
+ "fps": item["fps"] + "",
|
|
|
|
+ "bitrate": item["bitrate"] + "",
|
|
|
|
+ "url": decodedUrl,
|
|
|
|
+ "ext": "mp4",
|
|
|
|
+ "vcodec": item["mimeType"],
|
|
|
|
+ "acodec": item["mimeType"],
|
|
|
|
+ "vbr": "0",
|
|
|
|
+ "abr": "0",
|
|
|
|
+ "container": "mp4_dash"
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
|
|
- const videoDetails = {
|
|
|
|
- "isLiveContent": originVideoDetails["isLiveContent"],
|
|
|
|
- "title": originVideoDetails["title"],
|
|
|
|
- "thumbnails": thumbnails,
|
|
|
|
- "description": originVideoDetails["shortDescription"],
|
|
|
|
- "lengthSeconds": originVideoDetails["lengthSeconds"],
|
|
|
|
- "viewCount": originVideoDetails["viewCount"],
|
|
|
|
- "keywords": originVideoDetails["keywords"],
|
|
|
|
- "author": originVideoDetails["author"],
|
|
|
|
- "channelID": originVideoDetails["channelId"],
|
|
|
|
- "recommendInfo": recommendInfo,
|
|
|
|
- "channelURL": `https://www.youtube.com/channel/${originVideoDetails["channelId"]}`,
|
|
|
|
- "videoId": originVideoDetails["videoId"]
|
|
|
|
- }
|
|
|
|
- return {
|
|
|
|
- "code": 200,
|
|
|
|
- "msg": "",
|
|
|
|
- "data": {
|
|
|
|
- "videoDetails": videoDetails,
|
|
|
|
- "streamingData": {
|
|
|
|
- "formats": formats
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- "id": "MusicDetailViewModel_detail_url"
|
|
|
|
|
|
+ regex = /var ytInitialData\s*=\s*({.*?});/;
|
|
|
|
+ match = res.match(regex);
|
|
|
|
+ if (!match || !match.length) {
|
|
|
|
+ throw new Error('JSON not found.');
|
|
|
|
+ }
|
|
|
|
+ if (!match || !match.length) {
|
|
|
|
+ throw new Error('JSON not found.');
|
|
|
|
+ }
|
|
|
|
+ const ytInitialData = JSON.parse(match[1]);
|
|
|
|
+ console.log(ytInitialData);
|
|
|
|
+ const recommendInfo = [];
|
|
|
|
+ for (const item of ytInitialData["contents"]["twoColumnWatchNextResults"]["secondaryResults"]["secondaryResults"]["results"]) {
|
|
|
|
+ if (item["compactVideoRenderer"]) {
|
|
|
|
+ const recommendVideo = item["compactVideoRenderer"];
|
|
|
|
+ recommendInfo.push({
|
|
|
|
+ "type": "gridVideoRenderer",
|
|
|
|
+ "videoId": recommendVideo["videoId"],
|
|
|
|
+ "title": recommendVideo["title"]["simpleText"],
|
|
|
|
+ "thumbnails": recommendVideo["thumbnail"]["thumbnails"],
|
|
|
|
+ "channelName": recommendVideo["longBylineText"]["runs"][0]["text"],
|
|
|
|
+ "publishedTimeText": recommendVideo["publishedTimeText"]["simpleText"],
|
|
|
|
+ "viewCountText": recommendVideo["viewCountText"]["simpleText"],
|
|
|
|
+ "shortViewCountText": recommendVideo["shortViewCountText"]["simpleText"],
|
|
|
|
+ "lengthText": recommendVideo["lengthText"]["simpleText"]
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const videoDetails = {
|
|
|
|
+ "isLiveContent": originVideoDetails["isLiveContent"],
|
|
|
|
+ "title": originVideoDetails["title"],
|
|
|
|
+ "thumbnails": thumbnails,
|
|
|
|
+ "description": originVideoDetails["shortDescription"],
|
|
|
|
+ "lengthSeconds": originVideoDetails["lengthSeconds"],
|
|
|
|
+ "viewCount": originVideoDetails["viewCount"],
|
|
|
|
+ "keywords": originVideoDetails["keywords"],
|
|
|
|
+ "author": originVideoDetails["author"],
|
|
|
|
+ "channelID": originVideoDetails["channelId"],
|
|
|
|
+ "recommendInfo": recommendInfo,
|
|
|
|
+ "channelURL": `https://www.youtube.com/channel/${originVideoDetails["channelId"]}`,
|
|
|
|
+ "videoId": originVideoDetails["videoId"]
|
|
|
|
+ }
|
|
|
|
+ return {
|
|
|
|
+ "code": 200,
|
|
|
|
+ "msg": "",
|
|
|
|
+ "data": {
|
|
|
|
+ "videoDetails": videoDetails,
|
|
|
|
+ "streamingData": {
|
|
|
|
+ "formats": formats
|
|
}
|
|
}
|
|
- })
|
|
|
|
|
|
+ },
|
|
|
|
+ "id": "MusicDetailViewModel_detail_url"
|
|
|
|
+ }
|
|
}
|
|
}
|