From 482b26231b4e39234f107b8400ef606c5f003c55 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Thu, 23 Dec 2021 10:57:55 +0100 Subject: Fix audio only transcoding --- server/controllers/api/videos/upload.ts | 17 ++++++++++------- server/lib/job-queue/handlers/video-import.ts | 16 +++++++++++----- server/lib/transcoding/video-transcoding.ts | 1 + server/models/video/video-file.ts | 5 ++--- 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' import { openapiOperationDoc } from '@server/middlewares/doc' import { MVideo, MVideoFile, MVideoFullLight } from '@server/types/models' import { getLowercaseExtension, uuidToShort } from '@shared/core-utils' +import { isAudioFile } from '@shared/extra-utils' import { VideoCreate, VideoState } from '../../../../shared' -import { HttpStatusCode } from '../../../../shared/models' +import { HttpStatusCode, VideoResolution } from '../../../../shared/models' import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger' import { retryTransactionWrapper } from '../../../helpers/database-utils' import { createReqFiles } from '../../../helpers/express-utils' -import { getMetadataFromFile, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils' +import { ffprobePromise, getMetadataFromFile, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils' import { logger, loggerTagsFactory } from '../../../helpers/logger' import { CONFIG } from '../../../initializers/config' -import { DEFAULT_AUDIO_RESOLUTION, MIMETYPES } from '../../../initializers/constants' +import { MIMETYPES } from '../../../initializers/constants' import { sequelizeTypescript } from '../../../initializers/database' import { federateVideoIfNeeded } from '../../../lib/activitypub/videos' import { Notifier } from '../../../lib/notifier' @@ -252,11 +253,13 @@ async function buildNewFile (videoPhysicalFile: express.VideoUploadFile) { metadata: await getMetadataFromFile(videoPhysicalFile.path) }) - if (videoFile.isAudio()) { - videoFile.resolution = DEFAULT_AUDIO_RESOLUTION + const probe = await ffprobePromise(videoPhysicalFile.path) + + if (await isAudioFile(videoPhysicalFile.path, probe)) { + videoFile.resolution = VideoResolution.H_NOVIDEO } else { - videoFile.fps = await getVideoFileFPS(videoPhysicalFile.path) - videoFile.resolution = (await getVideoFileResolution(videoPhysicalFile.path)).resolution + videoFile.fps = await getVideoFileFPS(videoPhysicalFile.path, probe) + videoFile.resolution = (await getVideoFileResolution(videoPhysicalFile.path, probe)).resolution } 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 { VideoImportYoutubeDLPayloadType, VideoState } from '../../../../shared' -import { VideoImportState } from '../../../../shared/models/videos' +import { VideoImportState, VideoResolution } from '../../../../shared/models/videos' import { ThumbnailType } from '../../../../shared/models/videos/thumbnail.type' -import { getDurationFromVideoFile, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils' +import { ffprobePromise, getDurationFromVideoFile, getVideoFileFPS, getVideoFileResolution } from '../../../helpers/ffprobe-utils' import { logger } from '../../../helpers/logger' import { getSecureTorrentName } from '../../../helpers/utils' import { createTorrentAndSetInfoHash, downloadWebTorrentVideo } from '../../../helpers/webtorrent' @@ -36,6 +36,7 @@ import { MThumbnail } from '../../../types/models/video/thumbnail' import { federateVideoIfNeeded } from '../../activitypub/videos' import { Notifier } from '../../notifier' import { generateVideoMiniature } from '../../thumbnail' +import { isAudioFile } from '@shared/extra-utils' async function processVideoImport (job: Job) { const payload = job.data as VideoImportPayload @@ -114,9 +115,14 @@ async function processFile (downloader: () => Promise, videoImport: MVid throw new Error('The user video quota is exceeded with this video to import.') } - const { resolution } = await getVideoFileResolution(tempVideoPath) - const fps = await getVideoFileFPS(tempVideoPath) - const duration = await getDurationFromVideoFile(tempVideoPath) + const probe = await ffprobePromise(tempVideoPath) + + const { resolution } = await isAudioFile(tempVideoPath, probe) + ? await getVideoFileResolution(tempVideoPath) + : { resolution: VideoResolution.H_NOVIDEO } + + const fps = await getVideoFileFPS(tempVideoPath, probe) + const duration = await getDurationFromVideoFile(tempVideoPath, probe) // Prepare video file object for creation in database 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 // Important to do this before getVideoFilename() to take in account the new file extension inputVideoFile.extname = newExtname + inputVideoFile.resolution = resolution inputVideoFile.filename = generateWebTorrentVideoFilename(inputVideoFile.resolution, newExtname) 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' import { getHLSPublicFileUrl, getWebTorrentPublicFileUrl } from '@server/lib/object-storage' import { getFSTorrentFilePath } from '@server/lib/paths' import { isStreamingPlaylist, MStreamingPlaylistVideo, MVideo, MVideoWithHost } from '@server/types/models' +import { VideoResolution, VideoStorage } from '@shared/models' import { AttributesOnly } from '@shared/typescript-utils' -import { VideoStorage } from '@shared/models' import { isVideoFileExtnameValid, isVideoFileInfoHashValid, @@ -39,7 +39,6 @@ import { LAZY_STATIC_PATHS, MEMOIZE_LENGTH, MEMOIZE_TTL, - MIMETYPES, STATIC_DOWNLOAD_PATHS, STATIC_PATHS, WEBSERVER @@ -448,7 +447,7 @@ export class VideoFileModel extends Model } isAudio () { - return !!MIMETYPES.AUDIO.EXT_MIMETYPE[this.extname] + return this.resolution === VideoResolution.H_NOVIDEO } 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) { }) } +async function isAudioFile (path: string, existingProbe?: FfprobeData) { + const videoStream = await getVideoStreamFromFile(path, existingProbe) + + return !videoStream +} + async function getAudioStream (videoPath: string, existingProbe?: FfprobeData) { // without position, ffprobe considers the last input only // we make it consider the first input only @@ -174,6 +180,7 @@ export { getDurationFromVideoFile, getAudioStream, getVideoFileFPS, + isAudioFile, ffprobePromise, getVideoFileBitrate, canDoQuickAudioTranscode -- cgit v1.2.3