Fix audio only transcoding

This commit is contained in:
Chocobozzz 2021-12-23 10:57:55 +01:00
parent c7c6afc66d
commit 482b26231b
No known key found for this signature in database
GPG Key ID: 583A612D890159BE
5 changed files with 31 additions and 15 deletions

View 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)

View 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)

View 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)

View 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 () {

View 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