Comparing version 0.0.28 to 0.0.29
@@ -65,2 +65,3 @@ export declare const DEBUG = false; | ||
export declare const ENDPOINT_SEARCH_SUGGEST = "https://clients1.google.com/complete/search"; | ||
export declare const ENDPOINT_WATCHPAGE = "https://www.youtube.com/watch"; | ||
export declare const ERROR_DATA_INVALID_FORMAT: Error; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ERROR_DATA_INVALID_FORMAT = exports.ENDPOINT_SEARCH_SUGGEST = exports.ENDPOINT_COMMENT_CREATE = exports.ENDPOINT_PLAYER = exports.ENDPOINT_COMMENT_ACTION = exports.ENDPOINT_NEXT = exports.ENDPOINT_ADDTOPLAYLIST = exports.ENDPOINT_UNSUBSCRIBE = exports.ENDPOINT_SUBSCRIBE = exports.ENDPOINT_REMOVELIKE = exports.ENDPOINT_DISLIKE = exports.ENDPOINT_LIKE = exports.ENDPOINT_SEARCH = exports.ENDPOINT_BROWSE = exports.CONSOLE_COLORS = exports.DEFAULT_CONTEXT = exports.DEFAULT_USER_AGENT = exports.DEFAULT_CLIENT_NAME = exports.DEFAULT_CLIENT_VERSION = exports.DEFAULT_API_KEY = exports.DEBUG = void 0; | ||
exports.ERROR_DATA_INVALID_FORMAT = exports.ENDPOINT_WATCHPAGE = exports.ENDPOINT_SEARCH_SUGGEST = exports.ENDPOINT_COMMENT_CREATE = exports.ENDPOINT_PLAYER = exports.ENDPOINT_COMMENT_ACTION = exports.ENDPOINT_NEXT = exports.ENDPOINT_ADDTOPLAYLIST = exports.ENDPOINT_UNSUBSCRIBE = exports.ENDPOINT_SUBSCRIBE = exports.ENDPOINT_REMOVELIKE = exports.ENDPOINT_DISLIKE = exports.ENDPOINT_LIKE = exports.ENDPOINT_SEARCH = exports.ENDPOINT_BROWSE = exports.CONSOLE_COLORS = exports.DEFAULT_CONTEXT = exports.DEFAULT_USER_AGENT = exports.DEFAULT_CLIENT_NAME = exports.DEFAULT_CLIENT_VERSION = exports.DEFAULT_API_KEY = exports.DEBUG = void 0; | ||
exports.DEBUG = false; | ||
@@ -68,2 +68,3 @@ exports.DEFAULT_API_KEY = "AIzaSyAO_FJ2SlqU8Q4STEHLGCilw_Y9_11qcW8"; | ||
exports.ENDPOINT_SEARCH_SUGGEST = "https://clients1.google.com/complete/search"; | ||
exports.ENDPOINT_WATCHPAGE = "https://www.youtube.com/watch"; | ||
exports.ERROR_DATA_INVALID_FORMAT = new Error("The Data recieved from the Google API seems to have an invalid format. It might be that Google updated their APIs and this Method no longer Works"); |
@@ -1,2 +0,2 @@ | ||
import { CommentSectionContinuatedList, ContinuatedList, WrappedHTTPClient, Channel, Thumbnail, CaptionTrack, CommentThread } from "../main"; | ||
import { CommentSectionContinuatedList, ContinuatedList, WrappedHTTPClient, Channel, Thumbnail, CaptionTrack, CommentThread, Format } from "../main"; | ||
export declare class Video { | ||
@@ -24,2 +24,3 @@ videoId?: any; | ||
commentThreadList?: CommentSectionContinuatedList; | ||
formats?: Array<Format>; | ||
httpclient: WrappedHTTPClient; | ||
@@ -33,2 +34,3 @@ error: boolean; | ||
loadAll(): Promise<void>; | ||
loadFormats(): Promise<void>; | ||
getCommentThreadList(): Promise<ContinuatedList | undefined>; | ||
@@ -35,0 +37,0 @@ like(): Promise<boolean>; |
@@ -17,2 +17,3 @@ "use strict"; | ||
const HTTPClient_1 = require("./HTTPClient"); | ||
const formatsChipher_1 = require("../formatsChipher"); | ||
class Video { | ||
@@ -184,2 +185,67 @@ constructor(httpclient) { | ||
} | ||
loadFormats() { | ||
return __awaiter(this, void 0, void 0, function* () { | ||
const playerResponse = yield this.httpclient.request({ | ||
method: HTTPClient_1.HTTPRequestMethod.POST, | ||
url: constants_1.ENDPOINT_PLAYER, | ||
data: { | ||
videoId: this.videoId, | ||
racyCheckOk: false, | ||
contentCheckOk: false, | ||
playbackContext: { | ||
contentPlaybackContent: { | ||
currentUrl: "/watch?v=6Dh-RL__uN4", | ||
autonavState: "STATE_OFF", | ||
autoCaptionsDefaultOn: false, | ||
html5Preference: "HTML5_PREF_WANTS", | ||
lactMilliseconds: "-1", | ||
referer: "https://www.youtube.com/", | ||
signatureTimestamp: 19095, | ||
splay: false, | ||
vis: 0 | ||
} | ||
} | ||
} | ||
}); | ||
const playerJSON = yield JSON.parse(playerResponse.data); | ||
const formats = helpers_1.default.recursiveSearchForKey("adaptiveFormats", playerJSON)[0]; | ||
const watchURL = new URL(constants_1.ENDPOINT_WATCHPAGE); | ||
watchURL.searchParams.set("v", this.videoId); | ||
const playPage = yield this.httpclient.request({ | ||
method: HTTPClient_1.HTTPRequestMethod.GET, | ||
url: watchURL.toString() | ||
}); | ||
const html = playPage.data; | ||
let playerScript = /<script\s+src="([^"]+)"(?:\s+type="text\/javascript")?\s+name="player_ias\/base"\s*>|"jsUrl":"([^"]+)"/.exec(html); | ||
playerScript = playerScript[2] || playerScript[1]; | ||
const playerURLString = new URL(playerScript, watchURL).href; | ||
const cipher = new formatsChipher_1.CiphService(this.httpclient); | ||
const resolvedFormats = yield cipher.decipherFormats(formats, playerURLString, {}); | ||
this.formats = []; | ||
resolvedFormats.forEach((a) => { | ||
var _a; | ||
var parsedFormat = { | ||
type: a.audioChannels ? "AUDIO" : "VIDEO", | ||
itag: a.itag, | ||
url: a.url, | ||
mime: a.mimeType, | ||
quality: a.quality, | ||
bitrate: a.bitrate, | ||
averageBitrate: a.averageBitrate | ||
}; | ||
if (parsedFormat.type == 'VIDEO') { | ||
parsedFormat.qualityLabel = a.qualityLabel; | ||
parsedFormat.fps = a.fps; | ||
parsedFormat.height = a.height; | ||
parsedFormat.width = a.width; | ||
} | ||
else { | ||
parsedFormat.audioChannels = a.audioChannels; | ||
parsedFormat.loudness = a.loudnessDb; | ||
parsedFormat.audioSampleRate = a.audioSampleRate; | ||
} | ||
(_a = this.formats) === null || _a === void 0 ? void 0 : _a.push(parsedFormat); | ||
}); | ||
}); | ||
} | ||
getCommentThreadList() { | ||
@@ -186,0 +252,0 @@ return __awaiter(this, void 0, void 0, function* () { |
@@ -20,2 +20,3 @@ import { Explorer } from "./fetchers/Explorer"; | ||
import { SearchProposal } from "./interfaces/SearchProposal"; | ||
import { Format } from "./interfaces/Format"; | ||
import { default as IYoutube } from "./IYoutube"; | ||
@@ -42,2 +43,3 @@ export { IYoutube as IYoutube }; | ||
export { SearchProposal as SearchProposal }; | ||
export { Format as Format }; | ||
export declare const nodeDefault: () => Promise<IYoutube>; |
{ | ||
"name": "iyoutube", | ||
"version": "0.0.28", | ||
"version": "0.0.29", | ||
"description": "The ultimate unofficial YouTube API Client for Javascript", | ||
@@ -5,0 +5,0 @@ "main": "output/main.js", |
@@ -37,2 +37,3 @@ <h1 align="center">IYoutube</h1> | ||
- Google for their API and Chrome Dev Tools to analyse it :) | ||
- @appit-online for the Deciphering Code (from: https://github.com/appit-online/ionic-youtube-streams) | ||
@@ -39,0 +40,0 @@ #### Disclaimers |
@@ -69,4 +69,5 @@ export const DEBUG = false; | ||
export const ENDPOINT_SEARCH_SUGGEST = "https://clients1.google.com/complete/search"; | ||
export const ENDPOINT_WATCHPAGE = "https://www.youtube.com/watch"; | ||
/* Error */ | ||
export const ERROR_DATA_INVALID_FORMAT = new Error("The Data recieved from the Google API seems to have an invalid format. It might be that Google updated their APIs and this Method no longer Works"); |
@@ -1,5 +0,6 @@ | ||
import { ENDPOINT_COMMENT_CREATE, ENDPOINT_DISLIKE, ENDPOINT_LIKE, ENDPOINT_NEXT, ENDPOINT_PLAYER, ENDPOINT_REMOVELIKE } from "../constants"; | ||
import { ENDPOINT_COMMENT_CREATE, ENDPOINT_DISLIKE, ENDPOINT_LIKE, ENDPOINT_NEXT, ENDPOINT_PLAYER, ENDPOINT_REMOVELIKE, ENDPOINT_WATCHPAGE } from "../constants"; | ||
import helpers from "../fetchers/helpers"; | ||
import { CommentSectionContinuatedList, ContinuatedList, WrappedHTTPClient, Channel, Thumbnail, CaptionTrack, CommentThread } from "../main"; | ||
import { CommentSectionContinuatedList, ContinuatedList, WrappedHTTPClient, Channel, Thumbnail, CaptionTrack, CommentThread, Format } from "../main"; | ||
import { HTTPRequestMethod } from "./HTTPClient"; | ||
import { CiphService } from "../formatsChipher"; | ||
@@ -29,2 +30,3 @@ export class Video { | ||
commentThreadList?: CommentSectionContinuatedList; | ||
formats?: Array<Format> | ||
@@ -234,5 +236,73 @@ httpclient: WrappedHTTPClient; | ||
} | ||
//TODO: Video Formats | ||
} | ||
async loadFormats() { | ||
const playerResponse = await this.httpclient.request({ | ||
method: HTTPRequestMethod.POST, | ||
url: ENDPOINT_PLAYER, | ||
data: { | ||
videoId: this.videoId, | ||
racyCheckOk: false, | ||
contentCheckOk: false, | ||
playbackContext: { | ||
contentPlaybackContent: { | ||
currentUrl: "/watch?v=6Dh-RL__uN4", | ||
autonavState: "STATE_OFF", | ||
autoCaptionsDefaultOn: false, | ||
html5Preference: "HTML5_PREF_WANTS", | ||
lactMilliseconds: "-1", | ||
referer: "https://www.youtube.com/", | ||
signatureTimestamp: 19095, | ||
splay: false, | ||
vis: 0 | ||
} | ||
} | ||
} | ||
}); | ||
const playerJSON = await JSON.parse(playerResponse.data); | ||
const formats = helpers.recursiveSearchForKey("adaptiveFormats", playerJSON)[0]; | ||
const watchURL = new URL(ENDPOINT_WATCHPAGE); | ||
watchURL.searchParams.set("v", this.videoId); | ||
const playPage = await this.httpclient.request({ | ||
method: HTTPRequestMethod.GET, | ||
url: watchURL.toString() | ||
}); | ||
const html = playPage.data; | ||
let playerScript:any = /<script\s+src="([^"]+)"(?:\s+type="text\/javascript")?\s+name="player_ias\/base"\s*>|"jsUrl":"([^"]+)"/.exec(html); | ||
playerScript = playerScript[2] || playerScript[1]; | ||
const playerURLString = new URL(playerScript, watchURL).href; | ||
const cipher = new CiphService(this.httpclient); | ||
const resolvedFormats = await cipher.decipherFormats(formats, playerURLString, {}); | ||
this.formats = []; | ||
resolvedFormats.forEach((a:any) => { | ||
var parsedFormat:Format = { | ||
type: a.audioChannels ? "AUDIO" : "VIDEO", | ||
itag: a.itag, | ||
url: a.url, | ||
mime: a.mimeType, | ||
quality: a.quality, | ||
bitrate: a.bitrate, | ||
averageBitrate: a.averageBitrate | ||
} | ||
if(parsedFormat.type == 'VIDEO') { | ||
parsedFormat.qualityLabel = a.qualityLabel; | ||
parsedFormat.fps = a.fps; | ||
parsedFormat.height = a.height; | ||
parsedFormat.width = a.width; | ||
} else { | ||
parsedFormat.audioChannels = a.audioChannels; | ||
parsedFormat.loudness = a.loudnessDb; | ||
parsedFormat.audioSampleRate = a.audioSampleRate; | ||
} | ||
this.formats?.push(parsedFormat); | ||
}); | ||
} | ||
async getCommentThreadList():Promise<ContinuatedList | undefined> { | ||
@@ -239,0 +309,0 @@ if(!this.commentThreadList) { |
@@ -20,2 +20,3 @@ import { Explorer } from "./fetchers/Explorer"; | ||
import { SearchProposal } from "./interfaces/SearchProposal"; | ||
import { Format } from "./interfaces/Format"; | ||
import { default as IYoutube } from "./IYoutube"; | ||
@@ -46,2 +47,3 @@ | ||
export { SearchProposal as SearchProposal } | ||
export { Format as Format } | ||
@@ -48,0 +50,0 @@ //Skips Webpack checks |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
245203
109
5038
44