一. 背景与目标
1.1 视频审核背景
现有视频审核系统由于历史原因,针对不同的业务调用方和业务场景提供了多套视频审核技术方案和服务,且在审核时效、支持的协议完整性等方面存在一定的不足;同时,多套系统并存一直存在较高的运维成本的情况。
由此,需要设计一套统一的视频审核系统架构,将多套服务合并为一套服务,提供统一标准视频审核服务,大幅降低运维成本的同时,提供完整的接口协议支持和更高的审核时效。
1.2 设计目标
- 审核时效优化:
- 流式完成下载、拆帧、推理、通知四阶段处理;使得整个审核过程为:边下边拆边推边响应。
- 每阶段内并行处理,提高审核时效。
最终目标:审核时长 = MAX(并行下载、并行拆帧、并行推理)。
- 完整的接口协议,应对未来不同需求场景:
- 短视频同步:提供时长1~2分内、100MB内的视频,达成3秒内审核完成的目标;且以同步阻塞接口提供服务,简化业务方调用、交互过程。
- 长视频异步:支持10小时甚至更长视频的异步审核能力,按调用方需求提供实时响应开关。
- 实时直播视频流:针对实时直播流,提供边拉流、边审核、边响应的实时流式响应能力。
二. 拆帧技术方案选型
2.1 ffmpeg简要介绍
针对不同的编码器、封装协议、传输协议,提供统一的音视频处理接口。
跨平台,兼容200多种编码、180多种封装格式、20多种传输协议。世界上90%以上的音视频开发基于FFmpeg。
2.2 API vs 命令行
- 基于API
FFmpeg提供了一整套的音视频处理库,以统一的API分别完成音视频处理过程中的主要阶段,包括:
采集、解封装、解码、处理&转换、编码、封装、传输等。
其中,各个库提供的API粒度较细,非常适合对音频、图片帧做业务细粒度的自定义加工的场景。
ffmpeg库 | 简介 |
libavcodec | 封装绝大部分编码解码器,提供统一API。 |
libavformat | 封装绝大部分封装格式,针对不同封装格式提供统一API。 |
libswscale | 图片像素格式转换工具库。 |
libswresample | 音频采样格式转换、重采样工具库。 |
libavfilter | 音视频滤镜库。 |
libavutil | 音视频开发过程中的工具函数大全。 |
libavdevice | 摄像头、麦克风等外部设备数据采集API。 |
- 基于命令行
基于上述库,FFmpeg提供了可执行命令行工具:FFmpeg。
FFmpeg命令行以组合大量选项、参数的方式完成常规的音视频处理工作,且其本身以c语音实现,为常规音视频处理需求,提供了简单、稳定、高效的支撑;通过高级命令行参数可达成设计目标 :
流式下载:支持Http/flv流等传输协议作为输入,实现边下载边解码。
分段并行:利用ss、to等选项,其内部基于http range seek特性,完成并行多段处理。
自定义音视频参数:利用codec/afilter/vfilter等编解码、滤镜参数可完成输出图片自定义帧率、音频采样、声道等目标。
综合考虑视频审核业务特点,对音视频处理过程本身并不复杂,单纯、核心的目标就是将音频、图片帧从视频中拆分出来,并不存在过多的针对音视频帧的加工处理过程,因此,视频审核架构采用FFmpeg命令行工具完成基础的视频拆帧工作。
三.框架描述
3.1 流式处理框架
任务处理器是视频审核服务的核心组件,一个任务处理器实例包括三个子组件:拆帧引擎、任务驱动器、审核业务对象。通过任务驱动器的调度过程,协调拆帧引擎和审核业务对象两个对象实例完成一个视频任务的下载、拆帧、推理、响应四阶段流式、并行处理过程。
一个视频审核服务内根据容器cpu资源、配置情况,允许多个处理器实例并行完成多个视频处理任务。
3.1.1 拆帧引擎
拆帧引擎:图片拆帧逻辑图、音频拆帧逻辑图,目标均是流式生产数据。
图片拆帧
单一视频任务中,为了完成流式、并行处理目标,图片拆帧模块由两个主任务并行完成:
一是根据视频时间、业务策略,启动多个ffmpeg进程,利用ffmepg的seek机制将视频拆分为多段完成并行下载、拆帧。
二是收集任务,根据拆分出的图片帧时间戳信息生成图片帧信息,供后续推理读取。
音频拆帧
针对音频拆帧存在两种目标:
针对视频文件:采用单一命令完成整个音频文件的拆分,供后续asr、音频审核使用。
针对视频流:相对于视频文件,视频流具有连续性,时间比为1:1,为了达成边拆边推理边响应目标,需要在直播过程中动态切分音频段,完成实时处理和实时响应。
视频流中的音频处理部分涉及几个主要步骤:
拆段:利用segments机制,完成固定时间段的音频切分。
VAD:基于webrtc VAD模块,遍历PCM文件采样数据,完成有声段音频的拼接&切割。
编码:将原始PCM音频编码为mp3,大幅降低文件尺寸便于传输。
收集:负责收集编码后的mp3文件,生产音频段信息,用于后续推理读取。
3.1.2 审核业务模块
审核业务对象与任务处理器、调用算法服务进行交互,完成流式、并行的帧(图片、音频)审核业务过程。
审核业务对象内部由单线程驱动,循环检测帧队列、异步推理响应、异步上传响应三个状态,并根据推理、上传结果,在业务策略开启实时响应开关时,动态发送部分响应数据至实时结果队列完成实时响应。
3.1.3 任务调度器
拆帧引擎和业务对象对外部提供了标准的非阻塞状态查询及命令处理接口,围绕这些接口,任务调度器内部由单线程驱动,与拆帧引擎和业务对象进行流式调用交互,这个过程中,拆帧引擎作为帧生产者、业务对象作为帧消费者,任务驱动器将两者进行衔接,从任务处理的角度驱动两者共同完成视频审核过程。
至此,三者整体完成了核心目标:
下载、拆帧、推理三阶段,每阶段内并行加速。
下载、拆帧、推理、实时通知四阶段流式处理。
3.1.4 多业务场景
得益于核心组件间的标准接口交互,整个系统可以针对不同的业务场景、需求,将业务对象从主服务中剥离出去,由内部函数调用改为远程RPC调用,并进行分布式部署;使得所有业务在统一的流式、并行框架下,高效完成各种场景需求。
3.1.5 同步&异步处理流程
视频拆帧过程属cpu密集型业务,其任务处理的服务节点优先从cpu负载角度出发,而不是接收请求的节点进行处理;因此,在接收请求后,会将其派发到MQ任务队列中,由cpu闲置的节点通过手动pull方法完成任务获取并处理。
同步与异步不同的点在于,异步任务处理完成后,直接将响应发送到结果队列中,由调用发接收;而同步模式下,需要将结果通过回调的方式,将响应返回到请求接收节点,再由请求接收节点进行同步响应给调用方,内部通过同步对象、超时等机制完成同步调用协议。
3.2 结果服务
结果服务与主服务配套,从MQ接收主服务处理过程中发送的各种事件并保存,主要完成几个功能:
- 请求处理审计:保留一个月的细节结果,供后台查询、分析视频拆帧、审核过程的有效性、及时、快速、方便的审计问题。
- 提供主动查询接口:调用发发起异步请求后,对比mq接收结果,另一种常见的方式是通过主动调用查询接口进行定时检查的方式获取响应,结果服务提供get接口供调用方主动进行结果查询。
- 全局重试:主服务所在宿主机、容器宕机时,结果服务内部实现了定时检查机制,当发现视频任务开始处理后,且在一定时间内未响应的情况下,会调用主服务完成任务的重试处理过程,确保视频任务不丢失。
四. 策略配置
系统针对单一视频的整个处理过程中,涉及不同的策略可以进行配置&设置,包括两个方面:
一是框架处理过程,二是审核业务策略,根据不同业务需求,可以进行完成的处理过程配置;
业务方通过输入业务token+策略ID进行服务调用,以完成业务方特定需求,具体可配置策略包含如下:
框架行为策略 | 业务策略 |
是否开启中间结果实时通知 | 审核疑似阈值 |
分段并行策略 {开始、结束时间、FPS} | 审核能力列表 |
是否并行拆图片帧 | |
是否预下载,默认边下边解 | |
下载超时, 仅开启预下载时有效 | |
拆帧超时 | |
业务结果等待超时 | |
视频最大限制,默认4GB。 | |
视频最长限制,默认俩小时。 |
- 不同模式部署
16c机器情况下,针对不同协议场景,完成集群配置:
集群 | 目标 | Processor 实例数量 | Image公共池并行数 | 图片拆帧是否拆段并行 |
短视频同步 | 速度优先,避免 多任务CPU资源冲突 | 1 | 4 | 是 |
长视频异步 | 充分利用资源,允许任务排队 | 4 | 4 | 是 |
RTMP视频流 | 实时流无法拆段并行 | 16 | 16 | 否 |
五. 测试验证
经测试验证,在16C容器下达成设计目标:
- 1分钟、100MB内视频,2秒内可完成审核。
- 长视频异步模式下,对比旧版服务审核时效平均提升5倍。
- 优雅退出+全局重试保障任务不丢失。
- 标准模块接口为未来扩展为多场景通用分布式系统打下基础。