ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Filestash 视频转码插件 libav 与 ffmpeg 两种实现策略有何差异

Filestash 视频转码插件 libav 与 ffmpeg 两种实现策略有何差异 Filestash 视频转码插件 libav 与 ffmpeg 两种实现策略有何差异【免费下载链接】filestash:file_folder: Universal File Storage Client项目地址: https://gitcode.com/GitHub_Trending/fi/filestashFilestash 的视频转码插件plg_video_transcoder在按需转码HLS功能上维护着两套并存的实现一套通过 CGO 直连 libav C 库另一套调用系统里的 ffmpeg CLI。它们由编译条件决定而不是由运行配置决定。如果你要二次开发或定制这个插件比如改分段长度、换编码器第一步就是搞清楚当前二进制里跑的是哪一套、两套在分段、播放列表结构和外部依赖上分别做了什么。策略由编译期 CGO 开关决定插件入口 index.go 只调用两个与具体实现无关的函数isActive()判断插件是否可用servePlaylist/serveHLSChunks提供播放列表和分段。具体走哪套实现由构建标签在编译期二选一index.cgo.go 顶部是//go:build cgo启用 CGO 时生效调用libav包的RegisterRoutes和MasterPlaylist其isActive()恒返回trueindex.nocgo.go 顶部是//go:build !cgo关闭 CGO 时生效调用ffmpeg包isActive()会检查ffmpeg、ffprobe两个二进制是否存在于$PATH。所以同一个仓库CGO_ENABLED开与关构建出来的 Filestash转码路径完全不同。插件在 server/plugin/index.go 中被匿名导入注册无需额外插件安装步骤。libav 策略CGO 直连 C 库音视频在同一分段里libav 实现在 libav/transcode.go 中通过 cgo 调用 C 侧的转码逻辑编译依赖在文件头部声明// #cgo pkg-config: libavformat libavcodec libavfilter libavutil libswscale libswresample也就是说构建环境需要通过 pkg-config 找到 libavformat、libavcodec、libavfilter、libavutil、libswscale、libswresample 六个库。关键行为分段参数在 libav/constant.goHLS_SEGMENT_LENGTH默认 5 秒VIDEO_MAX_HEIGHT 720AUDIO_BITRATE 128000。若runtime.NumCPU() 4 runtime.GOARCH arm源码注释说明如树莓派分段长度自动改为 10 秒。每个分段通过ff_transcode_segment一次转码出音视频合一的 mpegts 分段音频码率和最大高度由上面的常量传入 C 侧请求结构。播放列表结构主播放列表MasterPlaylist声明#EXT-X-VERSION:3声明BANDWIDTH2628000,CODECSavc1.64001f,mp4a.40.2指向/hls/index.m3u8?path...介质播放列表再展开为/hls/segment_{segment}.ts?path...。注册的 HTTP 端点只有两个/hls/index.m3u8和/hls/segment_{segment}.ts见 libav/handler.go 的RegisterRoutes。时长探测走 C 侧ff_probe_duration不依赖任何外部进程。ffmpeg 策略调用 ffmpeg CLI音轨与视频轨拆分ffmpeg/index.nocgo.go 对应的实现 中isActive()对ffmpeg、ffprobe逐个执行exec.LookPath任一缺失就打一条警告并禁用转码plg_video_transcoder: ffmpeg not found in $PATH, transcoding disabled这是判断 ffmpeg 策略下插件到底活没活的直接依据启动日志里出现该 Warning 说明 CLI 没找到HLS 转码不会注册。与 libav 策略相比ffmpeg 策略的结构性差异在 ffmpeg/constant.go 和 ffmpeg/handler.go分段常量分两套视频HLS_VIDEO_SEGMENT_LENGTH 5秒音频HLS_AUDIO_SEGMENT_LENGTH 8 * 10即 80 秒。音频分段明显更长——这正是 README 说明的为规避音视频分段交界处问题而把音频拉长的做法。主播放列表升级为#EXT-X-VERSION:6并通过#EXT-X-MEDIA:TYPEAUDIO把音频拆成独立音轨BANDWIDTH2500000,CODECSavc1.64001f,mp4a.40.2,AUDIOaud分别指向/hls/video.m3u8和/hls/audio.m3u8。注册四个端点/hls/audio.m3u8、/hls/video.m3u8、/hls/video_{segment}.ts、/hls/audio_{segment}.ts。视频分段命令带-an -sn丢弃音频音频分段带-vn -sn丢弃视频音频统一编码为-c:a aac -b:a 128000每个 ffmpeg 子进程都带-timelimit 30防止单个分段转码挂死见 ffmpeg/transcoder.go。时长探测改用外部进程ffprobe -v error -show_entries formatduration -of json并解析 JSON 输出。视频编码参数按配置选中的编码器分支拼接同一文件# 默认 libx264软件编码 -vf scale-2:720,formatyuv420p -c:v libx264 -preset veryfast \ -x264opts subme0:me_range4:rc_lookahead10:media:no_chroma_me:8x8dct0:partitionsnone另有h264_vaapi-init_hw_device vaapiva:/dev/dri/renderD128scale_vaapi、h264_nvenc-init_hw_device cudahwscale_cuda、h264_v4l2m2m-c:v h264_v4l2m2m -b:v 2500k等三个硬件分支最终统一-f mpegts pipe:1写入响应。注意default分支直接返回ErrNotImplemented在 ffmpeg 策略下编码器取一个不在上述列表里的值会导致分段转码失败。两套策略共享的配置与运行边界无论编译进哪套实现运行期配置都定义在 config.gofeatures.video.enable_transcoder开关默认true。关闭后index.go里的Onload钩子直接返回不注册任何转码端点features.video.encoder转码编码器默认libx264可选项为libx264、h264_vaapi、h264_nvenc、h264_v4l2m2mfeatures.video.blacklist_format不转码的视频格式黑名单默认值可来自环境变量FEATURE_TRANSCODING_VIDEO_BLACKLIST。共同的运行路径插件加载时清空并重建data/cache/video/目录当请求带?transcodehls且路径 MIME 以video/开头时文件先落盘到该缓存目录文件名形如vid_{sessionID}_{hash}.dat由createPlaylist替换响应为application/x-mpegURL的主播放列表每个缓存文件 12 小时后CLEAR_CACHE_AFTER 12自动删除。如何判断当前实例运行的是哪套按以下顺序即可定位看编译产物CGO 是否启用决定走 libav 还是 ffmpeg 分支这是唯一分叉点若是 nocgo 构建启动日志中出现plg_video_transcoder: ffmpeg not found in $PATH, transcoding disabled表示 CLI 缺失、转码已禁用没有该日志才说明 ffmpeg 策略处于激活状态对某个视频文件请求?transcodehls观察响应主播放列表是EXT-X-VERSION:3且只有/hls/index.m3u8说明是 libav 策略若是EXT-X-VERSION:6且带EXT-X-MEDIA音轨指向/hls/video.m3u8//hls/audio.m3u8则是 ffmpeg 策略。两套实现的取舍插件 README 给出的差异总结是libav 实现是 C 层实现不经过 ffmpeg wrapper构建期依赖一组 libav 开发库ffmpeg 实现依赖运行环境中的 ffmpeg CLI官方说明其比 libav 实现慢约 50%并且在音视频分段交界处存在若干 libav 没有的边界情况——因此 ffmpeg 实现采用音/视频分离 更长的音频分段的处理方式。对二次开发而言改动 libav 策略的分段、高度、音频码率要同时动 Go 侧常量libav/constant.go和 C 侧FFRequest参数libav/transcode.go 的transcodeSegment改动 ffmpeg 策略则只需调整 ffmpeg/transcoder.go 中的命令行参数但要受ffmpeg/ffprobe可用性约束且编码器取值超出四个可选项会触发ErrNotImplemented。【免费下载链接】filestash:file_folder: Universal File Storage Client项目地址: https://gitcode.com/GitHub_Trending/fi/filestash创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表