Use android formats when available, web for everything else (#3715)

This commit is contained in:
absidue 2023-07-02 02:42:28 +02:00 committed by GitHub
parent 23e7041705
commit bcf21f6d44
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 21 additions and 5 deletions

View File

@ -31,10 +31,11 @@ const TRACKING_PARAM_NAMES = [
* @param {boolean} options.withPlayer set to true to get an Innertube instance that can decode the streaming URLs
* @param {string|undefined} options.location the geolocation to pass to YouTube get different content
* @param {boolean} options.safetyMode whether to hide mature content
* @param {string} options.clientType use an alterate client
* @param {import('youtubei.js').ClientType} options.clientType use an alterate client
* @param {boolean} options.generateSessionLocally generate the session locally or let YouTube generate it (local is faster, remote is more accurate)
* @returns the Innertube instance
*/
async function createInnertube(options = { withPlayer: false, location: undefined, safetyMode: false, clientType: undefined }) {
async function createInnertube(options = { withPlayer: false, location: undefined, safetyMode: false, clientType: undefined, generateSessionLocally: true }) {
let cache
if (options.withPlayer) {
const userData = await getUserDataPath()
@ -50,7 +51,7 @@ async function createInnertube(options = { withPlayer: false, location: undefine
// use browser fetch
fetch: (input, init) => fetch(input, init),
cache,
generate_session_locally: true
generate_session_locally: !!options.generateSessionLocally
})
}
@ -140,17 +141,32 @@ export async function getLocalVideoInfo(id, attemptBypass = false) {
let player
if (attemptBypass) {
const innertube = await createInnertube({ withPlayer: true, clientType: ClientType.TV_EMBEDDED })
const innertube = await createInnertube({ withPlayer: true, clientType: ClientType.TV_EMBEDDED, generateSessionLocally: false })
player = innertube.actions.session.player
// the second request that getInfo makes 404s with the bypass, so we use getBasicInfo instead
// that's fine as we have most of the information from the original getInfo request
info = await innertube.getBasicInfo(id, 'TV_EMBEDDED')
} else {
const innertube = await createInnertube({ withPlayer: true })
const innertube = await createInnertube({ withPlayer: true, generateSessionLocally: false })
player = innertube.actions.session.player
info = await innertube.getInfo(id)
// // the android streaming formats don't seem to be throttled at the moment so we use those if they are availabe
try {
const androidInnertube = await createInnertube({ clientType: ClientType.ANDROID, generateSessionLocally: false })
const androidInfo = await androidInnertube.getBasicInfo(id, 'ANDROID')
if (androidInfo.playability_status.status === 'OK') {
info.streaming_data = androidInfo.streaming_data
} else {
console.error('Failed to fetch android formats', JSON.parse(JSON.stringify(androidInfo.playability_status)))
}
} catch (error) {
console.error('Failed to fetch android formats')
console.error(error)
}
}
if (info.streaming_data) {