Youtube music and video downloader

Converter.js 1.8KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364
  1. import EventEmitter from 'events';
  2. import fs from 'fs';
  3. import ytdl from 'ytdl-core';
  4. import ffmpeg from 'fluent-ffmpeg';
  5. class Converter extends EventEmitter {
  6. constructor(url) {
  7. super();
  8. this.ytdl = null;
  9. this.totalSeconds = 0;
  10. ytdl.getInfo(url, {}, (err, info) => {
  11. if (err)
  12. this.emit('unavailable', err);
  13. else {
  14. this.totalSeconds = info ? info.length_seconds : 0;
  15. this.ytdl = ytdl(url);
  16. this.emit('available', info);
  17. }
  18. });
  19. }
  20. }
  21. export class VideoConverter extends Converter {
  22. constructor(url) { super(url); }
  23. initResponse(res, path) {
  24. const totalSize = res.headers['content-length'];
  25. let dataRead = 0;
  26. res.on('data', data => {
  27. dataRead += data.length;
  28. let percent = dataRead / totalSize;
  29. this.emit('progress', (percent * 100).toFixed(0));
  30. })
  31. .on('end', () => this.emit('end'))
  32. .on('error', () => fs.unlink(path, err => this.emit('error', error)));
  33. }
  34. download(path) {
  35. if (this.ytdl)
  36. this.ytdl.on('response', res => this.initResponse(res, path)).pipe(fs.createWriteStream(path));
  37. }
  38. }
  39. export class AudioConverter extends Converter {
  40. constructor(url) { super(url); }
  41. audio_percent(date) {
  42. const time = moment(new Date(...[0, 0, 0, ...date.split(':')]));
  43. const seconds = time.hours() * 3600 + time.minutes() * 60 + time.seconds();
  44. return ((seconds / this.totalSeconds) * 100).toFixed(0);
  45. }
  46. download(path) {
  47. if (this.ytdl)
  48. ffmpeg(this.ytdl)
  49. .noVideo().format('mp3')
  50. .output(fs.createWriteStream(path))
  51. .on('end', () => this.emit('end'))
  52. .on('start', () => this.emit('start'))
  53. .on('progress', params => this.emit('progress', this.audio_percent(params.timemark)))
  54. .on('error', (err, stdout, stderr) => fs.unlink(path, () => this.emit('error', err, stdout, stderr)))
  55. .run();
  56. }
  57. }