})
}
+// ---------------------------------------------------------------------------
+// Audio
+// ---------------------------------------------------------------------------
+
+const imageCodecs = new Set([
+ 'ansi', 'apng', 'bintext', 'bmp', 'brender_pix', 'dpx', 'exr', 'fits', 'gem', 'gif', 'jpeg2000', 'jpgls', 'mjpeg', 'mjpegb', 'msp2',
+ 'pam', 'pbm', 'pcx', 'pfm', 'pgm', 'pgmyuv', 'pgx', 'photocd', 'pictor', 'png', 'ppm', 'psd', 'sgi', 'sunrast', 'svg', 'targa', 'tiff',
+ 'txd', 'webp', 'xbin', 'xbm', 'xface', 'xpm', 'xwd'
+])
+
async function isAudioFile (path: string, existingProbe?: FfprobeData) {
- const videoStream = await getVideoStreamFromFile(path, existingProbe)
+ const videoStream = await getVideoStream(path, existingProbe)
+ if (!videoStream) return true
+
+ if (imageCodecs.has(videoStream.codec_name)) return true
- return !videoStream
+ return false
+}
+
+async function hasAudioStream (path: string, existingProbe?: FfprobeData) {
+ const { audioStream } = await getAudioStream(path, existingProbe)
+
+ return !!audioStream
}
async function getAudioStream (videoPath: string, existingProbe?: FfprobeData) {
}
}
-async function getVideoStreamSize (path: string, existingProbe?: FfprobeData): Promise<{ width: number, height: number }> {
- const videoStream = await getVideoStreamFromFile(path, existingProbe)
-
- return videoStream === null
- ? { width: 0, height: 0 }
- : { width: videoStream.width, height: videoStream.height }
-}
+// ---------------------------------------------------------------------------
+// Video
+// ---------------------------------------------------------------------------
-async function getVideoFileResolution (path: string, existingProbe?: FfprobeData) {
- const size = await getVideoStreamSize(path, existingProbe)
+async function getVideoStreamDimensionsInfo (path: string, existingProbe?: FfprobeData) {
+ const videoStream = await getVideoStream(path, existingProbe)
+ if (!videoStream) return undefined
return {
- width: size.width,
- height: size.height,
- ratio: Math.max(size.height, size.width) / Math.min(size.height, size.width),
- resolution: Math.min(size.height, size.width),
- isPortraitMode: size.height > size.width
+ width: videoStream.width,
+ height: videoStream.height,
+ ratio: Math.max(videoStream.height, videoStream.width) / Math.min(videoStream.height, videoStream.width),
+ resolution: Math.min(videoStream.height, videoStream.width),
+ isPortraitMode: videoStream.height > videoStream.width
}
}
-async function getVideoFileFPS (path: string, existingProbe?: FfprobeData) {
- const videoStream = await getVideoStreamFromFile(path, existingProbe)
- if (videoStream === null) return 0
+async function getVideoStreamFPS (path: string, existingProbe?: FfprobeData) {
+ const videoStream = await getVideoStream(path, existingProbe)
+ if (!videoStream) return 0
for (const key of [ 'avg_frame_rate', 'r_frame_rate' ]) {
const valuesText: string = videoStream[key]
return 0
}
-async function getMetadataFromFile (path: string, existingProbe?: FfprobeData) {
+async function buildFileMetadata (path: string, existingProbe?: FfprobeData) {
const metadata = existingProbe || await ffprobePromise(path)
return new VideoFileMetadata(metadata)
}
-async function getVideoFileBitrate (path: string, existingProbe?: FfprobeData): Promise<number> {
- const metadata = await getMetadataFromFile(path, existingProbe)
+async function getVideoStreamBitrate (path: string, existingProbe?: FfprobeData): Promise<number> {
+ const metadata = await buildFileMetadata(path, existingProbe)
let bitrate = metadata.format.bit_rate as number
if (bitrate && !isNaN(bitrate)) return bitrate
- const videoStream = await getVideoStreamFromFile(path, existingProbe)
+ const videoStream = await getVideoStream(path, existingProbe)
if (!videoStream) return undefined
bitrate = videoStream?.bit_rate
return undefined
}
-async function getDurationFromVideoFile (path: string, existingProbe?: FfprobeData) {
- const metadata = await getMetadataFromFile(path, existingProbe)
+async function getVideoStreamDuration (path: string, existingProbe?: FfprobeData) {
+ const metadata = await buildFileMetadata(path, existingProbe)
return Math.round(metadata.format.duration)
}
-async function getVideoStreamFromFile (path: string, existingProbe?: FfprobeData) {
- const metadata = await getMetadataFromFile(path, existingProbe)
-
- return metadata.streams.find(s => s.codec_type === 'video') || null
-}
-
-async function canDoQuickAudioTranscode (path: string, probe?: FfprobeData): Promise<boolean> {
- const parsedAudio = await getAudioStream(path, probe)
-
- if (!parsedAudio.audioStream) return true
-
- if (parsedAudio.audioStream['codec_name'] !== 'aac') return false
-
- const audioBitrate = parsedAudio.bitrate
- if (!audioBitrate) return false
-
- const maxAudioBitrate = getMaxAudioBitrate('aac', audioBitrate)
- if (maxAudioBitrate !== -1 && audioBitrate > maxAudioBitrate) return false
-
- const channelLayout = parsedAudio.audioStream['channel_layout']
- // Causes playback issues with Chrome
- if (!channelLayout || channelLayout === 'unknown') return false
+async function getVideoStream (path: string, existingProbe?: FfprobeData) {
+ const metadata = await buildFileMetadata(path, existingProbe)
- return true
+ return metadata.streams.find(s => s.codec_type === 'video')
}
// ---------------------------------------------------------------------------
export {
- getVideoStreamSize,
- getVideoFileResolution,
- getMetadataFromFile,
+ getVideoStreamDimensionsInfo,
+ buildFileMetadata,
getMaxAudioBitrate,
- getVideoStreamFromFile,
- getDurationFromVideoFile,
+ getVideoStream,
+ getVideoStreamDuration,
getAudioStream,
- getVideoFileFPS,
+ getVideoStreamFPS,
isAudioFile,
ffprobePromise,
- getVideoFileBitrate,
- canDoQuickAudioTranscode
+ getVideoStreamBitrate,
+ hasAudioStream
}