diff --git a/packages/ffmpeg/src/ffprobe.ts b/packages/ffmpeg/src/ffprobe.ts index f995e7925..1cfee9280 100644 --- a/packages/ffmpeg/src/ffprobe.ts +++ b/packages/ffmpeg/src/ffprobe.ts @@ -172,15 +172,21 @@ async function getVideoStream (path: string, existingProbe?: FfprobeData) { // Chapters // --------------------------------------------------------------------------- -async function getChaptersFromContainer (path: string, existingProbe?: FfprobeData) { - const metadata = existingProbe || await ffprobePromise(path) +async function getChaptersFromContainer (options: { + path: string + maxTitleLength: number + ffprobe?: FfprobeData +}) { + const { path, maxTitleLength, ffprobe } = options + + const metadata = ffprobe || await ffprobePromise(path) if (!Array.isArray(metadata?.chapters)) return [] return metadata.chapters .map(c => ({ - timecode: c.start_time, - title: c['TAG:title'] + timecode: Math.round(c.start_time), + title: (c['TAG:title'] || '').slice(0, maxTitleLength) })) } diff --git a/server/core/controllers/api/videos/upload.ts b/server/core/controllers/api/videos/upload.ts index 3d87deb1b..2487cfd2e 100644 --- a/server/core/controllers/api/videos/upload.ts +++ b/server/core/controllers/api/videos/upload.ts @@ -19,7 +19,7 @@ import { HttpStatusCode, VideoCreate, VideoPrivacy, VideoState } from '@peertube import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger.js' import { createReqFiles } from '../../../helpers/express-utils.js' import { logger, loggerTagsFactory } from '../../../helpers/logger.js' -import { MIMETYPES } from '../../../initializers/constants.js' +import { CONSTRAINTS_FIELDS, MIMETYPES } from '../../../initializers/constants.js' import { sequelizeTypescript } from '../../../initializers/database.js' import { Hooks } from '../../../lib/plugins/hooks.js' import { generateLocalVideoMiniature } from '../../../lib/thumbnail.js' @@ -145,7 +145,10 @@ async function addVideo (options: { const videoFile = await buildNewFile({ path: videoPhysicalFile.path, mode: 'web-video' }) const originalFilename = videoPhysicalFile.originalname - const containerChapters = await getChaptersFromContainer(videoPhysicalFile.path) + const containerChapters = await getChaptersFromContainer({ + path: videoPhysicalFile.path, + maxTitleLength: CONSTRAINTS_FIELDS.VIDEO_CHAPTERS.TITLE.max + }) logger.debug(`Got ${containerChapters.length} chapters from video "${video.name}" container`, { containerChapters, ...lTags(video.uuid) }) // Move physical file diff --git a/server/core/lib/job-queue/handlers/video-import.ts b/server/core/lib/job-queue/handlers/video-import.ts index 09d974e90..dfeadc8ef 100644 --- a/server/core/lib/job-queue/handlers/video-import.ts +++ b/server/core/lib/job-queue/handlers/video-import.ts @@ -41,7 +41,7 @@ import { import { logger } from '../../../helpers/logger.js' import { getSecureTorrentName } from '../../../helpers/utils.js' import { createTorrentAndSetInfoHash, downloadWebTorrentVideo } from '../../../helpers/webtorrent.js' -import { JOB_TTL } from '../../../initializers/constants.js' +import { CONSTRAINTS_FIELDS, JOB_TTL } from '../../../initializers/constants.js' import { sequelizeTypescript } from '../../../initializers/database.js' import { VideoFileModel } from '../../../models/video/video-file.js' import { VideoImportModel } from '../../../models/video/video-import.js' @@ -143,16 +143,20 @@ async function processFile (downloader: () => Promise, videoImport: MVid throw new Error('The user video quota is exceeded with this video to import.') } - const probe = await ffprobePromise(tempVideoPath) + const ffprobe = await ffprobePromise(tempVideoPath) - const { resolution } = await isAudioFile(tempVideoPath, probe) + const { resolution } = await isAudioFile(tempVideoPath, ffprobe) ? { resolution: VideoResolution.H_NOVIDEO } - : await getVideoStreamDimensionsInfo(tempVideoPath, probe) + : await getVideoStreamDimensionsInfo(tempVideoPath, ffprobe) - const fps = await getVideoStreamFPS(tempVideoPath, probe) - const duration = await getVideoStreamDuration(tempVideoPath, probe) + const fps = await getVideoStreamFPS(tempVideoPath, ffprobe) + const duration = await getVideoStreamDuration(tempVideoPath, ffprobe) - const containerChapters = await getChaptersFromContainer(tempVideoPath, probe) + const containerChapters = await getChaptersFromContainer({ + path: tempVideoPath, + maxTitleLength: CONSTRAINTS_FIELDS.VIDEO_CHAPTERS.TITLE.max, + ffprobe + }) // Prepare video file object for creation in database const fileExt = getLowercaseExtension(tempVideoPath)