1 import { FfprobeData } from 'fluent-ffmpeg'
2 import { getAudioStream, getVideoStream } from '@shared/ffmpeg'
3 import { logger } from '../logger'
4 import { forceNumber } from '@shared/core-utils'
6 export async function getVideoStreamCodec (path: string) {
7 const videoStream = await getVideoStream(path)
8 if (!videoStream) return ''
10 const videoCodec = videoStream.codec_tag_string
12 if (videoCodec === 'vp09') return 'vp09.00.50.08'
13 if (videoCodec === 'hev1') return 'hev1.1.6.L93.B0'
15 const baseProfileMatrix = {
28 let baseProfile = baseProfileMatrix[videoCodec][videoStream.profile]
30 logger.warn('Cannot get video profile codec of %s.', path, { videoStream })
31 baseProfile = baseProfileMatrix[videoCodec]['High'] // Fallback
34 if (videoCodec === 'av01') {
35 let level = videoStream.level.toString()
36 if (level.length === 1) level = `0${level}`
38 // Guess the tier indicator and bit depth
39 return `${videoCodec}.${baseProfile}.${level}M.08`
42 let level = forceNumber(videoStream.level).toString(16)
43 if (level.length === 1) level = `0${level}`
45 // Default, h264 codec
46 return `${videoCodec}.${baseProfile}${level}`
49 export async function getAudioStreamCodec (path: string, existingProbe?: FfprobeData) {
50 const { audioStream } = await getAudioStream(path, existingProbe)
52 if (!audioStream) return ''
54 const audioCodecName = audioStream.codec_name
56 if (audioCodecName === 'opus') return 'opus'
57 if (audioCodecName === 'vorbis') return 'vorbis'
58 if (audioCodecName === 'aac') return 'mp4a.40.2'
59 if (audioCodecName === 'mp3') return 'mp4a.40.34'
61 logger.warn('Cannot get audio codec of %s.', path, { audioStream })
63 return 'mp4a.40.2' // Fallback