Open Elite opened 4 days ago
Hi again.
What you're asking to do seems simple enough.
Most (all?) videos already have audio-only streams in "audio/mp4" format (using an mp4a.40.2
codec),
which ffmpeg
can resample to mp3.
The only trouble that I see is.. the browser-ytdl-core
library doesn't seem ready for a production release.
I've since updated my Youtube userscript and have made a troubling observation..
although true for any video, I'll use this video as an example..
only "itag: 18" currently works..
all other streams still return a 403 status..
and this includes the "audio/mp4" stream.
Something is still very hinky in the upstream library.. probably relating to the same regex pattern(s) that the pending PR is touching.
And I should probably warn you.. that this library is a moving target.. even if they do get everything working again for right now.. the next time Youtube makes the slightest change to their website.. then everything will stop working again, until the library can be updates to make the necessary adjustments. So, if you build something on a shaky foundation like this.. just be aware that it will inevitably require constant upkeep.. and will periodically break.
Have you seen this https://github.com/LuanRT/YouTube.js
I have, but..
that's entirely unrelated to ytdl-core
..
in the sense that neither project is dependent upon the other.
If you're suggesting/asking whether this other library could be used in a userscript instead of ytdl-core
, then my answer would be.. maybe? I haven't tried, though they do claim that it works in a browser environment.
update: a quick glance at their documentation says otherwise:
To use YouTube.js in the browser, you must proxy requests through your own server.
ffmpeg
wasm:https://ffmpegwasm.netlify.app/docs/getting-started/usage#transcode-webm-to-mp4-video
https://ffmpegwasm.netlify.app/docs/getting-started/examples/ https://github.com/ffmpegwasm/ffmpeg.wasm/tree/main/apps/vanilla-app https://github.com/ffmpegwasm/ffmpeg.wasm/blob/main/apps/vanilla-app/public/transcode.html
https://www.jsdelivr.com/package/npm/@ffmpeg/core https://cdn.jsdelivr.net/npm/@ffmpeg/core/ https://cdn.jsdelivr.net/npm/@ffmpeg/core@0.12.6/dist/umd/ffmpeg-core.js https://cdn.jsdelivr.net/npm/@ffmpeg/core@0.12.6/dist/umd/ffmpeg-core.wasm
https://www.jsdelivr.com/package/npm/@ffmpeg/ffmpeg https://cdn.jsdelivr.net/npm/@ffmpeg/ffmpeg/ https://cdn.jsdelivr.net/npm/@ffmpeg/ffmpeg@0.12.10/dist/umd/ffmpeg.js
https://www.jsdelivr.com/package/npm/@ffmpeg/util https://cdn.jsdelivr.net/npm/@ffmpeg/util/ https://cdn.jsdelivr.net/npm/@ffmpeg/util@0.12.1/dist/umd/index.js
https://ffmpegwasm.netlify.app/docs/api/ffmpeg/classes/FFmpeg
I haven't tried it yet, but this should work https://github.com/ybd-project-ver1/ytdl-core/issues/31. Additionally, what we need to do is send API requests to the Innertube API with client data, such as "web." The reason other downloaders are experiencing issues is that they operate server-side, whereas we are browser-side and can extract the poToken value directly from the browser. This should make implementation fairly simple.
I had took help of Claude AI and was able to extract potoken using something like this (lost track of the original script):
// Function to wait for a specified time
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
// Function to wait for a network request
const waitForRequest = (urlPattern, timeout = 30000) => {
return new Promise((resolve, reject) => {
const originalFetch = window.fetch;
const timeoutId = setTimeout(() => {
window.fetch = originalFetch;
reject(new Error(`Timeout waiting for request: ${urlPattern}`));
}, timeout);
window.fetch = function(...args) {
const result = originalFetch.apply(this, args);
if (args[0].includes(urlPattern)) {
clearTimeout(timeoutId);
window.fetch = originalFetch;
resolve(result);
}
return result;
};
});
};
// Main function
async function main() {
console.log("[INFO] Starting automation.");
// Check if we're already on the correct page
if (!window.location.href.includes('youtube.com/embed/jNQXAC9IVRw')) {
console.log("[INFO] Navigating to the correct page.");
localStorage.setItem('runYouTubeScript', 'true');
window.location.href = 'https://www.youtube.com/embed/jNQXAC9IVRw';
return; // Exit the function, it will be called again after navigation
}
console.log("[INFO] On the correct page. Proceeding with automation.");
localStorage.removeItem('runYouTubeScript');
// Wait for the page to load
await sleep(5000);
console.log("[INFO] Waited 5 seconds for page load.");
// Click the play button
const buttonPlay = document.querySelector("#movie_player");
if (buttonPlay) {
buttonPlay.click();
console.log("[INFO] Play button clicked.");
} else {
console.error("[ERROR] Play button not found.");
return;
}
// Wait for the player request
console.log("[INFO] Waiting for player request.");
try {
const response = await waitForRequest('/youtubei/v1/player');
const data = await response.json();
// Extract and log the required information
console.log("visitor_data: " + data.context.client.visitorData);
console.log("po_token: " + data.serviceIntegrityDimensions.poToken);
} catch (error) {
console.error("[ERROR] Failed to intercept player request:", error);
}
console.log("[INFO] Automation completed.");
}
// Check if we should run the script
if (localStorage.getItem('runYouTubeScript') === 'true' || window.location.href.includes('youtube.com/embed/jNQXAC9IVRw')) {
console.log("[INFO] Conditions met, running main function.");
main().catch(error => console.error("[ERROR] An error occurred in the main function:", error));
} else {
console.log("[INFO] Conditions not met, script not running automatically.");
console.log("[INFO] To run the script manually, call main() in the console.");
}```
quick status update..
ffmpeg.wasm
was a major pain to get to work.."itag": 18
format
quick update regarding Tampermonkey in Chrome..
chrome://extensions
to enable developer mode
- merely including the .wasm as a resource prevents the script from running in Chrome
Maybe search for SharedArray buffer issue
Hi Warren,
Hope you remember me (https://github.com/warren-bank/browser-ytdl-core/issues/1#issue-2580249130), I am a rookie with browser scripts and would love if you can get me the following done for a paid task.
I need to create a simple web extension (Manifest V3) that utilizes your browser-ytdl-core library. The goal is to patch it with ffmpeg.js to enable MP3 audio conversion directly in the browser. The web extension should display a dropdown menu on the YouTube page, providing users with an option to download audio as an MP3 file. I would be happy to pay for your time, hope it suites my limited budget for this :)
Thank you for considering this!
Thanks