import { checkFFmpegEncoders } from '../initializers/checker-before-init'
import { readFile, remove, writeFile } from 'fs-extra'
import { CONFIG } from '../initializers/config'
+import { VideoFileMetadata } from '@shared/models/videos/video-file-metadata'
/**
* A toolbox to play with audio
}
}
-function computeResolutionsToTranscode (videoFileHeight: number) {
+function computeResolutionsToTranscode (videoFileResolution: number) {
const resolutionsEnabled: number[] = []
const configResolutions = CONFIG.TRANSCODING.RESOLUTIONS
]
for (const resolution of resolutions) {
- if (configResolutions[resolution + 'p'] === true && videoFileHeight > resolution) {
+ if (configResolutions[resolution + 'p'] === true && videoFileResolution > resolution) {
resolutionsEnabled.push(resolution)
}
}
baseProfile = baseProfileMatrix['High'] // Fallback
}
- const level = videoStream.level.toString(16)
+ let level = videoStream.level.toString(16)
+ if (level.length === 1) level = `0${level}`
return `${videoCodec}.${baseProfile}${level}`
}
return 0
}
-async function getVideoFileBitrate (path: string) {
- return new Promise<number>((res, rej) => {
+async function getMetadataFromFile <T> (path: string, cb = metadata => metadata) {
+ return new Promise<T>((res, rej) => {
ffmpeg.ffprobe(path, (err, metadata) => {
if (err) return rej(err)
- return res(metadata.format.bit_rate)
+ return res(cb(new VideoFileMetadata(metadata)))
})
})
}
+async function getVideoFileBitrate (path: string) {
+ return getMetadataFromFile<number>(path, metadata => metadata.format.bit_rate)
+}
+
function getDurationFromVideoFile (path: string) {
- return new Promise<number>((res, rej) => {
- ffmpeg.ffprobe(path, (err, metadata) => {
- if (err) return rej(err)
+ return getMetadataFromFile<number>(path, metadata => Math.floor(metadata.format.duration))
+}
- return res(Math.floor(metadata.format.duration))
- })
- })
+function getVideoStreamFromFile (path: string) {
+ return getMetadataFromFile<any>(path, metadata => metadata.streams.find(s => s.codec_type === 'video') || null)
}
async function generateImageFromVideoFile (fromPath: string, folder: string, imageName: string, size: { width: number, height: number }) {
.sort((a, b) => fps % a - fps % b)[0]
}
+function convertWebPToJPG (path: string, destination: string): Promise<void> {
+ return new Promise<void>(async (res, rej) => {
+ try {
+ const command = ffmpeg(path).output(destination)
+
+ command.on('error', (err, stdout, stderr) => {
+ logger.error('Error in ffmpeg webp convert process.', { stdout, stderr })
+ return rej(err)
+ })
+ .on('end', () => res())
+ .run()
+ } catch (err) {
+ return rej(err)
+ }
+ })
+}
+
// ---------------------------------------------------------------------------
export {
getVideoStreamCodec,
getAudioStreamCodec,
+ convertWebPToJPG,
getVideoStreamSize,
getVideoFileResolution,
+ getMetadataFromFile,
getDurationFromVideoFile,
generateImageFromVideoFile,
TranscodeOptions,
const videoPath = getHLSVideoPath(options)
if (options.copyCodecs) command = presetCopy(command)
+ else if (options.resolution === VideoResolution.H_NOVIDEO) command = presetOnlyAudio(command)
else command = await buildx264Command(command, options)
command = command.outputOption('-hls_time 4')
await writeFile(options.outputPath, newContent)
}
-function getVideoStreamFromFile (path: string) {
- return new Promise<any>((res, rej) => {
- ffmpeg.ffprobe(path, (err, metadata) => {
- if (err) return rej(err)
-
- const videoStream = metadata.streams.find(s => s.codec_type === 'video')
- return res(videoStream || null)
- })
- })
-}
-
/**
* A slightly customised version of the 'veryfast' x264 preset
*