New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

youtube-mp3-downloader

Package Overview
Dependencies
Maintainers
1
Versions
32
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

youtube-mp3-downloader - npm Package Compare versions

Comparing version 0.6.8 to 0.7.0

286

lib/YoutubeMp3Downloader.js

@@ -1,177 +0,161 @@

"use strict";
var os = require("os");
var util = require("util");
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");
'use strict';
var os = require('os');
var util = require('util');
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');
function YoutubeMp3Downloader(options) {
class YoutubeMp3Downloader extends EventEmitter {
var self = this;
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 : []);
self.youtubeBaseUrl = "http://www.youtube.com/watch?v=";
self.youtubeVideoQuality = (options && options.youtubeVideoQuality ? options.youtubeVideoQuality : "highest");
self.outputPath = (options && options.outputPath ? options.outputPath : (os.platform() === "win32" ? "C:/Windows/Temp" : "/tmp"));
self.queueParallelism = (options && options.queueParallelism ? options.queueParallelism : 1);
self.progressTimeout = (options && options.progressTimeout ? options.progressTimeout : 1000);
self.fileNameReplacements = [[/"/g, ""], [/\|/g, ""], [/'/g, ""], [/\//g, ""], [/\?/g, ""], [/:/g, ""], [/;/g, ""]];
self.requestOptions = (options && options.requestOptions ? options.requestOptions : { maxRedirects: 5 });
self.outputOptions = (options && options.outputOptions ? options.outputOptions : []);
if (options && options.ffmpegPath) {
ffmpeg.setFfmpegPath(options.ffmpegPath);
}
if (options && options.ffmpegPath) {
ffmpeg.setFfmpegPath(options.ffmpegPath);
this.setupQueue();
}
//Async download/transcode queue
self.downloadQueue = async.queue(function (task, callback) {
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.emit('queueSize', self.downloadQueue.running() + self.downloadQueue.length());
self.performDownload(task, function(err, result) {
callback(err, result);
});
self.performDownload(task, function(err, result) {
callback(err, result);
});
}, self.queueParallelism);
}, self.queueParallelism);
}
}
cleanFileName (fileName) {
this.fileNameReplacements.forEach(function(replacement) {
fileName = fileName.replace(replacement[0], replacement[1]);
});
return fileName;
};
util.inherits(YoutubeMp3Downloader, EventEmitter);
YoutubeMp3Downloader.prototype.cleanFileName = function(fileName) {
var self = this;
self.fileNameReplacements.forEach(function(replacement) {
fileName = fileName.replace(replacement[0], replacement[1]);
});
return fileName;
};
YoutubeMp3Downloader.prototype.download = function(videoId, fileName) {
var self = this;
var task = {
videoId: videoId,
fileName: fileName
download = function(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);
}
});
};
self.downloadQueue.push(task, function (err, data) {
self.emit("queueSize", self.downloadQueue.running() + self.downloadQueue.length());
if (err) {
self.emit("error", 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 })
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 {
self.emit("finished", err, data);
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');
YoutubeMp3Downloader.prototype.performDownload = function(task, callback) {
//Stream setup
const stream = ytdl.downloadFromInfo(info, {
quality: self.youtubeVideoQuality,
requestOptions: self.requestOptions
});
var self = this;
var videoUrl = self.youtubeBaseUrl+task.videoId;
var resultObj = {
videoId: task.videoId
};
stream.on('response', function(httpResponse) {
ytdl.getInfo(videoUrl, function(err, info){
//Setup of progress module
const str = progress({
length: parseInt(httpResponse.headers['content-length']),
time: self.progressTimeout
});
if (err) {
callback(err.message, resultObj);
} else {
// Map new structure to old one
info = info.player_response.videoDetails;
var videoTitle = self.cleanFileName(info.title);
var artist = "Unknown";
var title = "Unknown";
var thumbnail = info.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();
//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))
}
}
} else {
title = videoTitle;
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)
.withAudioCodec('libmp3lame')
.toFormat('mp3')
.outputOptions(...outputOptions)
.on('error', function(err) {
callback(err.message, null);
})
.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);
//Derive file name, if given, use it, if not, from video title
var fileName = (task.fileName ? self.outputPath + "/" + task.fileName : self.outputPath + "/" + (sanitize(videoTitle) || info.videoId) + ".mp3");
});
};
ytdl.getInfo(videoUrl, { quality: self.youtubeVideoQuality }, function(err, info) {
}
if (err) callback(err, null);
//Stream setup
var stream = ytdl.downloadFromInfo(info, {
quality: self.youtubeVideoQuality,
requestOptions: self.requestOptions
});
stream.on("response", function(httpResponse) {
//Setup of progress module
var 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})
});
var outputOptions = [
"-id3v2_version", "4",
"-metadata", "title=" + title,
"-metadata", "artist=" + artist
];
if (self.outputOptions) {
outputOptions = outputOptions.concat(self.outputOptions);
}
//Start encoding
var proc = new ffmpeg({
source: stream.pipe(str)
})
.audioBitrate(info.formats[0].audioBitrate)
.withAudioCodec("libmp3lame")
.toFormat("mp3")
.outputOptions(...outputOptions)
.on("error", function(err) {
callback(err.message, null);
})
.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);
});
});
}
});
};
module.exports = YoutubeMp3Downloader;
{
"name": "youtube-mp3-downloader",
"version": "0.6.8",
"version": "0.7.0",
"description": "Downloads Youtube videos (in parallel, as streams), encodes the audio data as mp3 and stores them in a defineable location",

@@ -25,3 +25,3 @@ "keywords": [

"sanitize-filename": "^1.6.3",
"ytdl-core": "^2.1.7"
"ytdl-core": "^3.1.2"
},

@@ -28,0 +28,0 @@ "author": {

@@ -19,3 +19,3 @@ # Youtube MP3 Downloader

`git clone https://github.com/tobilg/youtube-mp3-downloader.git`
`git clone https://github.com/ytb2mp3/youtube-mp3-downloader.git`

@@ -37,7 +37,7 @@ #### Install module dependencies

var YD = new YoutubeMp3Downloader({
"ffmpegPath": "/path/to/ffmpeg", // Where is the FFmpeg binary located?
"outputPath": "/path/to/mp3/folder", // Where should the downloaded and encoded files be stored?
"youtubeVideoQuality": "highest", // What video quality should be used?
"queueParallelism": 2, // How many parallel downloads/encodes should be started?
"progressTimeout": 2000 // How long should be the interval of the progress reports
"ffmpegPath": "/path/to/ffmpeg", // FFmpeg binary location
"outputPath": "/path/to/mp3/folder", // Output file location (default: the home directory)
"youtubeVideoQuality": "highestaudio", // Desired video quality (default: highestaudio)
"queueParallelism": 2, // Download parallelism (default: 1)
"progressTimeout": 2000 // Interval in ms for the progress reports (default: 1000)
});

@@ -125,7 +125,7 @@

self.YD = new YoutubeMp3Downloader({
"ffmpegPath": "/path/to/ffmpeg", // Where is the FFmpeg binary located?
"outputPath": "/path/to/mp3/folder", // Where should the downloaded and encoded files be stored?
"youtubeVideoQuality": "highest", // What video quality should be used?
"queueParallelism": 2, // How many parallel downloads/encodes should be started?
"progressTimeout": 2000, // How long should be the interval of the progress reports
"ffmpegPath": "/path/to/ffmpeg", // FFmpeg binary location
"outputPath": "/path/to/mp3/folder", // Output file location (default: the home directory)
"youtubeVideoQuality": "highestaudio", // Desired video quality (default: highestaudio)
"queueParallelism": 2, // Download parallelism (default: 1)
"progressTimeout": 2000 // Interval in ms for the progress reports (default: 1000)
"outputOptions" : ["-af", "silenceremove=1:0:-50dB"] // Additional output options passend to ffmpeg

@@ -132,0 +132,0 @@ });

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc