diff options
-rw-r--r-- | server/controllers/api/videos/upload.ts | 17 | ||||
-rw-r--r-- | server/lib/job-queue/handlers/video-import.ts | 16 | ||||
-rw-r--r-- | server/lib/transcoding/video-transcoding.ts | 1 | ||||
-rw-r--r-- | server/models/video/video-file.ts | 5 | ||||
-rw-r--r-- | shared/extra-utils/ffprobe.ts | 7 |
5 files changed, 31 insertions, 15 deletions
diff --git a/server/controllers/api/videos/upload.ts b/server/controllers/api/videos/upload.ts index 9f620c04d..ecc4dfa37 100644 --- a/server/controllers/api/videos/upload.ts +++ b/server/controllers/api/videos/upload.ts | |||
@@ -19,15 +19,16 @@ import { buildNextVideoState } from '@server/lib/video-state' | |||
19 | import { openapiOperationDoc } from '@server/middlewares/doc' | 19 | import { openapiOperationDoc } from '@server/middlewares/doc' |
20 | import { MVideo, MVideoFile, MVideoFullLight } from '@server/types/models' | 20 | import { MVideo, MVideoFile, MVideoFullLight } from '@server/types/models' |
21 | import { getLowercaseExtension, uuidToShort } from '@shared/core-utils' | 21 | import { getLowercaseExtension, uuidToShort } from '@shared/core-utils' |
22 | import { isAudioFile } from '@shared/extra-utils' | ||
22 | import { VideoCreate, VideoState } from '../../../../shared' | 23 | import { VideoCreate, VideoState } from '../../../../shared' |
23 | import { HttpStatusCode } from '../../../../shared/models' | 24 | import { HttpStatusCode, VideoResolution } from '../../../../shared/models' |
24 | import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' | 25 | import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' |
25 | import { retryTransactionWrapper } from '../../../helpers/database-utils' | 26 | import { retryTransactionWrapper } from '../../../helpers/database-utils' |
26 | import { createReqFiles } from '../../../helpers/express-utils' | 27 | import { createReqFiles } from '../../../helpers/express-utils' |
27 | import { getMetadataFromFile, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils' | 28 | import { ffprobePromise, getMetadataFromFile, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils' |
28 | import { logger, loggerTagsFactory } from '../../../helpers/logger' | 29 | import { logger, loggerTagsFactory } from '../../../helpers/logger' |
29 | import { CONFIG } from '../../../initializers/config' | 30 | import { CONFIG } from '../../../initializers/config' |
30 | import { DEFAULT_AUDIO_RESOLUTION, MIMETYPES } from '../../../initializers/constants' | 31 | import { MIMETYPES } from '../../../initializers/constants' |
31 | import { sequelizeTypescript } from '../../../initializers/database' | 32 | import { sequelizeTypescript } from '../../../initializers/database' |
32 | import { federateVideoIfNeeded } from '../../../lib/activitypub/videos' | 33 | import { federateVideoIfNeeded } from '../../../lib/activitypub/videos' |
33 | import { Notifier } from '../../../lib/notifier' | 34 | import { Notifier } from '../../../lib/notifier' |
@@ -252,11 +253,13 @@ async function buildNewFile (videoPhysicalFile: express.VideoUploadFile) { | |||
252 | metadata: await getMetadataFromFile(videoPhysicalFile.path) | 253 | metadata: await getMetadataFromFile(videoPhysicalFile.path) |
253 | }) | 254 | }) |
254 | 255 | ||
255 | if (videoFile.isAudio()) { | 256 | const probe = await ffprobePromise(videoPhysicalFile.path) |
256 | videoFile.resolution = DEFAULT_AUDIO_RESOLUTION | 257 | |
258 | if (await isAudioFile(videoPhysicalFile.path, probe)) { | ||
259 | videoFile.resolution = VideoResolution.H_NOVIDEO | ||
257 | } else { | 260 | } else { |
258 | videoFile.fps = await getVideoFileFPS(videoPhysicalFile.path) | 261 | videoFile.fps = await getVideoFileFPS(videoPhysicalFile.path, probe) |
259 | videoFile.resolution = (await getVideoFileResolution(videoPhysicalFile.path)).resolution | 262 | videoFile.resolution = (await getVideoFileResolution(videoPhysicalFile.path, probe)).resolution |
260 | } | 263 | } |
261 | 264 | ||
262 | videoFile.filename = generateWebTorrentVideoFilename(videoFile.resolution, videoFile.extname) | 265 | videoFile.filename = generateWebTorrentVideoFilename(videoFile.resolution, videoFile.extname) |
diff --git a/server/lib/job-queue/handlers/video-import.ts b/server/lib/job-queue/handlers/video-import.ts index e5730e746..11ccd47ed 100644 --- a/server/lib/job-queue/handlers/video-import.ts +++ b/server/lib/job-queue/handlers/video-import.ts | |||
@@ -21,9 +21,9 @@ import { | |||
21 | VideoImportYoutubeDLPayloadType, | 21 | VideoImportYoutubeDLPayloadType, |
22 | VideoState | 22 | VideoState |
23 | } from '../../../../shared' | 23 | } from '../../../../shared' |
24 | import { VideoImportState } from '../../../../shared/models/videos' | 24 | import { VideoImportState, VideoResolution } from '../../../../shared/models/videos' |
25 | import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' | 25 | import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' |
26 | import { getDurationFromVideoFile, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils' | 26 | import { ffprobePromise, getDurationFromVideoFile, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils' |
27 | import { logger } from '../../../helpers/logger' | 27 | import { logger } from '../../../helpers/logger' |
28 | import { getSecureTorrentName } from '../../../helpers/utils' | 28 | import { getSecureTorrentName } from '../../../helpers/utils' |
29 | import { createTorrentAndSetInfoHash, downloadWebTorrentVideo } from '../../../helpers/webtorrent' | 29 | import { createTorrentAndSetInfoHash, downloadWebTorrentVideo } from '../../../helpers/webtorrent' |
@@ -36,6 +36,7 @@ import { MThumbnail } from '../../../types/models/video/thumbnail' | |||
36 | import { federateVideoIfNeeded } from '../../activitypub/videos' | 36 | import { federateVideoIfNeeded } from '../../activitypub/videos' |
37 | import { Notifier } from '../../notifier' | 37 | import { Notifier } from '../../notifier' |
38 | import { generateVideoMiniature } from '../../thumbnail' | 38 | import { generateVideoMiniature } from '../../thumbnail' |
39 | import { isAudioFile } from '@shared/extra-utils' | ||
39 | 40 | ||
40 | async function processVideoImport (job: Job) { | 41 | async function processVideoImport (job: Job) { |
41 | const payload = job.data as VideoImportPayload | 42 | const payload = job.data as VideoImportPayload |
@@ -114,9 +115,14 @@ async function processFile (downloader: () => Promise<string>, videoImport: MVid | |||
114 | throw new Error('The user video quota is exceeded with this video to import.') | 115 | throw new Error('The user video quota is exceeded with this video to import.') |
115 | } | 116 | } |
116 | 117 | ||
117 | const { resolution } = await getVideoFileResolution(tempVideoPath) | 118 | const probe = await ffprobePromise(tempVideoPath) |
118 | const fps = await getVideoFileFPS(tempVideoPath) | 119 | |
119 | const duration = await getDurationFromVideoFile(tempVideoPath) | 120 | const { resolution } = await isAudioFile(tempVideoPath, probe) |
121 | ? await getVideoFileResolution(tempVideoPath) | ||
122 | : { resolution: VideoResolution.H_NOVIDEO } | ||
123 | |||
124 | const fps = await getVideoFileFPS(tempVideoPath, probe) | ||
125 | const duration = await getDurationFromVideoFile(tempVideoPath, probe) | ||
120 | 126 | ||
121 | // Prepare video file object for creation in database | 127 | // Prepare video file object for creation in database |
122 | const fileExt = getLowercaseExtension(tempVideoPath) | 128 | const fileExt = getLowercaseExtension(tempVideoPath) |
diff --git a/server/lib/transcoding/video-transcoding.ts b/server/lib/transcoding/video-transcoding.ts index d0db05216..9942a067b 100644 --- a/server/lib/transcoding/video-transcoding.ts +++ b/server/lib/transcoding/video-transcoding.ts | |||
@@ -169,6 +169,7 @@ function mergeAudioVideofile (video: MVideoFullLight, resolution: VideoResolutio | |||
169 | 169 | ||
170 | // Important to do this before getVideoFilename() to take in account the new file extension | 170 | // Important to do this before getVideoFilename() to take in account the new file extension |
171 | inputVideoFile.extname = newExtname | 171 | inputVideoFile.extname = newExtname |
172 | inputVideoFile.resolution = resolution | ||
172 | inputVideoFile.filename = generateWebTorrentVideoFilename(inputVideoFile.resolution, newExtname) | 173 | inputVideoFile.filename = generateWebTorrentVideoFilename(inputVideoFile.resolution, newExtname) |
173 | 174 | ||
174 | const videoOutputPath = VideoPathManager.Instance.getFSVideoFileOutputPath(video, inputVideoFile) | 175 | const videoOutputPath = VideoPathManager.Instance.getFSVideoFileOutputPath(video, inputVideoFile) |
diff --git a/server/models/video/video-file.ts b/server/models/video/video-file.ts index 2b5ec3a20..6f03fae3a 100644 --- a/server/models/video/video-file.ts +++ b/server/models/video/video-file.ts | |||
@@ -26,8 +26,8 @@ import { extractVideo } from '@server/helpers/video' | |||
26 | import { getHLSPublicFileUrl, getWebTorrentPublicFileUrl } from '@server/lib/object-storage' | 26 | import { getHLSPublicFileUrl, getWebTorrentPublicFileUrl } from '@server/lib/object-storage' |
27 | import { getFSTorrentFilePath } from '@server/lib/paths' | 27 | import { getFSTorrentFilePath } from '@server/lib/paths' |
28 | import { isStreamingPlaylist, MStreamingPlaylistVideo, MVideo, MVideoWithHost } from '@server/types/models' | 28 | import { isStreamingPlaylist, MStreamingPlaylistVideo, MVideo, MVideoWithHost } from '@server/types/models' |
29 | import { VideoResolution, VideoStorage } from '@shared/models' | ||
29 | import { AttributesOnly } from '@shared/typescript-utils' | 30 | import { AttributesOnly } from '@shared/typescript-utils' |
30 | import { VideoStorage } from '@shared/models' | ||
31 | import { | 31 | import { |
32 | isVideoFileExtnameValid, | 32 | isVideoFileExtnameValid, |
33 | isVideoFileInfoHashValid, | 33 | isVideoFileInfoHashValid, |
@@ -39,7 +39,6 @@ import { | |||
39 | LAZY_STATIC_PATHS, | 39 | LAZY_STATIC_PATHS, |
40 | MEMOIZE_LENGTH, | 40 | MEMOIZE_LENGTH, |
41 | MEMOIZE_TTL, | 41 | MEMOIZE_TTL, |
42 | MIMETYPES, | ||
43 | STATIC_DOWNLOAD_PATHS, | 42 | STATIC_DOWNLOAD_PATHS, |
44 | STATIC_PATHS, | 43 | STATIC_PATHS, |
45 | WEBSERVER | 44 | WEBSERVER |
@@ -448,7 +447,7 @@ export class VideoFileModel extends Model<Partial<AttributesOnly<VideoFileModel> | |||
448 | } | 447 | } |
449 | 448 | ||
450 | isAudio () { | 449 | isAudio () { |
451 | return !!MIMETYPES.AUDIO.EXT_MIMETYPE[this.extname] | 450 | return this.resolution === VideoResolution.H_NOVIDEO |
452 | } | 451 | } |
453 | 452 | ||
454 | isLive () { | 453 | isLive () { |
diff --git a/shared/extra-utils/ffprobe.ts b/shared/extra-utils/ffprobe.ts index 9257bbd5f..53a3aa001 100644 --- a/shared/extra-utils/ffprobe.ts +++ b/shared/extra-utils/ffprobe.ts | |||
@@ -17,6 +17,12 @@ function ffprobePromise (path: string) { | |||
17 | }) | 17 | }) |
18 | } | 18 | } |
19 | 19 | ||
20 | async function isAudioFile (path: string, existingProbe?: FfprobeData) { | ||
21 | const videoStream = await getVideoStreamFromFile(path, existingProbe) | ||
22 | |||
23 | return !videoStream | ||
24 | } | ||
25 | |||
20 | async function getAudioStream (videoPath: string, existingProbe?: FfprobeData) { | 26 | async function getAudioStream (videoPath: string, existingProbe?: FfprobeData) { |
21 | // without position, ffprobe considers the last input only | 27 | // without position, ffprobe considers the last input only |
22 | // we make it consider the first input only | 28 | // we make it consider the first input only |
@@ -174,6 +180,7 @@ export { | |||
174 | getDurationFromVideoFile, | 180 | getDurationFromVideoFile, |
175 | getAudioStream, | 181 | getAudioStream, |
176 | getVideoFileFPS, | 182 | getVideoFileFPS, |
183 | isAudioFile, | ||
177 | ffprobePromise, | 184 | ffprobePromise, |
178 | getVideoFileBitrate, | 185 | getVideoFileBitrate, |
179 | canDoQuickAudioTranscode | 186 | canDoQuickAudioTranscode |