Compare commits
3 Commits
5a1e38a782
..
master
| Author | SHA1 | Date | |
|---|---|---|---|
| e5189b4066 | |||
| 842ca82a0e | |||
| 2ff0100f2a |
@@ -71,9 +71,11 @@ Gets Trending YouTube videos. Identical to `/search` but without `input` paramet
|
||||
## GET `/vrcurl/{pool}/{index}`
|
||||
|
||||
- `{pool}`: must be same as pool param in search endpoint.
|
||||
- `{index}`: vrcurl index number
|
||||
- `{index}`: vrcurl index number as specified in response data
|
||||
|
||||
Response may be 302 redirect to youtube url, `image/png` for imagesheet, `application/json` for next page (see response format above) or trending tab or video json data (see below).
|
||||
For youtube videos, if `User-Agent` header includes `UnityWebRequest`, then response is `application/json` for video metadata (captions). Otherwise, it is 302 redirect to youtube URL.
|
||||
|
||||
For image sheet, response is `image/png`. For next page or trending tab, response is `application/json`.
|
||||
|
||||
### Video metadata JSON format
|
||||
|
||||
|
||||
@@ -58,12 +58,14 @@ router.get("/vrcurl/:pool/:num", async ctx => {
|
||||
}
|
||||
switch (dest.type) {
|
||||
case "redirect":
|
||||
ctx.set("Referrer-Policy", "no-referrer");
|
||||
ctx.redirect(dest.url);
|
||||
break;
|
||||
case "video":
|
||||
if (ctx.get("User-Agent").includes("UnityWebRequest")) {
|
||||
ctx.body = {captions: await getVideoCaptionsCached(dest.id)};
|
||||
} else {
|
||||
ctx.set("Referrer-Policy", "no-referrer");
|
||||
ctx.redirect(`https://www.youtube.com/watch?v=${dest.id}`);
|
||||
}
|
||||
break;
|
||||
|
||||
Generated
-21
@@ -647,27 +647,6 @@
|
||||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/encoding": {
|
||||
"version": "0.1.13",
|
||||
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz",
|
||||
"integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"iconv-lite": "^0.6.2"
|
||||
}
|
||||
},
|
||||
"node_modules/encoding/node_modules/iconv-lite": {
|
||||
"version": "0.6.3",
|
||||
"resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
|
||||
"integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
|
||||
"optional": true,
|
||||
"dependencies": {
|
||||
"safer-buffer": ">= 2.1.2 < 3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/end-of-stream": {
|
||||
"version": "1.4.4",
|
||||
"resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
|
||||
|
||||
+6
-2
@@ -8,7 +8,7 @@ var xmlParser = new XMLParser({
|
||||
async function getVideoData(videoId) {
|
||||
var res = await gotw(`https://www.youtube.com/watch?v=${videoId}`);
|
||||
|
||||
var ytInitialPlayerResponse = res.body.match(/var ytInitialPlayerResponse = ({.*});/)[1];
|
||||
var ytInitialPlayerResponse = res.body.match(/var ytInitialPlayerResponse = ({.*?});/)[1];
|
||||
ytInitialPlayerResponse = JSON.parse(ytInitialPlayerResponse);
|
||||
|
||||
return ytInitialPlayerResponse;
|
||||
@@ -20,7 +20,11 @@ async function getVideoCaptions(videoId) {
|
||||
var captionTracks = ytInitialPlayerResponse.captions.playerCaptionsTracklistRenderer.captionTracks;
|
||||
captionTracks = await Promise.all(captionTracks.map(captionTrack => (async () => {
|
||||
try {
|
||||
var xml = await gotw(captionTrack.baseUrl, {resolveBodyOnly: true});
|
||||
var promise = gotw(captionTrack.baseUrl);
|
||||
var res = await promise;
|
||||
if (res.statusCode != 200) throw new Error("unexpected status " + res.statusCode);
|
||||
var xml = await promise.text();
|
||||
if (!xml) throw new Error("empty response for caption track");
|
||||
var parsed = xmlParser.parse(xml);
|
||||
var lines = parsed.transcript.text;
|
||||
if (!Array.isArray(lines)) lines = [lines];
|
||||
|
||||
Reference in New Issue
Block a user