mirror of https://github.com/Chocobozzz/PeerTube
Fix upload with chapters having non int timecode
parent
ed0852f1b8
commit
58fda6d416
|
@ -172,15 +172,21 @@ async function getVideoStream (path: string, existingProbe?: FfprobeData) {
|
||||||
// Chapters
|
// Chapters
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
||||||
async function getChaptersFromContainer (path: string, existingProbe?: FfprobeData) {
|
async function getChaptersFromContainer (options: {
|
||||||
const metadata = existingProbe || await ffprobePromise(path)
|
path: string
|
||||||
|
maxTitleLength: number
|
||||||
|
ffprobe?: FfprobeData
|
||||||
|
}) {
|
||||||
|
const { path, maxTitleLength, ffprobe } = options
|
||||||
|
|
||||||
|
const metadata = ffprobe || await ffprobePromise(path)
|
||||||
|
|
||||||
if (!Array.isArray(metadata?.chapters)) return []
|
if (!Array.isArray(metadata?.chapters)) return []
|
||||||
|
|
||||||
return metadata.chapters
|
return metadata.chapters
|
||||||
.map(c => ({
|
.map(c => ({
|
||||||
timecode: c.start_time,
|
timecode: Math.round(c.start_time),
|
||||||
title: c['TAG:title']
|
title: (c['TAG:title'] || '').slice(0, maxTitleLength)
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ import { HttpStatusCode, VideoCreate, VideoPrivacy, VideoState } from '@peertube
|
||||||
import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger.js'
|
import { auditLoggerFactory, getAuditIdFromRes, VideoAuditView } from '../../../helpers/audit-logger.js'
|
||||||
import { createReqFiles } from '../../../helpers/express-utils.js'
|
import { createReqFiles } from '../../../helpers/express-utils.js'
|
||||||
import { logger, loggerTagsFactory } from '../../../helpers/logger.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 { sequelizeTypescript } from '../../../initializers/database.js'
|
||||||
import { Hooks } from '../../../lib/plugins/hooks.js'
|
import { Hooks } from '../../../lib/plugins/hooks.js'
|
||||||
import { generateLocalVideoMiniature } from '../../../lib/thumbnail.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 videoFile = await buildNewFile({ path: videoPhysicalFile.path, mode: 'web-video' })
|
||||||
const originalFilename = videoPhysicalFile.originalname
|
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) })
|
logger.debug(`Got ${containerChapters.length} chapters from video "${video.name}" container`, { containerChapters, ...lTags(video.uuid) })
|
||||||
|
|
||||||
// Move physical file
|
// Move physical file
|
||||||
|
|
|
@ -41,7 +41,7 @@ import {
|
||||||
import { logger } from '../../../helpers/logger.js'
|
import { logger } from '../../../helpers/logger.js'
|
||||||
import { getSecureTorrentName } from '../../../helpers/utils.js'
|
import { getSecureTorrentName } from '../../../helpers/utils.js'
|
||||||
import { createTorrentAndSetInfoHash, downloadWebTorrentVideo } from '../../../helpers/webtorrent.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 { sequelizeTypescript } from '../../../initializers/database.js'
|
||||||
import { VideoFileModel } from '../../../models/video/video-file.js'
|
import { VideoFileModel } from '../../../models/video/video-file.js'
|
||||||
import { VideoImportModel } from '../../../models/video/video-import.js'
|
import { VideoImportModel } from '../../../models/video/video-import.js'
|
||||||
|
@ -143,16 +143,20 @@ async function processFile (downloader: () => Promise<string>, videoImport: MVid
|
||||||
throw new Error('The user video quota is exceeded with this video to import.')
|
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 }
|
? { resolution: VideoResolution.H_NOVIDEO }
|
||||||
: await getVideoStreamDimensionsInfo(tempVideoPath, probe)
|
: await getVideoStreamDimensionsInfo(tempVideoPath, ffprobe)
|
||||||
|
|
||||||
const fps = await getVideoStreamFPS(tempVideoPath, probe)
|
const fps = await getVideoStreamFPS(tempVideoPath, ffprobe)
|
||||||
const duration = await getVideoStreamDuration(tempVideoPath, probe)
|
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
|
// Prepare video file object for creation in database
|
||||||
const fileExt = getLowercaseExtension(tempVideoPath)
|
const fileExt = getLowercaseExtension(tempVideoPath)
|
||||||
|
|
Loading…
Reference in New Issue