add innerTube API, types and tests

This commit is contained in:
Michael C
2022-09-14 00:33:52 -04:00
parent 072324f0ab
commit 3c09033267
3 changed files with 103 additions and 0 deletions

View File

@@ -0,0 +1,23 @@
export interface innerTubeVideoDetails {
"videoId": string,
"title": string,
"lengthSeconds": string, // yes, don't ask.
"channelId": string,
"isOwnerViewing": boolean,
"shortDescription": string,
"isCrawlable": boolean,
"thumbnail": {
"thumbnails": [{
"url": string,
"width": number,
"height": number
}
]
},
"allowRatings": boolean,
"viewCount": string, // yes, don't ask
"author": string,
"isPrivate": boolean,
"isUnpluggedCorpus": boolean,
"isLiveContent": boolean
}

29
src/utils/innerTubeAPI.ts Normal file
View File

@@ -0,0 +1,29 @@
import axios from "axios";
import { innerTubeVideoDetails } from "../types/innerTubeApi.model";
export async function getPlayerData(videoID: string): Promise<innerTubeVideoDetails> {
// start subrequest
const url = "https://www.youtube.com/youtubei/v1/player";
const data = {
context: {
client: {
clientName: "WEB",
clientVersion: "2.20211129.09.00"
}
},
videoId: videoID
};
const result = await axios.post(url, data, {
timeout: 3500
});
if (result.status === 200) {
return result.data.videoDetails;
} else {
return Promise.reject(result.status);
}
}
export const getLength = (videoID: string): Promise<number> =>
getPlayerData(videoID)
.then(pData => Number(pData.lengthSeconds))
.catch(err => err);

View File

@@ -0,0 +1,51 @@
import { config } from "../../src/config";
import assert from "assert";
// import { innerTubeVideoDetails } from "../../src/types/innerTubeApi.model";
import { YouTubeAPI } from "../../src/utils/youtubeApi";
import * as innerTube from "../../src/utils/innerTubeAPI";
import { partialDeepEquals } from "../utils/partialDeepEquals";
const videoID = "dQw4w9WgXcQ";
const expected = { // partial type of innerTubeVideoDetails
videoId: videoID,
title: "Rick Astley - Never Gonna Give You Up (Official Music Video)",
lengthSeconds: "212",
channelId: "UCuAXFkgsw1L7xaCfnd5JJOw",
isOwnerViewing: false,
isCrawlable: true,
allowRatings: true,
author: "Rick Astley",
isPrivate: false,
isUnpluggedCorpus: false,
isLiveContent: false
};
const currentViews = 1284257550;
describe("innertube API test", function() {
it("should be able to get innerTube details", async () => {
const result = await innerTube.getPlayerData(videoID);
assert.ok(partialDeepEquals(result, expected));
});
it("Should have more views than current", async () => {
const result = await innerTube.getPlayerData(videoID);
assert.ok(Number(result.viewCount) >= currentViews);
});
it("Should have the same video duration from both endpoints", async () => {
const playerData = await innerTube.getPlayerData(videoID);
const length = await innerTube.getLength(videoID);
assert.equal(Number(playerData.lengthSeconds), length);
});
it("Should have equivalent response from NewLeaf", async function () {
if (!config.newLeafURLs || config.newLeafURLs.length <= 0 || config.newLeafURLs[0] == "placeholder") this.skip();
const itResponse = await innerTube.getPlayerData(videoID);
const newLeafResponse = await YouTubeAPI.listVideos(videoID, true);
// validate videoID
assert.strictEqual(itResponse.videoId, videoID);
assert.strictEqual(newLeafResponse.data?.videoId, videoID);
// validate description
assert.strictEqual(itResponse.shortDescription, newLeafResponse.data?.description);
// validate authorId
assert.strictEqual(itResponse.channelId, newLeafResponse.data?.authorId);
});
});