node-ytdl-core
node-ytdl-core copied to clipboard
Caught exception: Error: Video unavailable
Caught exception: Error: Video unavailable
I have no idea why this is happening, I also checked all the issues and no one has had this issue
Caught exception: Error: Video unavailable
at Object.exports.playError (Z:\Personal\repos\RedactedProjectName\node_modules\ytdl-core\lib\utils.js:124:12)
at validate (Z:\Personal\repos\RedactedProjectName\node_modules\ytdl-core\lib\info.js:53:25)
at pipeline (Z:\Personal\repos\RedactedProjectName\node_modules\ytdl-core\lib\info.js:175:11)
at processTicksAndRejections (node:internal/process/task_queues:94:5)
at async exports.getBasicInfo (Z:\Personal\repos\RedactedProjectName\node_modules\ytdl-core\lib\info.js:62:14)
this is the code that has been used
url = the video url id = randomly generated id so I can retrieve the video later on (not relevant to the error as it is for file path)
var dl = ytdl(url).pipe(fs.createWriteStream(`./videos/${id}.mp4`));
dl.on('finish', () => {
callback( id )
})
Can you access the URL via a webbrowser? And is the script hosted in (at least) the same region?
any solution?
any solution?
Not without help narrowing down the problem
Video Youtube: https://www.youtube.com/watch?v=KHOrp6Fcp9M
just before that another error occurred, like 10 seconds before
Video Youtube:
https://www.youtube.com/watch?v=qqSMqgGuSgU
I am trying to ignore the exception so that my program does not stop but even so the process ends up, it would be a great help if you told me how to ignore that exception
Code:
"use strict";
var os = require("os");
var EventEmitter = require("events").EventEmitter;
var ffmpeg = require("fluent-ffmpeg");
var ytdl = require("ytdl-core");
var async = require("async");
var progress = require("progress-stream");
var sanitize = require("sanitize-filename");
class YoutubeMp3Downloader extends EventEmitter {
constructor(options) {
super();
this.youtubeBaseUrl = "http://www.youtube.com/watch?v=";
this.youtubeVideoQuality =
options && options.youtubeVideoQuality
? options.youtubeVideoQuality
: "highestaudio";
this.outputPath =
options && options.outputPath ? options.outputPath : os.homedir();
this.queueParallelism =
options && options.queueParallelism ? options.queueParallelism : 1;
this.progressTimeout =
options && options.progressTimeout ? options.progressTimeout : 1000;
this.fileNameReplacements = [
[/'/g, ""],
[/\|/g, ""],
[/'/g, ""],
[/\//g, ""],
[/\?/g, ""],
[/:/g, ""],
[/;/g, ""],
];
this.requestOptions =
options && options.requestOptions
? options.requestOptions
: { maxRedirects: 5 };
this.outputOptions =
options && options.outputOptions ? options.outputOptions : [];
this.allowWebm =
options && options.allowWebm ? options.allowWebm : false;
if (options && options.ffmpegPath) {
ffmpeg.setFfmpegPath(options.ffmpegPath);
}
this.setupQueue();
}
setupQueue() {
let self = this;
//Async download/transcode queue
this.downloadQueue = async.queue(function (task, callback) {
self.emit(
"queueSize",
self.downloadQueue.running() + self.downloadQueue.length()
);
self.performDownload(task, function (err, result) {
callback(err, result);
});
}, self.queueParallelism);
}
cleanFileName(fileName) {
this.fileNameReplacements.forEach(function (replacement) {
fileName = fileName.replace(replacement[0], replacement[1]);
});
return fileName;
}
download(videoId, fileName) {
let self = this;
const task = {
videoId: videoId,
fileName: fileName,
};
this.downloadQueue.push(task, function (err, data) {
self.emit(
"queueSize",
self.downloadQueue.running() + self.downloadQueue.length()
);
if (err) {
self.emit("error", err, data);
} else {
self.emit("finished", err, data);
}
});
}
async performDownload(task, callback) {
let self = this;
const videoUrl = this.youtubeBaseUrl + task.videoId;
let resultObj = {
videoId: task.videoId,
};
const info = await ytdl.getInfo(videoUrl, {
quality: this
.youtubeVideoQuality /*requestOptions: {
headers: {
cookie: COOKIE,
},
}*/,
});
var videoTitle = this.cleanFileName(info.videoDetails.title);
var artist = "Unknown";
var title = "Unknown";
var thumbnail = info.videoDetails.thumbnail.thumbnails[0].url || null;
if (videoTitle.indexOf("-") > -1) {
var temp = videoTitle.split("-");
if (temp.length >= 2) {
artist = temp[0].trim();
title = temp[1].trim();
}
} else {
title = videoTitle;
}
//Derive file name, if given, use it, if not, from video title
const fileName = task.fileName
? self.outputPath + "/" + task.fileName
: self.outputPath +
"/" +
(sanitize(videoTitle) || info.videoId) +
".mp3";
//Stream setup
const streamOptions = {
quality: self.youtubeVideoQuality,
requestOptions: self.requestOptions,
/*requestOptions: {
headers: {
cookie: COOKIE,
},
}*/
};
if (!self.allowWebm) {
streamOptions.filter = (format) => format.container === "mp4";
}
try {
const stream = ytdl.downloadFromInfo(info, streamOptions);
stream.on("response", function (httpResponse) {
//Setup of progress module
const str = progress({
length: parseInt(httpResponse.headers["content-length"]),
time: self.progressTimeout,
});
//Add progress event listener
str.on("progress", function (progress) {
if (progress.percentage === 100) {
resultObj.stats = {
transferredBytes: progress.transferred,
runtime: progress.runtime,
averageSpeed: parseFloat(progress.speed.toFixed(2)),
};
}
self.emit("progress", {
videoId: task.videoId,
progress: progress,
});
});
let outputOptions = [
"-id3v2_version",
"4",
"-metadata",
"title=" + title,
"-metadata",
"artist=" + artist,
];
if (self.outputOptions) {
outputOptions = outputOptions.concat(self.outputOptions);
}
//Start encoding
const proc = new ffmpeg({
source: stream.pipe(str),
})
.audioBitrate(info.formats[0].audioBitrate || 96)
.withAudioCodec("libmp3lame")
.toFormat("mp3")
.outputOptions(...outputOptions)
.on("error", function (err) {
//return callback(err.message, null);//error por arreglar
})
.on("end", function () {
resultObj.file = fileName;
resultObj.youtubeUrl = videoUrl;
resultObj.videoTitle = videoTitle;
resultObj.artist = artist;
resultObj.title = title;
resultObj.thumbnail = thumbnail;
callback(null, resultObj);
})
.saveToFile(fileName);
});
} catch (err) {
self.emit("error", err, "");
}
}
}
module.exports = YoutubeMp3Downloader;
Call Class:
//Configure YoutubeMp3Downloader with your settings
var YD = new YoutubeMp3Downloader({
//"ffmpegPath": '/usr/bin/ffmpeg', // FFmpeg binary location
"ffmpegPath": ffmpeg.path,
"outputPath": "./youtube_mp3/mp3", // Output file location (default: the home directory)
"youtubeVideoQuality": "highestaudio", // Desired video quality (default: highestaudio)
"queueParallelism": 10, // Download parallelism (default: 1)
//"progressTimeout": 500, // Interval in ms for the progress reports (default: 1000)
"allowWebm": false // Enable download from WebM sources (default: false)
});
YD.download(url, nombreFile);
YD.on("finished", async function (err, dataYD) {
///...
});
YD.on("error", async function (err, dataYD) {
**//No working**
});
ytdl.downloadFromInfo(info, streamOptions);
should not "throw" an error but emit an error event
so try listening for that event instead of the try / catch
my server is local to me, same network and has access to the internet. and I can view it on YouTube just fine