基于Node.js按需获取任意视频的MediaSource API兼容编码信息
解决方案
核心方案:用ffprobe解析全格式媒体信息
ffprobe是FFmpeg配套的媒体分析工具,支持几乎所有主流视频格式(MP4、WEBM、OGG、MKV等),能输出机器可读的结构化数据,可直接转换成MediaSource API要求的格式。
具体实现步骤
- 部署ffprobe:可以通过系统安装FFmpeg(自带ffprobe),或使用Node.js的
fluent-ffmpeg模块(封装了ffprobe调用)。 - 获取结构化媒体数据:执行ffprobe命令,以JSON格式输出视频/音频流、容器的关键信息:
ffprobe -v quiet -print_format json -show_streams -show_format input.video - 映射为MediaSource兼容格式:从JSON结果中提取字段,拼接成标准的
type字符串:- 容器类型:根据
format.format_name映射(如mov,mp4,...对应video/mp4,webm对应video/webm) - 视频编码:
- H.264:将
codec_profile和level转十六进制,拼接为avc1.${profile}00${level}(如profile 100=64,level 40=28 →avc1.640028) - VP8/VP9:直接使用
vp8/vp9
- H.264:将
- 音频编码:
- AAC:使用
mp4a.40.2 - Opus:使用
opus - Vorbis:使用
vorbis
- AAC:使用
- 容器类型:根据
- 组合结果:将容器类型和编码字符串拼接,生成MediaSource需要的格式,例如
video/webm; codecs="vp9,opus"
Node.js代码示例(基于fluent-ffmpeg)
const ffmpeg = require('fluent-ffmpeg'); async function getMediaSourceType(filePath) { const probeData = await new Promise((resolve, reject) => { ffmpeg.ffprobe(filePath, (err, data) => err ? reject(err) : resolve(data)); }); const videoStream = probeData.streams.find(s => s.codec_type === 'video'); const audioStream = probeData.streams.find(s => s.codec_type === 'audio'); const codecs = []; // 处理视频编码 if (videoStream) { switch (videoStream.codec_name) { case 'h264': const profileHex = videoStream.codec_profile.toString(16).padStart(2, '0'); const levelHex = videoStream.level.toString(16).padStart(2, '0'); codecs.push(`avc1.${profileHex}00${levelHex}`); break; case 'vp8': case 'vp9': codecs.push(videoStream.codec_name); break; // 扩展其他编码类型(如h265等) } } // 处理音频编码 if (audioStream) { switch (audioStream.codec_name) { case 'aac': codecs.push('mp4a.40.2'); break; case 'opus': case 'vorbis': codecs.push(audioStream.codec_name); break; // 扩展其他音频编码类型 } } // 映射容器类型 let containerType = ''; const baseFormat = probeData.format.format_name.split(',')[0]; switch (baseFormat) { case 'mov,mp4,m4a,3gp,3g2,mj2': containerType = 'video/mp4'; break; case 'webm': containerType = 'video/webm'; break; case 'ogg': containerType = 'video/ogg'; break; // 扩展其他容器类型(如mkv等) } if (!containerType || codecs.length === 0) { throw new Error('无法生成MediaSource兼容的类型字符串'); } return `${containerType}; codecs="${codecs.join(',')}"`; }
额外说明
- 对于不兼容MediaSource的格式(如MKV内的MPEG-2编码等),该方法能准确检测,方便触发后续转码流程(和Plex的处理逻辑一致)。
- ffprobe仅读取媒体头信息,性能开销极低,适合实时请求场景。
内容的提问来源于stack exchange,提问作者mcbeav
相关产品推荐
相关产品推荐

