|
|
@ -1,13 +1,10 @@ |
|
|
|
import util from 'util'; |
|
|
|
import * as api from './api.mjs'; |
|
|
|
import { WATCH_BASE, PromiseQueue, escapeQuotes } from './util.mjs'; |
|
|
|
import { retryable } from '../lib/retry.mjs'; |
|
|
|
import { WATCH_BASE, escapeQuotes } from './util.mjs'; |
|
|
|
|
|
|
|
const GRAPH_NODE = ' "%s" [label="%s", URL="%s", fontcolor=blue]'; |
|
|
|
const GRAPH_LINK = ' "%s" -> "%s"'; |
|
|
|
|
|
|
|
const retryPlayerConfig = retryable(api.getPlayerConfig); |
|
|
|
|
|
|
|
/** |
|
|
|
* Explore the video graph starting from the given root. |
|
|
|
* |
|
|
@ -19,23 +16,22 @@ export const exploreVideos = async videoId => |
|
|
|
{ |
|
|
|
// Store metadata about each visited video
|
|
|
|
const videosNodes = Object.create(null); |
|
|
|
videosNodes[videoId] = {}; |
|
|
|
|
|
|
|
// List of videos linked from each video either through a card or an
|
|
|
|
// endscreen item
|
|
|
|
const nextVideos = Object.create(null); |
|
|
|
nextVideos[videoId] = new Set(); |
|
|
|
|
|
|
|
// Pending video requests
|
|
|
|
const queue = new PromiseQueue(); |
|
|
|
queue.add(retryPlayerConfig(videoId)); |
|
|
|
// Videos that still need to be explored
|
|
|
|
const queue = [videoId]; |
|
|
|
|
|
|
|
while (!queue.empty()) |
|
|
|
while (queue.length > 0) |
|
|
|
{ |
|
|
|
const config = await queue.next(); |
|
|
|
const currentId = queue.shift(); |
|
|
|
const config = await api.getPlayerConfig(currentId); |
|
|
|
const meta = api.getVideoMeta(config); |
|
|
|
|
|
|
|
videosNodes[meta.videoId] = meta; |
|
|
|
videosNodes[currentId] = meta; |
|
|
|
nextVideos[currentId] = new Set(); |
|
|
|
|
|
|
|
// Add links between this video and the linked ones
|
|
|
|
api.getEndScreenVideos(config) |
|
|
@ -47,9 +43,7 @@ export const exploreVideos = async videoId => |
|
|
|
{ |
|
|
|
if (!(nextId in videosNodes)) |
|
|
|
{ |
|
|
|
videosNodes[nextId] = {}; |
|
|
|
nextVideos[nextId] = new Set(); |
|
|
|
queue.add(retryPlayerConfig(nextId)); |
|
|
|
queue.push(nextId); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|