FFmpegDownloader.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import { dirname, basename, resolve } from 'path';
  2. import * as request from 'request';
  3. import * as ProgressBar from 'progress';
  4. const debug = require('debug')('build:ffmpegDownloader');
  5. const progress = require('request-progress');
  6. import { Event, DownloaderBase } from './common';
  7. import { mergeOptions, extractGeneric } from './util';
  8. interface IRequestProgress {
  9. percent: number;
  10. speed: number;
  11. size: {
  12. total: number,
  13. transferred: number,
  14. };
  15. time: {
  16. elapsed: number,
  17. remaining: number,
  18. };
  19. }
  20. interface IFFmpegDownloaderOptions {
  21. platform?: string;
  22. arch?: string;
  23. version?: string;
  24. mirror?: string;
  25. useCaches?: boolean;
  26. showProgress?: boolean;
  27. }
  28. export class FFmpegDownloader extends DownloaderBase {
  29. public static DEFAULT_OPTIONS: IFFmpegDownloaderOptions = {
  30. platform: process.platform,
  31. arch: process.arch,
  32. version: '0.14.7',
  33. mirror: 'https://github.com/iteufel/nwjs-ffmpeg-prebuilt/releases/download/',
  34. useCaches: true,
  35. showProgress: true,
  36. };
  37. public options: IFFmpegDownloaderOptions;
  38. constructor(options: IFFmpegDownloaderOptions) {
  39. super();
  40. this.options = mergeOptions(FFmpegDownloader.DEFAULT_OPTIONS, options);
  41. debug('in constructor', 'options', options);
  42. }
  43. public async fetch() {
  44. const { mirror, version, platform, arch, showProgress } = this.options;
  45. const partVersion = await this.handleVersion(version);
  46. const partPlatform = this.handlePlatform(platform);
  47. const partArch = this.handleArch(arch);
  48. const url = `${ mirror }/${ partVersion }/${ partVersion }-${ partPlatform }-${ partArch }.zip`;
  49. const filename = `ffmpeg-${ basename(url) }`;
  50. const path = resolve(this.destination, filename);
  51. debug('in fetch', 'url', url);
  52. debug('in fetch', 'filename', filename);
  53. debug('in fetch', 'path', path);
  54. try {
  55. if(await this.isFileExists(path) && await this.isFileSynced(url, path)) {
  56. return path;
  57. }
  58. }
  59. catch(err) {
  60. debug('in fetch', 'err', err);
  61. if(err.code === 'ENOTFOUND' && this.options.useCaches) {
  62. console.info('DNS lookup fails, use local caches at this time.');
  63. return path;
  64. }
  65. else if(err.code === 'EAI_AGAIN' && this.options.useCaches) {
  66. console.info('DNS lookup timeout, use local caches at this time.');
  67. return path;
  68. }
  69. else {
  70. throw err;
  71. }
  72. }
  73. await this.download(url, filename, path, showProgress);
  74. return path;
  75. }
  76. protected async handleVersion(version: string) {
  77. switch(version) {
  78. case 'lts':
  79. case 'stable':
  80. case 'latest':
  81. throw new Error('ERROR_VERSION_UNSUPPORTED');
  82. default:
  83. return version[0] == 'v' ? version.slice(1) : version;
  84. }
  85. }
  86. }