diff options
-rw-r--r-- | server/controllers/api/videos/index.ts | 6 | ||||
-rw-r--r-- | server/helpers/ffmpeg-utils.ts | 14 | ||||
-rw-r--r-- | server/initializers/migrations/0075-video-resolutions.ts | 4 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/video-file.ts | 11 | ||||
-rw-r--r-- | server/models/video/video.ts | 11 |
5 files changed, 27 insertions, 19 deletions
diff --git a/server/controllers/api/videos/index.ts b/server/controllers/api/videos/index.ts index c3d3acd26..10b309cd1 100644 --- a/server/controllers/api/videos/index.ts +++ b/server/controllers/api/videos/index.ts | |||
@@ -3,7 +3,7 @@ import { extname, join } from 'path' | |||
3 | import { VideoCreate, VideoPrivacy, VideoUpdate } from '../../../../shared' | 3 | import { VideoCreate, VideoPrivacy, VideoUpdate } from '../../../../shared' |
4 | import { renamePromise } from '../../../helpers/core-utils' | 4 | import { renamePromise } from '../../../helpers/core-utils' |
5 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 5 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
6 | import { getVideoFileHeight } from '../../../helpers/ffmpeg-utils' | 6 | import { getVideoFileResolution } from '../../../helpers/ffmpeg-utils' |
7 | import { processImage } from '../../../helpers/image-utils' | 7 | import { processImage } from '../../../helpers/image-utils' |
8 | import { logger } from '../../../helpers/logger' | 8 | import { logger } from '../../../helpers/logger' |
9 | import { createReqFiles, getFormattedObjects, getServerActor, resetSequelizeInstance } from '../../../helpers/utils' | 9 | import { createReqFiles, getFormattedObjects, getServerActor, resetSequelizeInstance } from '../../../helpers/utils' |
@@ -187,11 +187,11 @@ async function addVideo (req: express.Request, res: express.Response, videoPhysi | |||
187 | const video = new VideoModel(videoData) | 187 | const video = new VideoModel(videoData) |
188 | video.url = getVideoActivityPubUrl(video) | 188 | video.url = getVideoActivityPubUrl(video) |
189 | 189 | ||
190 | const videoFileHeight = await getVideoFileHeight(videoPhysicalFile.path) | 190 | const { videoFileResolution } = await getVideoFileResolution(videoPhysicalFile.path) |
191 | 191 | ||
192 | const videoFileData = { | 192 | const videoFileData = { |
193 | extname: extname(videoPhysicalFile.filename), | 193 | extname: extname(videoPhysicalFile.filename), |
194 | resolution: videoFileHeight, | 194 | resolution: videoFileResolution, |
195 | size: videoPhysicalFile.size | 195 | size: videoPhysicalFile.size |
196 | } | 196 | } |
197 | const videoFile = new VideoFileModel(videoFileData) | 197 | const videoFile = new VideoFileModel(videoFileData) |
diff --git a/server/helpers/ffmpeg-utils.ts b/server/helpers/ffmpeg-utils.ts index b0f95797c..4f75ba5a8 100644 --- a/server/helpers/ffmpeg-utils.ts +++ b/server/helpers/ffmpeg-utils.ts | |||
@@ -6,9 +6,13 @@ import { unlinkPromise } from './core-utils' | |||
6 | import { processImage } from './image-utils' | 6 | import { processImage } from './image-utils' |
7 | import { logger } from './logger' | 7 | import { logger } from './logger' |
8 | 8 | ||
9 | async function getVideoFileHeight (path: string) { | 9 | async function getVideoFileResolution (path: string) { |
10 | const videoStream = await getVideoFileStream(path) | 10 | const videoStream = await getVideoFileStream(path) |
11 | return videoStream.height | 11 | |
12 | return { | ||
13 | videoFileResolution: Math.min(videoStream.height, videoStream.width), | ||
14 | isPortraitMode: videoStream.height > videoStream.width | ||
15 | } | ||
12 | } | 16 | } |
13 | 17 | ||
14 | async function getVideoFileFPS (path: string) { | 18 | async function getVideoFileFPS (path: string) { |
@@ -74,6 +78,7 @@ type TranscodeOptions = { | |||
74 | inputPath: string | 78 | inputPath: string |
75 | outputPath: string | 79 | outputPath: string |
76 | resolution?: VideoResolution | 80 | resolution?: VideoResolution |
81 | isPortraitMode?: boolean | ||
77 | } | 82 | } |
78 | 83 | ||
79 | function transcode (options: TranscodeOptions) { | 84 | function transcode (options: TranscodeOptions) { |
@@ -90,7 +95,8 @@ function transcode (options: TranscodeOptions) { | |||
90 | if (fps > MAX_VIDEO_TRANSCODING_FPS) command = command.withFPS(MAX_VIDEO_TRANSCODING_FPS) | 95 | if (fps > MAX_VIDEO_TRANSCODING_FPS) command = command.withFPS(MAX_VIDEO_TRANSCODING_FPS) |
91 | 96 | ||
92 | if (options.resolution !== undefined) { | 97 | if (options.resolution !== undefined) { |
93 | const size = `?x${options.resolution}` // '?x720' for example | 98 | // '?x720' or '720x?' for example |
99 | const size = options.isPortraitMode === true ? `${options.resolution}x?` : `?x${options.resolution}` | ||
94 | command = command.size(size) | 100 | command = command.size(size) |
95 | } | 101 | } |
96 | 102 | ||
@@ -103,7 +109,7 @@ function transcode (options: TranscodeOptions) { | |||
103 | // --------------------------------------------------------------------------- | 109 | // --------------------------------------------------------------------------- |
104 | 110 | ||
105 | export { | 111 | export { |
106 | getVideoFileHeight, | 112 | getVideoFileResolution, |
107 | getDurationFromVideoFile, | 113 | getDurationFromVideoFile, |
108 | generateImageFromVideoFile, | 114 | generateImageFromVideoFile, |
109 | transcode, | 115 | transcode, |
diff --git a/server/initializers/migrations/0075-video-resolutions.ts b/server/initializers/migrations/0075-video-resolutions.ts index e7d8a2876..54ea852b1 100644 --- a/server/initializers/migrations/0075-video-resolutions.ts +++ b/server/initializers/migrations/0075-video-resolutions.ts | |||
@@ -3,7 +3,7 @@ import { join } from 'path' | |||
3 | 3 | ||
4 | import { readdirPromise, renamePromise } from '../../helpers/core-utils' | 4 | import { readdirPromise, renamePromise } from '../../helpers/core-utils' |
5 | import { CONFIG } from '../../initializers/constants' | 5 | import { CONFIG } from '../../initializers/constants' |
6 | import { getVideoFileHeight } from '../../helpers/ffmpeg-utils' | 6 | import { getVideoFileResolution } from '../../helpers/ffmpeg-utils' |
7 | 7 | ||
8 | function up (utils: { | 8 | function up (utils: { |
9 | transaction: Sequelize.Transaction, | 9 | transaction: Sequelize.Transaction, |
@@ -27,7 +27,7 @@ function up (utils: { | |||
27 | const uuid = matches[1] | 27 | const uuid = matches[1] |
28 | const ext = matches[2] | 28 | const ext = matches[2] |
29 | 29 | ||
30 | const p = getVideoFileHeight(join(videoFileDir, videoFile)) | 30 | const p = getVideoFileResolution(join(videoFileDir, videoFile)) |
31 | .then(height => { | 31 | .then(height => { |
32 | const oldTorrentName = uuid + '.torrent' | 32 | const oldTorrentName = uuid + '.torrent' |
33 | const newTorrentName = uuid + '-' + height + '.torrent' | 33 | const newTorrentName = uuid + '-' + height + '.torrent' |
diff --git a/server/lib/job-queue/handlers/video-file.ts b/server/lib/job-queue/handlers/video-file.ts index 5294483bd..bd9412290 100644 --- a/server/lib/job-queue/handlers/video-file.ts +++ b/server/lib/job-queue/handlers/video-file.ts | |||
@@ -11,7 +11,8 @@ import { JobQueue } from '../job-queue' | |||
11 | 11 | ||
12 | export type VideoFilePayload = { | 12 | export type VideoFilePayload = { |
13 | videoUUID: string | 13 | videoUUID: string |
14 | resolution?: VideoResolution | 14 | resolution?: VideoResolution, |
15 | isPortraitMode?: boolean | ||
15 | } | 16 | } |
16 | 17 | ||
17 | async function processVideoFile (job: kue.Job) { | 18 | async function processVideoFile (job: kue.Job) { |
@@ -27,7 +28,7 @@ async function processVideoFile (job: kue.Job) { | |||
27 | 28 | ||
28 | // Transcoding in other resolution | 29 | // Transcoding in other resolution |
29 | if (payload.resolution) { | 30 | if (payload.resolution) { |
30 | await video.transcodeOriginalVideofile(payload.resolution) | 31 | await video.transcodeOriginalVideofile(payload.resolution, payload.isPortraitMode) |
31 | await onVideoFileTranscoderSuccess(video) | 32 | await onVideoFileTranscoderSuccess(video) |
32 | } else { | 33 | } else { |
33 | await video.optimizeOriginalVideofile() | 34 | await video.optimizeOriginalVideofile() |
@@ -66,12 +67,12 @@ async function onVideoFileOptimizerSuccess (video: VideoModel) { | |||
66 | await shareVideoByServerAndChannel(video, undefined) | 67 | await shareVideoByServerAndChannel(video, undefined) |
67 | } | 68 | } |
68 | 69 | ||
69 | const originalFileHeight = await videoDatabase.getOriginalFileHeight() | 70 | const { videoFileResolution } = await videoDatabase.getOriginalFileResolution() |
70 | 71 | ||
71 | // Create transcoding jobs if there are enabled resolutions | 72 | // Create transcoding jobs if there are enabled resolutions |
72 | const resolutionsEnabled = computeResolutionsToTranscode(originalFileHeight) | 73 | const resolutionsEnabled = computeResolutionsToTranscode(videoFileResolution) |
73 | logger.info( | 74 | logger.info( |
74 | 'Resolutions computed for video %s and origin file height of %d.', videoDatabase.uuid, originalFileHeight, | 75 | 'Resolutions computed for video %s and origin file height of %d.', videoDatabase.uuid, videoFileResolution, |
75 | { resolutions: resolutionsEnabled } | 76 | { resolutions: resolutionsEnabled } |
76 | ) | 77 | ) |
77 | 78 | ||
diff --git a/server/models/video/video.ts b/server/models/video/video.ts index 4e065e377..80ca513bf 100644 --- a/server/models/video/video.ts +++ b/server/models/video/video.ts | |||
@@ -42,7 +42,7 @@ import { | |||
42 | isVideoNameValid, | 42 | isVideoNameValid, |
43 | isVideoPrivacyValid, isVideoSupportValid | 43 | isVideoPrivacyValid, isVideoSupportValid |
44 | } from '../../helpers/custom-validators/videos' | 44 | } from '../../helpers/custom-validators/videos' |
45 | import { generateImageFromVideoFile, getVideoFileHeight, transcode } from '../../helpers/ffmpeg-utils' | 45 | import { generateImageFromVideoFile, getVideoFileResolution, transcode } from '../../helpers/ffmpeg-utils' |
46 | import { logger } from '../../helpers/logger' | 46 | import { logger } from '../../helpers/logger' |
47 | import { getServerActor } from '../../helpers/utils' | 47 | import { getServerActor } from '../../helpers/utils' |
48 | import { | 48 | import { |
@@ -1140,7 +1140,7 @@ export class VideoModel extends Model<VideoModel> { | |||
1140 | } | 1140 | } |
1141 | } | 1141 | } |
1142 | 1142 | ||
1143 | transcodeOriginalVideofile = async function (resolution: VideoResolution) { | 1143 | transcodeOriginalVideofile = async function (resolution: VideoResolution, isPortraitMode: boolean) { |
1144 | const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR | 1144 | const videosDirectory = CONFIG.STORAGE.VIDEOS_DIR |
1145 | const extname = '.mp4' | 1145 | const extname = '.mp4' |
1146 | 1146 | ||
@@ -1158,7 +1158,8 @@ export class VideoModel extends Model<VideoModel> { | |||
1158 | const transcodeOptions = { | 1158 | const transcodeOptions = { |
1159 | inputPath: videoInputPath, | 1159 | inputPath: videoInputPath, |
1160 | outputPath: videoOutputPath, | 1160 | outputPath: videoOutputPath, |
1161 | resolution | 1161 | resolution, |
1162 | isPortraitMode | ||
1162 | } | 1163 | } |
1163 | 1164 | ||
1164 | await transcode(transcodeOptions) | 1165 | await transcode(transcodeOptions) |
@@ -1174,10 +1175,10 @@ export class VideoModel extends Model<VideoModel> { | |||
1174 | this.VideoFiles.push(newVideoFile) | 1175 | this.VideoFiles.push(newVideoFile) |
1175 | } | 1176 | } |
1176 | 1177 | ||
1177 | getOriginalFileHeight () { | 1178 | getOriginalFileResolution () { |
1178 | const originalFilePath = this.getVideoFilePath(this.getOriginalFile()) | 1179 | const originalFilePath = this.getVideoFilePath(this.getOriginalFile()) |
1179 | 1180 | ||
1180 | return getVideoFileHeight(originalFilePath) | 1181 | return getVideoFileResolution(originalFilePath) |
1181 | } | 1182 | } |
1182 | 1183 | ||
1183 | getDescriptionPath () { | 1184 | getDescriptionPath () { |