diff options
Diffstat (limited to 'server/helpers')
-rw-r--r-- | server/helpers/custom-validators/videos.ts | 5 | ||||
-rw-r--r-- | server/helpers/ffmpeg-utils.ts | 79 | ||||
-rw-r--r-- | server/helpers/index.ts | 1 | ||||
-rw-r--r-- | server/helpers/utils.ts | 2 |
4 files changed, 83 insertions, 4 deletions
diff --git a/server/helpers/custom-validators/videos.ts b/server/helpers/custom-validators/videos.ts index 2eb021ae7..a31aca019 100644 --- a/server/helpers/custom-validators/videos.ts +++ b/server/helpers/custom-validators/videos.ts | |||
@@ -8,8 +8,7 @@ import { | |||
8 | VIDEO_CATEGORIES, | 8 | VIDEO_CATEGORIES, |
9 | VIDEO_LICENCES, | 9 | VIDEO_LICENCES, |
10 | VIDEO_LANGUAGES, | 10 | VIDEO_LANGUAGES, |
11 | VIDEO_RATE_TYPES, | 11 | VIDEO_RATE_TYPES |
12 | VIDEO_FILE_RESOLUTIONS | ||
13 | } from '../../initializers' | 12 | } from '../../initializers' |
14 | import { isUserUsernameValid } from './users' | 13 | import { isUserUsernameValid } from './users' |
15 | import { isArray, exists } from './misc' | 14 | import { isArray, exists } from './misc' |
@@ -128,7 +127,7 @@ function isVideoFileSizeValid (value: string) { | |||
128 | } | 127 | } |
129 | 128 | ||
130 | function isVideoFileResolutionValid (value: string) { | 129 | function isVideoFileResolutionValid (value: string) { |
131 | return VIDEO_FILE_RESOLUTIONS[value] !== undefined | 130 | return exists(value) && validator.isInt(value + '') |
132 | } | 131 | } |
133 | 132 | ||
134 | function isVideoFileExtnameValid (value: string) { | 133 | function isVideoFileExtnameValid (value: string) { |
diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts new file mode 100644 index 000000000..c35125ec1 --- /dev/null +++ b/server/helpers/ffmpeg-utils.ts | |||
@@ -0,0 +1,79 @@ | |||
1 | import * as Promise from 'bluebird' | ||
2 | import * as ffmpeg from 'fluent-ffmpeg' | ||
3 | |||
4 | import { CONFIG } from '../initializers' | ||
5 | import { VideoResolution } from '../../shared/models/videos/video-resolution.enum' | ||
6 | |||
7 | function getVideoFileHeight (path: string) { | ||
8 | return new Promise<number>((res, rej) => { | ||
9 | ffmpeg.ffprobe(path, (err, metadata) => { | ||
10 | if (err) return rej(err) | ||
11 | |||
12 | const videoStream = metadata.streams.find(s => s.codec_type === 'video') | ||
13 | return res(videoStream.height) | ||
14 | }) | ||
15 | }) | ||
16 | } | ||
17 | |||
18 | function getDurationFromVideoFile (path: string) { | ||
19 | return new Promise<number>((res, rej) => { | ||
20 | ffmpeg.ffprobe(path, (err, metadata) => { | ||
21 | if (err) return rej(err) | ||
22 | |||
23 | return res(Math.floor(metadata.format.duration)) | ||
24 | }) | ||
25 | }) | ||
26 | } | ||
27 | |||
28 | function generateImageFromVideoFile (fromPath: string, folder: string, imageName: string, size?: string) { | ||
29 | const options = { | ||
30 | filename: imageName, | ||
31 | count: 1, | ||
32 | folder | ||
33 | } | ||
34 | |||
35 | if (size !== undefined) { | ||
36 | options['size'] = size | ||
37 | } | ||
38 | |||
39 | return new Promise<string>((res, rej) => { | ||
40 | ffmpeg(fromPath) | ||
41 | .on('error', rej) | ||
42 | .on('end', () => res(imageName)) | ||
43 | .thumbnail(options) | ||
44 | }) | ||
45 | } | ||
46 | |||
47 | type TranscodeOptions = { | ||
48 | inputPath: string | ||
49 | outputPath: string | ||
50 | resolution?: VideoResolution | ||
51 | } | ||
52 | |||
53 | function transcode (options: TranscodeOptions) { | ||
54 | return new Promise<void>((res, rej) => { | ||
55 | let command = ffmpeg(options.inputPath) | ||
56 | .output(options.outputPath) | ||
57 | .videoCodec('libx264') | ||
58 | .outputOption('-threads ' + CONFIG.TRANSCODING.THREADS) | ||
59 | .outputOption('-movflags faststart') | ||
60 | |||
61 | if (options.resolution !== undefined) { | ||
62 | const size = `${options.resolution}x?` // '720x?' for example | ||
63 | command = command.size(size) | ||
64 | } | ||
65 | |||
66 | command.on('error', rej) | ||
67 | .on('end', res) | ||
68 | .run() | ||
69 | }) | ||
70 | } | ||
71 | |||
72 | // --------------------------------------------------------------------------- | ||
73 | |||
74 | export { | ||
75 | getVideoFileHeight, | ||
76 | getDurationFromVideoFile, | ||
77 | generateImageFromVideoFile, | ||
78 | transcode | ||
79 | } | ||
diff --git a/server/helpers/index.ts b/server/helpers/index.ts index 78215fe10..846bd796f 100644 --- a/server/helpers/index.ts +++ b/server/helpers/index.ts | |||
@@ -1,6 +1,7 @@ | |||
1 | export * from './core-utils' | 1 | export * from './core-utils' |
2 | export * from './logger' | 2 | export * from './logger' |
3 | export * from './custom-validators' | 3 | export * from './custom-validators' |
4 | export * from './ffmpeg-utils' | ||
4 | export * from './database-utils' | 5 | export * from './database-utils' |
5 | export * from './peertube-crypto' | 6 | export * from './peertube-crypto' |
6 | export * from './requests' | 7 | export * from './requests' |
diff --git a/server/helpers/utils.ts b/server/helpers/utils.ts index b74442ab0..3317dddc3 100644 --- a/server/helpers/utils.ts +++ b/server/helpers/utils.ts | |||
@@ -61,7 +61,7 @@ function computeResolutionsToTranscode (videoFileHeight: number) { | |||
61 | ] | 61 | ] |
62 | 62 | ||
63 | for (const resolution of resolutions) { | 63 | for (const resolution of resolutions) { |
64 | if (configResolutions[resolution.toString()] === true && videoFileHeight >= resolution) { | 64 | if (configResolutions[resolution.toString()] === true && videoFileHeight > resolution) { |
65 | resolutionsEnabled.push(resolution) | 65 | resolutionsEnabled.push(resolution) |
66 | } | 66 | } |
67 | } | 67 | } |