diff options
Diffstat (limited to 'server/lib')
-rw-r--r-- | server/lib/video-transcoding-profiles.ts | 35 | ||||
-rw-r--r-- | server/lib/video-transcoding.ts | 13 |
2 files changed, 37 insertions, 11 deletions
diff --git a/server/lib/video-transcoding-profiles.ts b/server/lib/video-transcoding-profiles.ts index 91a5c65f2..03c26f236 100644 --- a/server/lib/video-transcoding-profiles.ts +++ b/server/lib/video-transcoding-profiles.ts | |||
@@ -1,11 +1,22 @@ | |||
1 | import { logger } from '@server/helpers/logger' | ||
1 | import { getTargetBitrate } from '../../shared/models/videos' | 2 | import { getTargetBitrate } from '../../shared/models/videos' |
2 | import { AvailableEncoders, buildStreamSuffix, EncoderOptionsBuilder } from '../helpers/ffmpeg-utils' | 3 | import { AvailableEncoders, buildStreamSuffix, EncoderOptionsBuilder } from '../helpers/ffmpeg-utils' |
3 | import { ffprobePromise, getAudioStream, getMaxAudioBitrate, getVideoFileBitrate, getVideoStreamFromFile } from '../helpers/ffprobe-utils' | 4 | import { |
5 | canDoQuickAudioTranscode, | ||
6 | ffprobePromise, | ||
7 | getAudioStream, | ||
8 | getMaxAudioBitrate, | ||
9 | getVideoFileBitrate, | ||
10 | getVideoStreamFromFile | ||
11 | } from '../helpers/ffprobe-utils' | ||
4 | import { VIDEO_TRANSCODING_FPS } from '../initializers/constants' | 12 | import { VIDEO_TRANSCODING_FPS } from '../initializers/constants' |
5 | 13 | ||
6 | // --------------------------------------------------------------------------- | 14 | /** |
7 | // Available encoders profiles | 15 | * |
8 | // --------------------------------------------------------------------------- | 16 | * Available encoders and profiles for the transcoding jobs |
17 | * These functions are used by ffmpeg-utils that will get the encoders and options depending on the chosen profile | ||
18 | * | ||
19 | */ | ||
9 | 20 | ||
10 | // Resources: | 21 | // Resources: |
11 | // * https://slhck.info/video/2017/03/01/rate-control.html | 22 | // * https://slhck.info/video/2017/03/01/rate-control.html |
@@ -27,7 +38,8 @@ const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = async ({ input, reso | |||
27 | 38 | ||
28 | return { | 39 | return { |
29 | outputOptions: [ | 40 | outputOptions: [ |
30 | `-maxrate ${targetBitrate}`, `-bufsize ${targetBitrate * 2}` | 41 | `-maxrate ${targetBitrate}`, |
42 | `-bufsize ${targetBitrate * 2}` | ||
31 | ] | 43 | ] |
32 | } | 44 | } |
33 | } | 45 | } |
@@ -45,7 +57,14 @@ const defaultX264LiveOptionsBuilder: EncoderOptionsBuilder = async ({ resolution | |||
45 | } | 57 | } |
46 | 58 | ||
47 | const defaultAACOptionsBuilder: EncoderOptionsBuilder = async ({ input, streamNum }) => { | 59 | const defaultAACOptionsBuilder: EncoderOptionsBuilder = async ({ input, streamNum }) => { |
48 | const parsedAudio = await getAudioStream(input) | 60 | const probe = await ffprobePromise(input) |
61 | |||
62 | if (await canDoQuickAudioTranscode(input, probe)) { | ||
63 | logger.debug('Copy audio stream %s by AAC encoder.', input) | ||
64 | return { copy: true, outputOptions: [] } | ||
65 | } | ||
66 | |||
67 | const parsedAudio = await getAudioStream(input, probe) | ||
49 | 68 | ||
50 | // We try to reduce the ceiling bitrate by making rough matches of bitrates | 69 | // We try to reduce the ceiling bitrate by making rough matches of bitrates |
51 | // Of course this is far from perfect, but it might save some space in the end | 70 | // Of course this is far from perfect, but it might save some space in the end |
@@ -54,11 +73,13 @@ const defaultAACOptionsBuilder: EncoderOptionsBuilder = async ({ input, streamNu | |||
54 | 73 | ||
55 | const bitrate = getMaxAudioBitrate(audioCodecName, parsedAudio.bitrate) | 74 | const bitrate = getMaxAudioBitrate(audioCodecName, parsedAudio.bitrate) |
56 | 75 | ||
76 | logger.debug('Calculating audio bitrate of %s by AAC encoder.', input, { bitrate: parsedAudio.bitrate, audioCodecName }) | ||
77 | |||
57 | if (bitrate !== undefined && bitrate !== -1) { | 78 | if (bitrate !== undefined && bitrate !== -1) { |
58 | return { outputOptions: [ buildStreamSuffix('-b:a', streamNum), bitrate + 'k' ] } | 79 | return { outputOptions: [ buildStreamSuffix('-b:a', streamNum), bitrate + 'k' ] } |
59 | } | 80 | } |
60 | 81 | ||
61 | return { copy: true, outputOptions: [] } | 82 | return { outputOptions: [ ] } |
62 | } | 83 | } |
63 | 84 | ||
64 | const defaultLibFDKAACVODOptionsBuilder: EncoderOptionsBuilder = ({ streamNum }) => { | 85 | const defaultLibFDKAACVODOptionsBuilder: EncoderOptionsBuilder = ({ streamNum }) => { |
diff --git a/server/lib/video-transcoding.ts b/server/lib/video-transcoding.ts index aaad219dd..e022f2a68 100644 --- a/server/lib/video-transcoding.ts +++ b/server/lib/video-transcoding.ts | |||
@@ -16,8 +16,13 @@ import { generateVideoStreamingPlaylistName, getVideoFilename, getVideoFilePath | |||
16 | import { availableEncoders } from './video-transcoding-profiles' | 16 | import { availableEncoders } from './video-transcoding-profiles' |
17 | 17 | ||
18 | /** | 18 | /** |
19 | * Optimize the original video file and replace it. The resolution is not changed. | 19 | * |
20 | * Functions that run transcoding functions, update the database, cleanup files, create torrent files... | ||
21 | * Mainly called by the job queue | ||
22 | * | ||
20 | */ | 23 | */ |
24 | |||
25 | // Optimize the original video file and replace it. The resolution is not changed. | ||
21 | async function optimizeOriginalVideofile (video: MVideoWithFile, inputVideoFileArg?: MVideoFile) { | 26 | async function optimizeOriginalVideofile (video: MVideoWithFile, inputVideoFileArg?: MVideoFile) { |
22 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR | 27 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR |
23 | const newExtname = '.mp4' | 28 | const newExtname = '.mp4' |
@@ -62,9 +67,7 @@ async function optimizeOriginalVideofile (video: MVideoWithFile, inputVideoFileA | |||
62 | } | 67 | } |
63 | } | 68 | } |
64 | 69 | ||
65 | /** | 70 | // Transcode the original video file to a lower resolution. |
66 | * Transcode the original video file to a lower resolution. | ||
67 | */ | ||
68 | async function transcodeNewResolution (video: MVideoWithFile, resolution: VideoResolution, isPortrait: boolean) { | 71 | async function transcodeNewResolution (video: MVideoWithFile, resolution: VideoResolution, isPortrait: boolean) { |
69 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR | 72 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR |
70 | const extname = '.mp4' | 73 | const extname = '.mp4' |
@@ -110,6 +113,7 @@ async function transcodeNewResolution (video: MVideoWithFile, resolution: VideoR | |||
110 | return onVideoFileTranscoding(video, newVideoFile, videoTranscodedPath, videoOutputPath) | 113 | return onVideoFileTranscoding(video, newVideoFile, videoTranscodedPath, videoOutputPath) |
111 | } | 114 | } |
112 | 115 | ||
116 | // Merge an image with an audio file to create a video | ||
113 | async function mergeAudioVideofile (video: MVideoWithAllFiles, resolution: VideoResolution) { | 117 | async function mergeAudioVideofile (video: MVideoWithAllFiles, resolution: VideoResolution) { |
114 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR | 118 | const transcodeDirectory = CONFIG.STORAGE.TMP_DIR |
115 | const newExtname = '.mp4' | 119 | const newExtname = '.mp4' |
@@ -159,6 +163,7 @@ async function mergeAudioVideofile (video: MVideoWithAllFiles, resolution: Video | |||
159 | return onVideoFileTranscoding(video, inputVideoFile, videoTranscodedPath, videoOutputPath) | 163 | return onVideoFileTranscoding(video, inputVideoFile, videoTranscodedPath, videoOutputPath) |
160 | } | 164 | } |
161 | 165 | ||
166 | // Generate an HLS playlist from an input file, and update the master playlist | ||
162 | async function generateHlsPlaylist (options: { | 167 | async function generateHlsPlaylist (options: { |
163 | video: MVideoWithFile | 168 | video: MVideoWithFile |
164 | videoInputPath: string | 169 | videoInputPath: string |