Open Dmytro-Tihunov opened 2 months ago
me also get 403. i tried with cloud vm and also get 403 :(
me algo get 403
MinigetError: Status code: 403
at ClientRequest.eval (webpack-internal:///(rsc)/./node_modules/miniget/dist/index.js:206:27)
at Object.onceWrapper (node:events:633:26)
at ClientRequest.emit (node:events:518:28)
at HTTPParser.parserOnIncomingClient [as onIncoming] (node:_http_client:698:27)
at HTTPParser.parserOnHeadersComplete (node:_http_common:119:17)
at TLSSocket.socketOnData (node:_http_client:540:22)
at TLSSocket.emit (node:events:518:28)
at addChunk (node:internal/streams/readable:559:12)
at readableAddChunkPushByteMode (node:internal/streams/readable:510:3)
at Readable.push (node:internal/streams/readable:390:5)
at TLSWrap.onStreamRead (node:internal/stream_base_commons:190:23)
at TLSWrap.callbackTrampoline (node:internal/async_hooks:130:17) {
statusCode: 403
} writeStream error
Same here, infinite loading..
Does anybody managed to get around it?
I tried it, but didn't manage to fix the promlem. May be did smth wrong, not sure/
me also get 403. i tried with cloud vm and also get 403 :(
i tried konsumer's solution at #1289 and it works. I don't know why it works, because when I try yt-dlp executable it returns 403 too..
look everywhere (yt-dlp, newpipe, etc) and everyone is having exactly this problem. google has dropped the ban hammer. just sit tight until some kind soul hacks this again
look everywhere (yt-dlp, newpipe, etc) and everyone is having exactly this problem. google has dropped the ban hammer. just sit tight until some kind soul hacks this again
Oh no
Does anybody managed to get around it?
I tried it, but didn't manage to fix the promlem. May be did smth wrong, not sure/
me also get 403. i tried with cloud vm and also get 403 :(
i tried konsumer's solution at #1289 and it works. I don't know why it works, because when I try yt-dlp executable it returns 403 too..
I could get the getInfo
to work well, but the output format is wildly different from ytdl-core
's ytdl.getInfo
and you cannot simply plug the output of it into ytdl.downloadFromInfo
. I haven't been able to get the fetch(video.url)
part working.
Same here.
me algo get 403
MinigetError: Status code: 403 at ClientRequest.eval (webpack-internal:///(rsc)/./node_modules/miniget/dist/index.js:206:27) at Object.onceWrapper (node:events:633:26) at ClientRequest.emit (node:events:518:28) at HTTPParser.parserOnIncomingClient [as onIncoming] (node:_http_client:698:27) at HTTPParser.parserOnHeadersComplete (node:_http_common:119:17) at TLSSocket.socketOnData (node:_http_client:540:22) at TLSSocket.emit (node:events:518:28) at addChunk (node:internal/streams/readable:559:12) at readableAddChunkPushByteMode (node:internal/streams/readable:510:3) at Readable.push (node:internal/streams/readable:390:5) at TLSWrap.onStreamRead (node:internal/stream_base_commons:190:23) at TLSWrap.callbackTrampoline (node:internal/async_hooks:130:17) { statusCode: 403 } writeStream error
Does anybody managed to get around it? I tried it, but didn't manage to fix the promlem. May be did smth wrong, not sure/
me also get 403. i tried with cloud vm and also get 403 :(
i tried konsumer's solution at #1289 and it works. I don't know why it works, because when I try yt-dlp executable it returns 403 too..
I could get the
getInfo
to work well, but the output format is wildly different fromytdl-core
'sytdl.getInfo
and you cannot simply plug the output of it intoytdl.downloadFromInfo
. I haven't been able to get thefetch(video.url)
part working.
Have you tried manually visiting URL?
Does anybody managed to get around it? I tried it, but didn't manage to fix the promlem. May be did smth wrong, not sure/
me also get 403. i tried with cloud vm and also get 403 :(
i tried konsumer's solution at #1289 and it works. I don't know why it works, because when I try yt-dlp executable it returns 403 too..
I could get the
getInfo
to work well, but the output format is wildly different fromytdl-core
'sytdl.getInfo
and you cannot simply plug the output of it intoytdl.downloadFromInfo
. I haven't been able to get thefetch(video.url)
part working.Have you tried manually visiting URL?
Yeah I did and it displays the video/audio file fine. I was able to just write my own code to then use fs.createWriteStream
to download it. If anyone else wants to try it out, here it is:
import fs from 'fs';
import { Readable } from 'stream';
type DownloadOptions = {
startTime?: number;
endTime?: number;
bitrate?: number;
outputFile?: string;
};
/**
* Downloads a specified part of an audio file from a URL.
*
* @param {string} url - The URL of the audio file.
* @param {DownloadOptions} [options] - Options for downloading the audio part.
* @returns {Promise<void>} - A promise that resolves when the download is complete.
*/
export async function downloadAudioFromUrl(
url: string,
options: DownloadOptions = {},
): Promise<void> {
const {
startTime = 0,
endTime = Infinity,
bitrate = 50548,
outputFile = `your/desired/default/path/here.mp4`,
} = options;
try {
// Convert start and end time from seconds to bytes
const startByte = Math.floor((startTime * bitrate) / 8);
const endByte = isFinite(endTime)
? Math.floor((endTime * bitrate) / 8) - 1
: '';
// Fetch the specified byte range
const response = await fetch(url, {
headers: {
Range: `bytes=${startByte}-${endByte}`,
},
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// Convert response body to a Uint8Array and then to a readable stream
const arrayBuffer = await response.arrayBuffer();
const uint8Array = new Uint8Array(arrayBuffer);
// Create a readable stream and push the data
const readableStream = new Readable({
read() {
this.push(uint8Array);
this.push(null); // Indicate the end of the stream
},
});
// Create a writable stream to save the audio part
const fileStream = fs.createWriteStream(outputFile);
// Pipe the response data to the file
readableStream.pipe(fileStream);
fileStream.on('finish', () => {
console.log('Download complete');
});
} catch (error) {
console.error('Error downloading audio part:', error);
}
}
Does anybody managed to get around it? I tried it, but didn't manage to fix the promlem. May be did smth wrong, not sure/
me also get 403. i tried with cloud vm and also get 403 :(
i tried konsumer's solution at #1289 and it works. I don't know why it works, because when I try yt-dlp executable it returns 403 too..
I could get the
getInfo
to work well, but the output format is wildly different fromytdl-core
'sytdl.getInfo
and you cannot simply plug the output of it intoytdl.downloadFromInfo
. I haven't been able to get thefetch(video.url)
part working.Have you tried manually visiting URL?
Yeah I did and it displays the video/audio file fine. I was able to just write my own code to then use
fs.createWriteStream
to download it. If anyone else wants to try it out, here it is:import fs from 'fs'; import { Readable } from 'stream'; type DownloadOptions = { startTime?: number; endTime?: number; bitrate?: number; outputFile?: string; }; /** * Downloads a specified part of an audio file from a URL. * * @param {string} url - The URL of the audio file. * @param {DownloadOptions} [options] - Options for downloading the audio part. * @returns {Promise<void>} - A promise that resolves when the download is complete. */ export async function downloadAudioFromUrl( url: string, options: DownloadOptions = {}, ): Promise<void> { const { startTime = 0, endTime = Infinity, bitrate = 50548, outputFile = `your/desired/default/path/here.mp4`, } = options; try { // Convert start and end time from seconds to bytes const startByte = Math.floor((startTime * bitrate) / 8); const endByte = isFinite(endTime) ? Math.floor((endTime * bitrate) / 8) - 1 : ''; // Fetch the specified byte range const response = await fetch(url, { headers: { Range: `bytes=${startByte}-${endByte}`, }, }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } // Convert response body to a Uint8Array and then to a readable stream const arrayBuffer = await response.arrayBuffer(); const uint8Array = new Uint8Array(arrayBuffer); // Create a readable stream and push the data const readableStream = new Readable({ read() { this.push(uint8Array); this.push(null); // Indicate the end of the stream }, }); // Create a writable stream to save the audio part const fileStream = fs.createWriteStream(outputFile); // Pipe the response data to the file readableStream.pipe(fileStream); fileStream.on('finish', () => { console.log('Download complete'); }); } catch (error) { console.error('Error downloading audio part:', error); } }
Doesn't work
Does anybody managed to get around it? I tried it, but didn't manage to fix the promlem. May be did smth wrong, not sure/
me also get 403. i tried with cloud vm and also get 403 :(
i tried konsumer's solution at #1289 and it works. I don't know why it works, because when I try yt-dlp executable it returns 403 too..
I could get the
getInfo
to work well, but the output format is wildly different fromytdl-core
'sytdl.getInfo
and you cannot simply plug the output of it intoytdl.downloadFromInfo
. I haven't been able to get thefetch(video.url)
part working.Have you tried manually visiting URL?
Yeah I did and it displays the video/audio file fine. I was able to just write my own code to then use
fs.createWriteStream
to download it. If anyone else wants to try it out, here it is:import fs from 'fs'; import { Readable } from 'stream'; type DownloadOptions = { startTime?: number; endTime?: number; bitrate?: number; outputFile?: string; }; /** * Downloads a specified part of an audio file from a URL. * * @param {string} url - The URL of the audio file. * @param {DownloadOptions} [options] - Options for downloading the audio part. * @returns {Promise<void>} - A promise that resolves when the download is complete. */ export async function downloadAudioFromUrl( url: string, options: DownloadOptions = {}, ): Promise<void> { const { startTime = 0, endTime = Infinity, bitrate = 50548, outputFile = `your/desired/default/path/here.mp4`, } = options; try { // Convert start and end time from seconds to bytes const startByte = Math.floor((startTime * bitrate) / 8); const endByte = isFinite(endTime) ? Math.floor((endTime * bitrate) / 8) - 1 : ''; // Fetch the specified byte range const response = await fetch(url, { headers: { Range: `bytes=${startByte}-${endByte}`, }, }); if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } // Convert response body to a Uint8Array and then to a readable stream const arrayBuffer = await response.arrayBuffer(); const uint8Array = new Uint8Array(arrayBuffer); // Create a readable stream and push the data const readableStream = new Readable({ read() { this.push(uint8Array); this.push(null); // Indicate the end of the stream }, }); // Create a writable stream to save the audio part const fileStream = fs.createWriteStream(outputFile); // Pipe the response data to the file readableStream.pipe(fileStream); fileStream.on('finish', () => { console.log('Download complete'); }); } catch (error) { console.error('Error downloading audio part:', error); } }
Doesn't work
const fs = require('fs');
const { Readable } = require('stream');
const { finished } = require('stream/promises');
async function getInfo(videoId) {
const apiKey = 'AIzaSyB-63vPrdThhKuerbB2N_l7Kwwcxj6yUAc'
const headers = {
'X-YouTube-Client-Name': '5',
'X-YouTube-Client-Version': '19.09.3',
Origin: 'https://www.youtube.com',
'User-Agent': 'com.google.ios.youtube/19.09.3 (iPhone14,3; U; CPU iOS 15_6 like Mac OS X)',
'content-type': 'application/json'
}
const b = {
context: {
client: {
clientName: 'IOS',
clientVersion: '19.09.3',
deviceModel: 'iPhone14,3',
userAgent: 'com.google.ios.youtube/19.09.3 (iPhone14,3; U; CPU iOS 15_6 like Mac OS X)',
hl: 'en',
timeZone: 'UTC',
utcOffsetMinutes: 0
}
},
videoId,
playbackContext: { contentPlaybackContext: { html5Preference: 'HTML5_PREF_WANTS' } },
contentCheckOk: true,
racyCheckOk: true
}
const res = await fetch(`https://www.youtube.com/youtubei/v1/player?key${apiKey}&prettyPrint=false`, { method: 'POST', body: JSON.stringify(b), headers });
// throw an error when failed to get info
if(!res.ok) throw new Error(`${res.status} ${res.statusText}`);
const json = await res.json();
return json;
}
;(async function() {
// get video info by id
const info = await getInfo('oDAw7vW7H0c');
// check playability status
if(info.playabilityStatus.status !== 'OK') throw new Error(info.playabilityStatus.reason);
// get formats
const formats = info.streamingData.adaptiveFormats;
const selectedFormat = formats[2];
const ext = selectedFormat.mimeType.match(/^\w+\/(\w+)/)[1];
// create filename for video
const filename = `${info.videoDetails.title}-${info.videoDetails.videoId}.${ext}`;
// download video
console.log(`Downloading ${filename}`);
const writer = fs.createWriteStream(filename);
const res = await fetch(selectedFormat.url);
// throw an error when failed to download
if(!res.ok) throw new Error(`${res.status} ${res.statusText}`);
// waiting for download is finished
await finished(Readable.fromWeb(res.body).pipe(writer));
console.log(`Downloaded ${filename}`);
})();
try it. it works on my machine.
@kevinrss01 try @navetacandra's code. I didn't post the full example and my code is a little bit specialized because I use it as a part of a bigger codebase and I probably missed parts that only work because of other parts of my code and I only need the audio file. His example is more versatile and has an example code as well.
@navetacandra Your code works but I don't have any sound in the video, do you have a solution?
@navetacandra I tried your code and it works, but it doesn't include audio stream.
@mitsuki31 @kevinrss01 you can just simply merge video and audio using fluent-ffmpeg. example:
const ffmpeg = require('fluent-ffmpeg');
....
;(async function() {
// get video info by id
const info = await getInfo('xvFZjo5PgG0');
// check playability status
if(info.playabilityStatus.status !== 'OK') throw new Error(info.playabilityStatus.reason);
// get formats
const formats = info.streamingData.adaptiveFormats;
const video = formats.filter(f => f.mimeType.match(/^video\/\w+/))[0];
const audio = formats.filter(f => f.mimeType.match(/^audio\/\w+/))[0];
const ext = video.mimeType.match(/^\w+\/(\w+)/)[1];
// create filename for video
const filename = `${info.videoDetails.title}-${info.videoDetails.videoId}.${ext}`;
// download video
console.log(`Downloading ${filename}`);
const tmpVideo = fs.createWriteStream('tmp_' + filename);
const videoRes = await fetch(video.url);
const audioRes = await fetch(audio.url);
// throw an error when failed to download
if(!videoRes.ok) throw new Error(`${videoRes.status} ${videoRes.statusText}`);
if(!audioRes.ok) throw new Error(`${audioRes.status} ${audioRes.statusText}`);
// download video first
await finished(Readable.fromWeb(videoRes.body).pipe(tmpVideo));
// then merge video with audio
ffmpeg()
.input('tmp_' + filename)
.input(Readable.fromWeb(audioRes.body))
.addOption(['-c:v', 'copy', '-c:a', 'aac', '-map', '0:v:0', '-map', '1:a:0', '-shortest'])
.saveToFile(filename)
.on('start', () => console.log('Merge video with audio'))
.on('end', () => {
fs.unlinkSync('tmp_' + filename);
console.log(`Downloaded ${filename}`);
});
})();
or asynchronously
const ffmpeg = require('fluent-ffmpeg');
....
// audio can be Readable stream or filepath
const mergeVideoWithAudio = (videoPath, audio, output) => {
return new Promise((resolve, reject) => {
ffmpeg()
.input(videoPath)
.input(audio)
.addOption(['-c:v', 'copy', '-c:a', 'aac', '-map', '0:v:0', '-map', '1:a:0', '-shortest'])
.save(output)
.on('start', () => console.log('Merge video with audio'))
.on('end', () => {
fs.unlinkSync(videoPath);
resolve();
})
.on('error', err => reject(err))
});
}
;(async function() {
// get video info by id
const info = await getInfo('xvFZjo5PgG0');
// check playability status
if(info.playabilityStatus.status !== 'OK') throw new Error(info.playabilityStatus.reason);
// get formats
const formats = info.streamingData.adaptiveFormats;
const video = formats.filter(f => f.mimeType.match(/^video\/\w+/))[0];
const audio = formats.filter(f => f.mimeType.match(/^audio\/\w+/))[0];
const ext = video.mimeType.match(/^\w+\/(\w+)/)[1];
// create filename for video
const filename = `${info.videoDetails.title}-${info.videoDetails.videoId}.${ext}`;
// download video
console.log(`Downloading ${filename}`);
const tmpVideo = fs.createWriteStream('tmp_' + filename);
const videoRes = await fetch(video.url);
const audioRes = await fetch(audio.url);
// throw an error when failed to download
if(!videoRes.ok) throw new Error(`${videoRes.status} ${videoRes.statusText}`);
if(!audioRes.ok) throw new Error(`${audioRes.status} ${audioRes.statusText}`);
// download video first
await finished(Readable.fromWeb(videoRes.body).pipe(tmpVideo));
// then merge video with audio
await mergeVideoWithAudio('tmp_' + filename, Readable.fromWeb(audioRes.body), filename);
console.log(`Downloaded ${filename}`);
})();
@navetacandra Thanks, it worked. Maybe it will be a good idea to use this as fallback downloader.
@navetacandra from where did you generate the api key
@sohamhaldar Google Developers Console
@navetacandra Ok thanks, btw will my youtube data api key will work here
@navetacandra from where did you generate the api key
i just put hardcoded api key from yt-dlp repo https://github.com/yt-dlp/yt-dlp/blob/master/yt_dlp/extractor/youtube.py
@navetacandra from where did you generate the api key
i just put hardcoded api key from yt-dlp repo https://github.com/yt-dlp/yt-dlp/blob/master/yt_dlp/extractor/youtube.py
Ok thanks a lot
@mitsuki31 @kevinrss01 you can just simply merge video and audio using fluent-ffmpeg. example:
const ffmpeg = require('fluent-ffmpeg'); .... ;(async function() { // get video info by id const info = await getInfo('xvFZjo5PgG0'); // check playability status if(info.playabilityStatus.status !== 'OK') throw new Error(info.playabilityStatus.reason); // get formats const formats = info.streamingData.adaptiveFormats; const video = formats.filter(f => f.mimeType.match(/^video\/\w+/))[0]; const audio = formats.filter(f => f.mimeType.match(/^audio\/\w+/))[0]; const ext = video.mimeType.match(/^\w+\/(\w+)/)[1]; // create filename for video const filename = `${info.videoDetails.title}-${info.videoDetails.videoId}.${ext}`; // download video console.log(`Downloading ${filename}`); const tmpVideo = fs.createWriteStream('tmp_' + filename); const videoRes = await fetch(video.url); const audioRes = await fetch(audio.url); // throw an error when failed to download if(!videoRes.ok) throw new Error(`${videoRes.status} ${videoRes.statusText}`); if(!audioRes.ok) throw new Error(`${audioRes.status} ${audioRes.statusText}`); // download video first await finished(Readable.fromWeb(videoRes.body).pipe(tmpVideo)); // then merge video with audio ffmpeg() .input('tmp_' + filename) .input(Readable.fromWeb(audioRes.body)) .addOption(['-c:v', 'copy', '-c:a', 'aac', '-map', '0:v:0', '-map', '1:a:0', '-shortest']) .saveToFile(filename) .on('start', () => console.log('Merge video with audio')) .on('end', () => { fs.unlinkSync('tmp_' + filename); console.log(`Downloaded ${filename}`); }); })();
or asynchronously
const ffmpeg = require('fluent-ffmpeg'); .... // audio can be Readable stream or filepath const mergeVideoWithAudio = (videoPath, audio, output) => { return new Promise((resolve, reject) => { ffmpeg() .input(videoPath) .input(audio) .addOption(['-c:v', 'copy', '-c:a', 'aac', '-map', '0:v:0', '-map', '1:a:0', '-shortest']) .save(output) .on('start', () => console.log('Merge video with audio')) .on('end', () => { fs.unlinkSync(videoPath); resolve(); }) .on('error', err => reject(err)) }); } ;(async function() { // get video info by id const info = await getInfo('xvFZjo5PgG0'); // check playability status if(info.playabilityStatus.status !== 'OK') throw new Error(info.playabilityStatus.reason); // get formats const formats = info.streamingData.adaptiveFormats; const video = formats.filter(f => f.mimeType.match(/^video\/\w+/))[0]; const audio = formats.filter(f => f.mimeType.match(/^audio\/\w+/))[0]; const ext = video.mimeType.match(/^\w+\/(\w+)/)[1]; // create filename for video const filename = `${info.videoDetails.title}-${info.videoDetails.videoId}.${ext}`; // download video console.log(`Downloading ${filename}`); const tmpVideo = fs.createWriteStream('tmp_' + filename); const videoRes = await fetch(video.url); const audioRes = await fetch(audio.url); // throw an error when failed to download if(!videoRes.ok) throw new Error(`${videoRes.status} ${videoRes.statusText}`); if(!audioRes.ok) throw new Error(`${audioRes.status} ${audioRes.statusText}`); // download video first await finished(Readable.fromWeb(videoRes.body).pipe(tmpVideo)); // then merge video with audio await mergeVideoWithAudio('tmp_' + filename, Readable.fromWeb(audioRes.body), filename); console.log(`Downloaded ${filename}`); })();
Downloading speed is very poor for the above code.
@mitsuki31 @kevinrss01 you can just simply merge video and audio using fluent-ffmpeg. example:
const ffmpeg = require('fluent-ffmpeg'); .... ;(async function() { // get video info by id const info = await getInfo('xvFZjo5PgG0'); // check playability status if(info.playabilityStatus.status !== 'OK') throw new Error(info.playabilityStatus.reason); // get formats const formats = info.streamingData.adaptiveFormats; const video = formats.filter(f => f.mimeType.match(/^video\/\w+/))[0]; const audio = formats.filter(f => f.mimeType.match(/^audio\/\w+/))[0]; const ext = video.mimeType.match(/^\w+\/(\w+)/)[1]; // create filename for video const filename = `${info.videoDetails.title}-${info.videoDetails.videoId}.${ext}`; // download video console.log(`Downloading ${filename}`); const tmpVideo = fs.createWriteStream('tmp_' + filename); const videoRes = await fetch(video.url); const audioRes = await fetch(audio.url); // throw an error when failed to download if(!videoRes.ok) throw new Error(`${videoRes.status} ${videoRes.statusText}`); if(!audioRes.ok) throw new Error(`${audioRes.status} ${audioRes.statusText}`); // download video first await finished(Readable.fromWeb(videoRes.body).pipe(tmpVideo)); // then merge video with audio ffmpeg() .input('tmp_' + filename) .input(Readable.fromWeb(audioRes.body)) .addOption(['-c:v', 'copy', '-c:a', 'aac', '-map', '0:v:0', '-map', '1:a:0', '-shortest']) .saveToFile(filename) .on('start', () => console.log('Merge video with audio')) .on('end', () => { fs.unlinkSync('tmp_' + filename); console.log(`Downloaded ${filename}`); }); })();
or asynchronously
const ffmpeg = require('fluent-ffmpeg'); .... // audio can be Readable stream or filepath const mergeVideoWithAudio = (videoPath, audio, output) => { return new Promise((resolve, reject) => { ffmpeg() .input(videoPath) .input(audio) .addOption(['-c:v', 'copy', '-c:a', 'aac', '-map', '0:v:0', '-map', '1:a:0', '-shortest']) .save(output) .on('start', () => console.log('Merge video with audio')) .on('end', () => { fs.unlinkSync(videoPath); resolve(); }) .on('error', err => reject(err)) }); } ;(async function() { // get video info by id const info = await getInfo('xvFZjo5PgG0'); // check playability status if(info.playabilityStatus.status !== 'OK') throw new Error(info.playabilityStatus.reason); // get formats const formats = info.streamingData.adaptiveFormats; const video = formats.filter(f => f.mimeType.match(/^video\/\w+/))[0]; const audio = formats.filter(f => f.mimeType.match(/^audio\/\w+/))[0]; const ext = video.mimeType.match(/^\w+\/(\w+)/)[1]; // create filename for video const filename = `${info.videoDetails.title}-${info.videoDetails.videoId}.${ext}`; // download video console.log(`Downloading ${filename}`); const tmpVideo = fs.createWriteStream('tmp_' + filename); const videoRes = await fetch(video.url); const audioRes = await fetch(audio.url); // throw an error when failed to download if(!videoRes.ok) throw new Error(`${videoRes.status} ${videoRes.statusText}`); if(!audioRes.ok) throw new Error(`${audioRes.status} ${audioRes.statusText}`); // download video first await finished(Readable.fromWeb(videoRes.body).pipe(tmpVideo)); // then merge video with audio await mergeVideoWithAudio('tmp_' + filename, Readable.fromWeb(audioRes.body), filename); console.log(`Downloaded ${filename}`); })();
Downloading speed is very poor for the above code.
Yes. It is because you must download video and audio instead of only downloading video or audio.
I use this package for making music blob data, is it possible?
seems like folks at distubejs just slapped a fix: https://github.com/distubejs/ytdl-core/commit/3df824e57fe4ce3037a91efd124b729dea38c01f also strictly for my purposes, youtubei still works just fine. just FYI
seems like folks at distubejs just slapped a fix: distubejs@3df824e also strictly for my purposes, youtubei still works just fine. just FYI
when node-ytdl-core will slap a fix??
when node-ytdl-core will slap a fix??
Just install @distubejs/ytdl-core and in your files change const ytdl = require("ytdl-core");
to const ytdl = require("@distube/ytdl-core");
This worked for me!
Just install @distubejs/ytdl-core and in your files change
const ytdl = require("ytdl-core");
toconst ytdl = require("@distube/ytdl-core");
This worked for me!
@bendaacz your forked package branch is behind with x number of commits i am wondering if i use require("@distube/ytdl-core") something else could break.
something else could break.
YOLO! Just try it in dev mode, no? Everything works so far.
@bendaacz it works on dev mode.
when node-ytdl-core will slap a fix??
Just install @distubejs/ytdl-core and in your files change
const ytdl = require("ytdl-core");
toconst ytdl = require("@distube/ytdl-core");
This worked for me!
Thank you very much, it worked for me, I switched to this library (which is a fork of the current package) and it worked again.
Muito obrigado, funcionou para mim, fiz a troca para essa biblioteca (Que é um fork do package atual) e voltou a funcionar. Code:
// const ytdl = require('ytdl-core');
const ytdl = require('@distube/ytdl-core');
let stream = ytdl(url, {
quality: 'highestaudio',
format: 'mp3',
highWaterMark: 1 << 30,
liveBuffer: 1 << 30,
})
.on('error', erro => {
downloadSucess = undefined;
console.error(erro)
});
ffmpeg(stream)
.audioBitrate(96)
.audioChannels(1)
.format('mp3')
.save(`${__dirname}/midias/audio/${nameVideo}.mp3`)
.on('error', erro => {
downloadSucess = undefined;
console.error(erro)
})
.on('end', () => {
downloadSucess = true;
})
same performance
i digged in a bit deeper and the ntransform function has failed to extract. the best course of action is to switch to distube's branch. unfortunately i failed to adapt the distube branch myself so i'm stuck at the upstream branch, but copying distube's ntranform extraction logic seems to resolve this issue, just FYI https://github.com/lovegaoshi/rn-ytdl-core/commit/55d73611d3bd42050ae3f42c067d682518a83c59
change dependency to @distube/ytdl-core
works
this is the reason why I use both ytdl and ytdlp in my bot
when node-ytdl-core will slap a fix??
Just install @distubejs/ytdl-core and in your files change
const ytdl = require("ytdl-core");
toconst ytdl = require("@distube/ytdl-core");
This worked for me!Thank you very much, it worked for me, I switched to this library (which is a fork of the current package) and it worked again.
Muito obrigado, funcionou para mim, fiz a troca para essa biblioteca (Que é um fork do package atual) e voltou a funcionar. Code:
// const ytdl = require('ytdl-core'); const ytdl = require('@distube/ytdl-core'); let stream = ytdl(url, { quality: 'highestaudio', format: 'mp3', highWaterMark: 1 << 30, liveBuffer: 1 << 30, }) .on('error', erro => { downloadSucess = undefined; console.error(erro) }); ffmpeg(stream) .audioBitrate(96) .audioChannels(1) .format('mp3') .save(`${__dirname}/midias/audio/${nameVideo}.mp3`) .on('error', erro => { downloadSucess = undefined; console.error(erro) }) .on('end', () => { downloadSucess = true; })
same performance:
I am simply starting node in ssh and I type these commands one by one:
const ytdl = require("ytdl-core");
await ytdl.getBasicInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ")
Returns:
Uncaught UnrecoverableError: This video is unavailable at exports.playError (/root/project/node_modules/@distube/ytdl-core/lib/utils.js:164:12) at exports.getBasicInfo (/root/project/node_modules/@distube/ytdl-core/lib/info.js:52:25) at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Happens for every video.
I am simply starting node in ssh and I type these commands one by one:
const ytdl = require("ytdl-core");
await ytdl.getBasicInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ")
Returns:
Uncaught UnrecoverableError: This video is unavailable at exports.playError (/root/project/node_modules/@distube/ytdl-core/lib/utils.js:164:12) at exports.getBasicInfo (/root/project/node_modules/@distube/ytdl-core/lib/info.js:52:25) at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Happens for every video.
Environment
- ytdl-core version: 4.11.5
- Node.js version: v20.3.1
- Operating system: Ubuntu 24.04
Did you mean to use require('@distube/ytdl-core')
? Because your error message refers to different module.
And also, I tried your code with ytdl-core
module with version the same as yours (v4.11.5), and it works just fine.
I am simply starting node in ssh and I type these commands one by one:
const ytdl = require("ytdl-core");
await ytdl.getBasicInfo("http://www.youtube.com/watch?v=aqz-KE-bpKQ")
Returns:
Uncaught UnrecoverableError: This video is unavailable at exports.playError (/root/project/node_modules/@distube/ytdl-core/lib/utils.js:164:12) at exports.getBasicInfo (/root/project/node_modules/@distube/ytdl-core/lib/info.js:52:25) at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
Happens for every video.
Environment
- ytdl-core version: 4.11.5
- Node.js version: v20.3.1
- Operating system: Ubuntu 24.04
Did you mean to use
require('@distube/ytdl-core')
? Because your error message refers to different module.And also, I tried your code with
ytdl-core
module with version the same as yours (v4.11.5), and it works just fine.
Well, no, it refers to a different module but it happens with ytdl-core and with @distube/ytdl-core too. Can it be a Ubuntu 24.04 issue?
I have big latency when recovering the video with distube/ytdl-core
. Do people have the same?
I have big latency when recovering the video with
distube/ytdl-core
. Do people have the same?
Nope, I'm fine using @distube/ytdl-core
I have big latency when recovering the video with
distube/ytdl-core
. Do people have the same?Nope, I'm fine using
@distube/ytdl-core
Ca n you show what params you are using ? I'm using:
const info = await ytdl.getInfo(link);
const format = ytdl.chooseFormat(info.formats, {
quality: "highest",
filter: "videoonly",
});
return new Promise((resolve, reject) => {
ytdl
.downloadFromInfo(info, { format: format })
.pipe(outputStream)
.on('finish', () => {
resolve(outputFilePath);
console.debug('Video or audio saved.');
})
.on('error', (err) => {
console.error(err);
reject(err);
});
});
I have big latency when recovering the video with
distube/ytdl-core
. Do people have the same?Nope, I'm fine using
@distube/ytdl-core
Ca n you show what params you are using ? I'm using:
const info = await ytdl.getInfo(link); const format = ytdl.chooseFormat(info.formats, { quality: "highest", filter: "videoonly", }); return new Promise((resolve, reject) => { ytdl .downloadFromInfo(info, { format: format }) .pipe(outputStream) .on('finish', () => { resolve(outputFilePath); console.debug('Video or audio saved.'); }) .on('error', (err) => { console.error(err); reject(err); }); });
I've customized cookie, highwatermark and Chunk size, and I use it for streaming since ytdlp
is better in downloading files.
Below is the section that I use in the discord bot, I preserve ytdlp version too in case ytdl-core is dead again.
Keep in mind that this use @distube/ytdl-core
//YTDLP
//var audio_stream = this.createYTDLPStream(url);
//ytdl
var audio_stream = ytdl(url, {
filter: "audioonly",
//liveBuffer: 2000,
highWaterMark: 16384,
dlChunkSize: 65536,
quality: 'highestaudio',
//begin: BT,
requestOptions: {
headers: {
cookie: YT_COOKIE,
// Optional. If not given, ytdl-core will try to find it.
// You can find this by going to a video's watch page, viewing the source,
// and searching for "ID_TOKEN".
// 'x-youtube-identity-token': 1324,
},
},
});
this.playAudioResauce(this.wrapStreamToResauce(audio_stream, begin_t));
I confirm https://www.npmjs.com/package/@distube/ytdl-core works fine. Just switched.
Yes, it works =) thanks guys
I don't think we should close this issue since the fix is installing another fork.
still have this bug, switch for https://www.npmjs.com/package/@distube/ytdl-core works nice.
as I understand we all faced with new problem that is "Sign in to confirm you’re not a bot" and that means youtube asks for captcha, is there anybody who find solution?
@Brendon3578 based on @distubejs I was able to make this patch to lib/sig.js
:
https://github.com/fent/node-ytdl-core/issues/1305#issuecomment-2253373635
I am not getting the "Sign in to confirm you’re not a bot" error that @Dmytro-Tihunov has mentioned. So this may not be the only issue.
@corwin-of-amber have you tried in production ?
@Dmytro-Tihunov What do you mean by "production"?
I have patched the file in my node_modules/
directory, then ran these lines in node
:
ytdl = require('ytdl-core');
ytdl('https://www.youtube.com/watch?v=8gWFUuSCWk8').pipe(fs.createWriteStream('/tmp/out.mp4'))
and I got the file. This is on my local machine. Nothing fancy.
Hey guys! it stopped working we need an update :)