diff options
Diffstat (limited to 'server/helpers/ffmpeg-utils.ts')
-rw-r--r-- | server/helpers/ffmpeg-utils.ts | 79 |
1 files changed, 79 insertions, 0 deletions
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 | } | ||