]> git.immae.eu Git - github/Chocobozzz/PeerTube.git/commitdiff
Fix audio only transcoding
authorChocobozzz <me@florianbigard.com>
Thu, 23 Dec 2021 09:57:55 +0000 (10:57 +0100)
committerChocobozzz <me@florianbigard.com>
Thu, 23 Dec 2021 09:57:55 +0000 (10:57 +0100)
server/controllers/api/videos/upload.ts
server/lib/job-queue/handlers/video-import.ts
server/lib/transcoding/video-transcoding.ts
server/models/video/video-file.ts
shared/extra-utils/ffprobe.ts

index 9f620c04d3abf79b6b38ea889824abdee6edc043..ecc4dfa3702db1bd5fc69cb06aa7c9995e432d57 100644 (file)
@@ -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)
index e5730e746a288ca97b918187e9324ab68215c642..11ccd47edd6cbbe51cb971e807cbd236386bb976 100644 (file)
@@ -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<string>, 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)
index d0db052163a971bcb6b111570176a2d63267ebfd..9942a067b08e40d75aea435524e0214e4dd9fe28 100644 (file)
@@ -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)
index 2b5ec3a20b88a8522d76c00a2326de81630e812a..6f03fae3a501bf986a7dbb774bb7e2d7800060bf 100644 (file)
@@ -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<Partial<AttributesOnly<VideoFileModel>
   }
 
   isAudio () {
-    return !!MIMETYPES.AUDIO.EXT_MIMETYPE[this.extname]
+    return this.resolution === VideoResolution.H_NOVIDEO
   }
 
   isLive () {
index 9257bbd5fa0d26992d465807b1d4a119d9b176b7..53a3aa0010758bd47f974e79941855668514355e 100644 (file)
@@ -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