diff options
-rw-r--r-- | server/helpers/youtube-dl.ts | 22 | ||||
-rw-r--r-- | server/lib/schedulers/abstract-scheduler.ts | 2 | ||||
-rw-r--r-- | server/lib/schedulers/youtube-dl-update-scheduler.ts | 71 |
3 files changed, 60 insertions, 35 deletions
diff --git a/server/helpers/youtube-dl.ts b/server/helpers/youtube-dl.ts index 77986f407..0afc54fd2 100644 --- a/server/helpers/youtube-dl.ts +++ b/server/helpers/youtube-dl.ts | |||
@@ -1,8 +1,8 @@ | |||
1 | import * as youtubeDL from 'youtube-dl' | ||
2 | import { truncate } from 'lodash' | 1 | import { truncate } from 'lodash' |
3 | import { CONSTRAINTS_FIELDS, VIDEO_CATEGORIES } from '../initializers' | 2 | import { CONSTRAINTS_FIELDS, VIDEO_CATEGORIES } from '../initializers' |
4 | import { logger } from './logger' | 3 | import { logger } from './logger' |
5 | import { generateVideoTmpPath } from './utils' | 4 | import { generateVideoTmpPath } from './utils' |
5 | import { YoutubeDlUpdateScheduler } from '../lib/schedulers/youtube-dl-update-scheduler' | ||
6 | 6 | ||
7 | export type YoutubeDLInfo = { | 7 | export type YoutubeDLInfo = { |
8 | name?: string | 8 | name?: string |
@@ -15,9 +15,10 @@ export type YoutubeDLInfo = { | |||
15 | } | 15 | } |
16 | 16 | ||
17 | function getYoutubeDLInfo (url: string): Promise<YoutubeDLInfo> { | 17 | function getYoutubeDLInfo (url: string): Promise<YoutubeDLInfo> { |
18 | return new Promise<YoutubeDLInfo>((res, rej) => { | 18 | return new Promise<YoutubeDLInfo>(async (res, rej) => { |
19 | const options = [ '-j', '--flat-playlist' ] | 19 | const options = [ '-j', '--flat-playlist' ] |
20 | 20 | ||
21 | const youtubeDL = await safeGetYoutubeDL() | ||
21 | youtubeDL.getInfo(url, options, (err, info) => { | 22 | youtubeDL.getInfo(url, options, (err, info) => { |
22 | if (err) return rej(err) | 23 | if (err) return rej(err) |
23 | 24 | ||
@@ -35,7 +36,8 @@ function downloadYoutubeDLVideo (url: string) { | |||
35 | 36 | ||
36 | const options = [ '-f', 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best', '-o', path ] | 37 | const options = [ '-f', 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best', '-o', path ] |
37 | 38 | ||
38 | return new Promise<string>((res, rej) => { | 39 | return new Promise<string>(async (res, rej) => { |
40 | const youtubeDL = await safeGetYoutubeDL() | ||
39 | youtubeDL.exec(url, options, async (err, output) => { | 41 | youtubeDL.exec(url, options, async (err, output) => { |
40 | if (err) return rej(err) | 42 | if (err) return rej(err) |
41 | 43 | ||
@@ -53,6 +55,20 @@ export { | |||
53 | 55 | ||
54 | // --------------------------------------------------------------------------- | 56 | // --------------------------------------------------------------------------- |
55 | 57 | ||
58 | async function safeGetYoutubeDL () { | ||
59 | let youtubeDL | ||
60 | |||
61 | try { | ||
62 | youtubeDL = require('youtube-dl') | ||
63 | } catch (e) { | ||
64 | // Download binary | ||
65 | await YoutubeDlUpdateScheduler.Instance.execute() | ||
66 | youtubeDL = require('youtube-dl') | ||
67 | } | ||
68 | |||
69 | return youtubeDL | ||
70 | } | ||
71 | |||
56 | function normalizeObject (obj: any) { | 72 | function normalizeObject (obj: any) { |
57 | const newObj: any = {} | 73 | const newObj: any = {} |
58 | 74 | ||
diff --git a/server/lib/schedulers/abstract-scheduler.ts b/server/lib/schedulers/abstract-scheduler.ts index 6ec5e3360..b9d0a4d17 100644 --- a/server/lib/schedulers/abstract-scheduler.ts +++ b/server/lib/schedulers/abstract-scheduler.ts | |||
@@ -14,5 +14,5 @@ export abstract class AbstractScheduler { | |||
14 | clearInterval(this.interval) | 14 | clearInterval(this.interval) |
15 | } | 15 | } |
16 | 16 | ||
17 | protected abstract execute () | 17 | abstract execute () |
18 | } | 18 | } |
diff --git a/server/lib/schedulers/youtube-dl-update-scheduler.ts b/server/lib/schedulers/youtube-dl-update-scheduler.ts index a2d919603..24cd3f87b 100644 --- a/server/lib/schedulers/youtube-dl-update-scheduler.ts +++ b/server/lib/schedulers/youtube-dl-update-scheduler.ts | |||
@@ -7,7 +7,7 @@ import { logger } from '../../helpers/logger' | |||
7 | import * as request from 'request' | 7 | import * as request from 'request' |
8 | import { createWriteStream, writeFile } from 'fs' | 8 | import { createWriteStream, writeFile } from 'fs' |
9 | import { join } from 'path' | 9 | import { join } from 'path' |
10 | import { root } from '../../helpers/core-utils' | 10 | import { mkdirpPromise, root } from '../../helpers/core-utils' |
11 | 11 | ||
12 | export class YoutubeDlUpdateScheduler extends AbstractScheduler { | 12 | export class YoutubeDlUpdateScheduler extends AbstractScheduler { |
13 | 13 | ||
@@ -20,49 +20,58 @@ export class YoutubeDlUpdateScheduler extends AbstractScheduler { | |||
20 | } | 20 | } |
21 | 21 | ||
22 | async execute () { | 22 | async execute () { |
23 | logger.info('Updating youtubeDL binary.') | ||
24 | |||
23 | const binDirectory = join(root(), 'node_modules', 'youtube-dl', 'bin') | 25 | const binDirectory = join(root(), 'node_modules', 'youtube-dl', 'bin') |
24 | const bin = join(binDirectory, 'youtube-dl') | 26 | const bin = join(binDirectory, 'youtube-dl') |
25 | const detailsPath = join(binDirectory, 'details') | 27 | const detailsPath = join(binDirectory, 'details') |
26 | const url = 'https://yt-dl.org/downloads/latest/youtube-dl' | 28 | const url = 'https://yt-dl.org/downloads/latest/youtube-dl' |
27 | 29 | ||
28 | request.get(url, { followRedirect: false }, (err, res) => { | 30 | await mkdirpPromise(binDirectory) |
29 | if (err) { | 31 | |
30 | logger.error('Cannot update youtube-dl.', { err }) | 32 | return new Promise(res => { |
31 | return | 33 | request.get(url, { followRedirect: false }, (err, result) => { |
32 | } | 34 | if (err) { |
33 | 35 | logger.error('Cannot update youtube-dl.', { err }) | |
34 | if (res.statusCode !== 302) { | 36 | return res() |
35 | logger.error('youtube-dl update error: did not get redirect for the latest version link. Status %d', res.statusCode) | ||
36 | return | ||
37 | } | ||
38 | |||
39 | const url = res.headers.location | ||
40 | const downloadFile = request.get(url) | ||
41 | const newVersion = /yt-dl\.org\/downloads\/(\d{4}\.\d\d\.\d\d(\.\d)?)\/youtube-dl/.exec(url)[1] | ||
42 | |||
43 | downloadFile.on('response', res => { | ||
44 | if (res.statusCode !== 200) { | ||
45 | logger.error('Cannot update youtube-dl: new version response is not 200, it\'s %d.', res.statusCode) | ||
46 | return | ||
47 | } | 37 | } |
48 | 38 | ||
49 | downloadFile.pipe(createWriteStream(bin, { mode: 493 })) | 39 | if (result.statusCode !== 302) { |
50 | }) | 40 | logger.error('youtube-dl update error: did not get redirect for the latest version link. Status %d', result.statusCode) |
41 | return res() | ||
42 | } | ||
51 | 43 | ||
52 | downloadFile.on('error', err => logger.error('youtube-dl update error.', { err })) | 44 | const url = result.headers.location |
45 | const downloadFile = request.get(url) | ||
46 | const newVersion = /yt-dl\.org\/downloads\/(\d{4}\.\d\d\.\d\d(\.\d)?)\/youtube-dl/.exec(url)[ 1 ] | ||
53 | 47 | ||
54 | downloadFile.on('end', () => { | 48 | downloadFile.on('response', result => { |
55 | const details = JSON.stringify({ version: newVersion, path: bin, exec: 'youtube-dl' }) | 49 | if (result.statusCode !== 200) { |
56 | writeFile(detailsPath, details, { encoding: 'utf8' }, err => { | 50 | logger.error('Cannot update youtube-dl: new version response is not 200, it\'s %d.', result.statusCode) |
57 | if (err) { | 51 | return res() |
58 | logger.error('youtube-dl update error: cannot write details.', { err }) | ||
59 | return | ||
60 | } | 52 | } |
61 | 53 | ||
62 | logger.info('youtube-dl updated to version %s.', newVersion) | 54 | downloadFile.pipe(createWriteStream(bin, { mode: 493 })) |
63 | }) | 55 | }) |
64 | }) | ||
65 | 56 | ||
57 | downloadFile.on('error', err => { | ||
58 | logger.error('youtube-dl update error.', { err }) | ||
59 | return res() | ||
60 | }) | ||
61 | |||
62 | downloadFile.on('end', () => { | ||
63 | const details = JSON.stringify({ version: newVersion, path: bin, exec: 'youtube-dl' }) | ||
64 | writeFile(detailsPath, details, { encoding: 'utf8' }, err => { | ||
65 | if (err) { | ||
66 | logger.error('youtube-dl update error: cannot write details.', { err }) | ||
67 | return res() | ||
68 | } | ||
69 | |||
70 | logger.info('youtube-dl updated to version %s.', newVersion) | ||
71 | return res() | ||
72 | }) | ||
73 | }) | ||
74 | }) | ||
66 | }) | 75 | }) |
67 | } | 76 | } |
68 | 77 | ||