LuanRT / YouTube.js

A wrapper around YouTube's internal API — reverse engineering InnerTube
https://www.npmjs.com/package/youtubei.js
MIT License
3.48k stars 219 forks source link

Streaming URLs failing due to PoToken experiment #724

Open rustynail1984 opened 1 month ago

rustynail1984 commented 1 month ago

Hi,

i want to report that all extracted googlevideo urls using WEB Client (Encrypted and non encrypted videos) respoding with 403 error.

I guess its the nsig again.

Can someone confirm this?

Thanks.

LuanRT commented 1 month ago

Unfortunately no, it's more complicated than that. This is due to YouTube expecting you to pass in a PoToken.

See #708.

rustynail1984 commented 1 month ago

Unfortunately no, it's more complicated than that. This is due to YouTube expecting you to pass in a PoToken.

See #708.

I pass a poToken and visitor data in the player API request. It has worked fine for two days now. But since few hours all extracted googlevideo urls responding with 403 error.

Edit: ohhh i see now.. it expect a pot parameter in the googlevideo urls with the poToken value

Edit2: After adding pot parameter to the googlevideo streaming urls it works for the most videos. i renewing the poToken and visitorData all 2 hours automatically with my puppeteer script.

RatWasHere commented 1 month ago

@rustynail1984 would you mind sharing your puppeteer script?

retrouser955 commented 1 month ago

@RatWasHere this is my puppeteer script modelled after iv-org's trusted session generator

You modify this code by using the promise API to wait for the poToken to be intercepted.

import puppeteer from "puppeteer";

const browser = await puppeteer.launch({
    headless: false
})

// start scraping youtube!
const page = await browser.newPage()

// laymen's terms: Turn on chrome dev tools
const client = await page.createCDPSession();
await client.send('Debugger.enable');
await client.send('Debugger.setAsyncCallStackDepth', { maxDepth: 32 });
await client.send('Network.enable');

// Intercept requestWillBeSent from the dev tools
client.on("Network.requestWillBeSent", (e) => {
    if(e.request.url.includes("/youtubei/v1/player")) {
        const jsonData = JSON.parse(e.request.postData)

        // Extractor PO Token and visitor data
        console.log(`PO TOKEN: ${jsonData["serviceIntegrityDimensions"]["poToken"]}`)
        console.log(`VISITOR DATA: ${jsonData["context"]["client"]["visitorData"]}`)

        browser.close()
    }
})
// Go to a YouTube embed
await page.goto("https://www.youtube.com/embed/jNQXAC9IVRw", {
    waitUntil: "networkidle2"
})

// Start playing the video
const playButton = await page.$("#movie_player")

await playButton.click()
Elite commented 1 month ago

@retrouser955 Do you need to be logged in for a valid PO token?

retrouser955 commented 1 month ago

@Elite I don't believe so.

rogerpadilla commented 2 weeks ago

@Elite i think the script above that uses pptr doesn't work properly in remote servers but the BgUtils script from LuanRT works fine.