aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/lib/transcoding
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2022-02-11 10:51:33 +0100
committerChocobozzz <chocobozzz@cpy.re>2022-02-28 10:42:19 +0100
commitc729caf6cc34630877a0e5a1bda1719384cd0c8a (patch)
tree1d2e13722e518c73d2c9e6f0969615e29d51cf8c /server/lib/transcoding
parenta24bf4dc659cebb65d887862bf21d7a35e9ec791 (diff)
downloadPeerTube-c729caf6cc34630877a0e5a1bda1719384cd0c8a.tar.gz
PeerTube-c729caf6cc34630877a0e5a1bda1719384cd0c8a.tar.zst
PeerTube-c729caf6cc34630877a0e5a1bda1719384cd0c8a.zip
Add basic video editor support
Diffstat (limited to 'server/lib/transcoding')
-rw-r--r--server/lib/transcoding/default-transcoding-profiles.ts (renamed from server/lib/transcoding/video-transcoding-profiles.ts)25
-rw-r--r--server/lib/transcoding/transcoding.ts (renamed from server/lib/transcoding/video-transcoding.ts)35
2 files changed, 41 insertions, 19 deletions
diff --git a/server/lib/transcoding/video-transcoding-profiles.ts b/server/lib/transcoding/default-transcoding-profiles.ts
index dcc8d4c5c..ba98a11ca 100644
--- a/server/lib/transcoding/video-transcoding-profiles.ts
+++ b/server/lib/transcoding/default-transcoding-profiles.ts
@@ -2,8 +2,14 @@
2import { logger } from '@server/helpers/logger' 2import { logger } from '@server/helpers/logger'
3import { getAverageBitrate, getMinLimitBitrate } from '@shared/core-utils' 3import { getAverageBitrate, getMinLimitBitrate } from '@shared/core-utils'
4import { AvailableEncoders, EncoderOptionsBuilder, EncoderOptionsBuilderParams, VideoResolution } from '../../../shared/models/videos' 4import { AvailableEncoders, EncoderOptionsBuilder, EncoderOptionsBuilderParams, VideoResolution } from '../../../shared/models/videos'
5import { buildStreamSuffix, resetSupportedEncoders } from '../../helpers/ffmpeg-utils' 5import {
6import { canDoQuickAudioTranscode, ffprobePromise, getAudioStream, getMaxAudioBitrate } from '../../helpers/ffprobe-utils' 6 buildStreamSuffix,
7 canDoQuickAudioTranscode,
8 ffprobePromise,
9 getAudioStream,
10 getMaxAudioBitrate,
11 resetSupportedEncoders
12} from '../../helpers/ffmpeg'
7 13
8/** 14/**
9 * 15 *
@@ -15,8 +21,14 @@ import { canDoQuickAudioTranscode, ffprobePromise, getAudioStream, getMaxAudioBi
15 * * https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate 21 * * https://trac.ffmpeg.org/wiki/Limiting%20the%20output%20bitrate
16 */ 22 */
17 23
24// ---------------------------------------------------------------------------
25// Default builders
26// ---------------------------------------------------------------------------
27
18const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => { 28const defaultX264VODOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOptionsBuilderParams) => {
19 const { fps, inputRatio, inputBitrate, resolution } = options 29 const { fps, inputRatio, inputBitrate, resolution } = options
30
31 // TODO: remove in 4.2, fps is not optional anymore
20 if (!fps) return { outputOptions: [ ] } 32 if (!fps) return { outputOptions: [ ] }
21 33
22 const targetBitrate = getTargetBitrate({ inputBitrate, ratio: inputRatio, fps, resolution }) 34 const targetBitrate = getTargetBitrate({ inputBitrate, ratio: inputRatio, fps, resolution })
@@ -45,10 +57,10 @@ const defaultX264LiveOptionsBuilder: EncoderOptionsBuilder = (options: EncoderOp
45 } 57 }
46} 58}
47 59
48const defaultAACOptionsBuilder: EncoderOptionsBuilder = async ({ input, streamNum }) => { 60const defaultAACOptionsBuilder: EncoderOptionsBuilder = async ({ input, streamNum, canCopyAudio }) => {
49 const probe = await ffprobePromise(input) 61 const probe = await ffprobePromise(input)
50 62
51 if (await canDoQuickAudioTranscode(input, probe)) { 63 if (canCopyAudio && await canDoQuickAudioTranscode(input, probe)) {
52 logger.debug('Copy audio stream %s by AAC encoder.', input) 64 logger.debug('Copy audio stream %s by AAC encoder.', input)
53 return { copy: true, outputOptions: [ ] } 65 return { copy: true, outputOptions: [ ] }
54 } 66 }
@@ -75,7 +87,10 @@ const defaultLibFDKAACVODOptionsBuilder: EncoderOptionsBuilder = ({ streamNum })
75 return { outputOptions: [ buildStreamSuffix('-q:a', streamNum), '5' ] } 87 return { outputOptions: [ buildStreamSuffix('-q:a', streamNum), '5' ] }
76} 88}
77 89
78// Used to get and update available encoders 90// ---------------------------------------------------------------------------
91// Profile manager to get and change default profiles
92// ---------------------------------------------------------------------------
93
79class VideoTranscodingProfilesManager { 94class VideoTranscodingProfilesManager {
80 private static instance: VideoTranscodingProfilesManager 95 private static instance: VideoTranscodingProfilesManager
81 96
diff --git a/server/lib/transcoding/video-transcoding.ts b/server/lib/transcoding/transcoding.ts
index 9942a067b..d55364e25 100644
--- a/server/lib/transcoding/video-transcoding.ts
+++ b/server/lib/transcoding/transcoding.ts
@@ -6,8 +6,15 @@ import { createTorrentAndSetInfoHash } from '@server/helpers/webtorrent'
6import { MStreamingPlaylistFilesVideo, MVideoFile, MVideoFullLight } from '@server/types/models' 6import { MStreamingPlaylistFilesVideo, MVideoFile, MVideoFullLight } from '@server/types/models'
7import { VideoResolution, VideoStorage } from '../../../shared/models/videos' 7import { VideoResolution, VideoStorage } from '../../../shared/models/videos'
8import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type' 8import { VideoStreamingPlaylistType } from '../../../shared/models/videos/video-streaming-playlist.type'
9import { transcode, TranscodeOptions, TranscodeOptionsType } from '../../helpers/ffmpeg-utils' 9import {
10import { canDoQuickTranscode, getDurationFromVideoFile, getMetadataFromFile, getVideoFileFPS } from '../../helpers/ffprobe-utils' 10 canDoQuickTranscode,
11 getVideoStreamDuration,
12 buildFileMetadata,
13 getVideoStreamFPS,
14 transcodeVOD,
15 TranscodeVODOptions,
16 TranscodeVODOptionsType
17} from '../../helpers/ffmpeg'
11import { CONFIG } from '../../initializers/config' 18import { CONFIG } from '../../initializers/config'
12import { P2P_MEDIA_LOADER_PEER_VERSION } from '../../initializers/constants' 19import { P2P_MEDIA_LOADER_PEER_VERSION } from '../../initializers/constants'
13import { VideoFileModel } from '../../models/video/video-file' 20import { VideoFileModel } from '../../models/video/video-file'
@@ -21,7 +28,7 @@ import {
21 getHlsResolutionPlaylistFilename 28 getHlsResolutionPlaylistFilename
22} from '../paths' 29} from '../paths'
23import { VideoPathManager } from '../video-path-manager' 30import { VideoPathManager } from '../video-path-manager'
24import { VideoTranscodingProfilesManager } from './video-transcoding-profiles' 31import { VideoTranscodingProfilesManager } from './default-transcoding-profiles'
25 32
26/** 33/**
27 * 34 *
@@ -38,13 +45,13 @@ function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile: MVid
38 return VideoPathManager.Instance.makeAvailableVideoFile(inputVideoFile.withVideoOrPlaylist(video), async videoInputPath => { 45 return VideoPathManager.Instance.makeAvailableVideoFile(inputVideoFile.withVideoOrPlaylist(video), async videoInputPath => {
39 const videoTranscodedPath = join(transcodeDirectory, video.id + '-transcoded' + newExtname) 46 const videoTranscodedPath = join(transcodeDirectory, video.id + '-transcoded' + newExtname)
40 47
41 const transcodeType: TranscodeOptionsType = await canDoQuickTranscode(videoInputPath) 48 const transcodeType: TranscodeVODOptionsType = await canDoQuickTranscode(videoInputPath)
42 ? 'quick-transcode' 49 ? 'quick-transcode'
43 : 'video' 50 : 'video'
44 51
45 const resolution = toEven(inputVideoFile.resolution) 52 const resolution = toEven(inputVideoFile.resolution)
46 53
47 const transcodeOptions: TranscodeOptions = { 54 const transcodeOptions: TranscodeVODOptions = {
48 type: transcodeType, 55 type: transcodeType,
49 56
50 inputPath: videoInputPath, 57 inputPath: videoInputPath,
@@ -59,7 +66,7 @@ function optimizeOriginalVideofile (video: MVideoFullLight, inputVideoFile: MVid
59 } 66 }
60 67
61 // Could be very long! 68 // Could be very long!
62 await transcode(transcodeOptions) 69 await transcodeVOD(transcodeOptions)
63 70
64 // Important to do this before getVideoFilename() to take in account the new filename 71 // Important to do this before getVideoFilename() to take in account the new filename
65 inputVideoFile.extname = newExtname 72 inputVideoFile.extname = newExtname
@@ -121,7 +128,7 @@ function transcodeNewWebTorrentResolution (video: MVideoFullLight, resolution: V
121 job 128 job
122 } 129 }
123 130
124 await transcode(transcodeOptions) 131 await transcodeVOD(transcodeOptions)
125 132
126 return onWebTorrentVideoFileTranscoding(video, newVideoFile, videoTranscodedPath, videoOutputPath) 133 return onWebTorrentVideoFileTranscoding(video, newVideoFile, videoTranscodedPath, videoOutputPath)
127 }) 134 })
@@ -158,7 +165,7 @@ function mergeAudioVideofile (video: MVideoFullLight, resolution: VideoResolutio
158 } 165 }
159 166
160 try { 167 try {
161 await transcode(transcodeOptions) 168 await transcodeVOD(transcodeOptions)
162 169
163 await remove(audioInputPath) 170 await remove(audioInputPath)
164 await remove(tmpPreviewPath) 171 await remove(tmpPreviewPath)
@@ -175,7 +182,7 @@ function mergeAudioVideofile (video: MVideoFullLight, resolution: VideoResolutio
175 const videoOutputPath = VideoPathManager.Instance.getFSVideoFileOutputPath(video, inputVideoFile) 182 const videoOutputPath = VideoPathManager.Instance.getFSVideoFileOutputPath(video, inputVideoFile)
176 // ffmpeg generated a new video file, so update the video duration 183 // ffmpeg generated a new video file, so update the video duration
177 // See https://trac.ffmpeg.org/ticket/5456 184 // See https://trac.ffmpeg.org/ticket/5456
178 video.duration = await getDurationFromVideoFile(videoTranscodedPath) 185 video.duration = await getVideoStreamDuration(videoTranscodedPath)
179 await video.save() 186 await video.save()
180 187
181 return onWebTorrentVideoFileTranscoding(video, inputVideoFile, videoTranscodedPath, videoOutputPath) 188 return onWebTorrentVideoFileTranscoding(video, inputVideoFile, videoTranscodedPath, videoOutputPath)
@@ -239,8 +246,8 @@ async function onWebTorrentVideoFileTranscoding (
239 outputPath: string 246 outputPath: string
240) { 247) {
241 const stats = await stat(transcodingPath) 248 const stats = await stat(transcodingPath)
242 const fps = await getVideoFileFPS(transcodingPath) 249 const fps = await getVideoStreamFPS(transcodingPath)
243 const metadata = await getMetadataFromFile(transcodingPath) 250 const metadata = await buildFileMetadata(transcodingPath)
244 251
245 await move(transcodingPath, outputPath, { overwrite: true }) 252 await move(transcodingPath, outputPath, { overwrite: true })
246 253
@@ -299,7 +306,7 @@ async function generateHlsPlaylistCommon (options: {
299 job 306 job
300 } 307 }
301 308
302 await transcode(transcodeOptions) 309 await transcodeVOD(transcodeOptions)
303 310
304 // Create or update the playlist 311 // Create or update the playlist
305 const playlist = await VideoStreamingPlaylistModel.loadOrGenerate(video) 312 const playlist = await VideoStreamingPlaylistModel.loadOrGenerate(video)
@@ -344,8 +351,8 @@ async function generateHlsPlaylistCommon (options: {
344 const stats = await stat(videoFilePath) 351 const stats = await stat(videoFilePath)
345 352
346 newVideoFile.size = stats.size 353 newVideoFile.size = stats.size
347 newVideoFile.fps = await getVideoFileFPS(videoFilePath) 354 newVideoFile.fps = await getVideoStreamFPS(videoFilePath)
348 newVideoFile.metadata = await getMetadataFromFile(videoFilePath) 355 newVideoFile.metadata = await buildFileMetadata(videoFilePath)
349 356
350 await createTorrentAndSetInfoHash(playlist, newVideoFile) 357 await createTorrentAndSetInfoHash(playlist, newVideoFile)
351 358