云/移动端媒体处理技术分享

1,348 阅读5分钟

今天在部门内做了一个分享,我整理了一下也分享给大家。文章的内容是我在上家单位做的云剪辑和短视频处理用到的一些技术和架构。

先来说一下当初做这个跨平台媒体处理的一个指标吧,当初是对标阿里云媒体处理服务。当初我们对接阿里云媒体处理的合成效率是 1:1。后面我单独基于 ffmpeg 重新设计了一个媒体处理的架构。最终上线,我们的媒体处理效率是超出了预期的。

媒体处理指标:

  1. 媒体合成速率 1:0.5
  2. 编辑实时预览无卡顿支持任何业务场景

云剪辑应用场景:

  • 云剪辑的应用场景比较广泛,基本上也没有平台限制,但是用的最多的还是 Web 端和小程序。因为它们访问底层的能力有限。
  • 移动端的应用场景: 短视频创作、美颜相机、直播等

媒体处理架构设计

上图所示为整个媒体处理的一个架构设计,主要分为 4 层

第一层:定义为应用对接层,大致可以分为 Android、IOS、Linux 三个对接平台

第二层:定义为 SDK 层,主要是基于当前使用平台的开发语言进行开发,将核心处理层在各平台上的一个 API 调用封装

第三层: 定义为 媒体处理 核心层,主要是用于音视频的编辑、转码、编解码、mp4 封装以 c++ 语言开发,具备跨平台的能力

第四层: 定义为系统平台层,在各个平台需要用到的原生库和跨平台的音视频处理开源库。

云剪辑数据流程

云剪辑不涉及渲染,所有处理基于 FFmpeg API 进行。

Web : 通常指运行在PC-浏览器上的程序

小程序: 指在微信生态上运行的小程序

发起媒体处理: 通过 HTTP-POST JSON 协议将需要处理的媒体资源按规定的定义传输

调度服务: 接收业务服务的 request task,将 request task 提交到空闲媒体处理服务器上

媒体处理服务: 运行 HTTPServer, 接入 Linux 平台媒体处理 SDK(动态库)

移动端媒体处理数据流程

输入:

移动端的媒体数据输入主要包含 MP4文件、本地 Camera 相机数据采集、本地 AudioRecord 音频数据采集

媒体处理技术点:

编解码

  • 优先使用 Android 、IOS MediaCodec/VideoToolBox 硬件编解码能力,不支持的格式使用 ffmepg 内置软编解码

视频裁剪:

  • 视频裁剪主要分为精准裁剪和不精准裁剪,精准裁剪主要是找到之前最近的 I 帧,然后依次解码到 pts >= clipStartTime ,到 >= clipEndTime . 不精准一般就是 seekto 的点也就是 I 帧,到 pts >= clipEndTime

多段拼接:

  • 多段拼接需要注意音频采样格式是否一致,视频的分辨率、yuv 格式、帧率是否一致。还需要注意 curPts > lastPts(有 B 帧的情况下,不然会导致花屏)

添加字幕:

  • OpenGL 不支持直接绘制 Text 文本,我们需要将 text 先渲染到 TextView 上,然后将 TextView 转成 Bitmap ,通过 OffScreenRenderer(离屏渲染)增加一个图层,实现图像的叠加效果实现字幕的渲染

添加滤镜:

  • Android / IOS 可以接入 GPUImage 或者 LUT (512*512 色彩图) 实现滤镜

添加贴纸:

  • 实现贴纸的话需要将采集到相机原始 YUV 数据通过 OpenCV 或者其它图像处理框架,将识别到的人物头像的 Rect 坐标拿到,然后在将贴纸渲染到对于的坐标上即可。

添加 BGM:

  • 将 2 段解码完的 PCM 进行重采样之后(如果格式不一致),进行 mix ,最简单的算法原理为: 直接把两组 PCM 数据相加,相加后的数据范围不能超过 pcm 位宽的表示范围即可。具体算法可以参考 webrtc 内部的音频 mix 算法:chromium.googlesource.com/external/we…

音视频变速: 视频变速:

  • 需要编解码-可以通过丢帧实现
  • 不需要编解码-可以直接修改 pts,如果存在 b 帧的情况下,pts/dts 都需要修改但是一定要注意对应关系,有 B 帧的情况下 pts 不是递增的 音频变速:
  • 可以通过 FFmpeg AVFilter tempo 的滤波器
  • 也可以通过 soundtouch 开源库实现

音视频归一化:

  • 为了实现多段媒体资源拼接,那么必然需要对 PCM、YUV 进行归一化处理。不然会导致合成失败

媒体处理难点

云剪辑可以做成像移动端那样在端上处理吗?

是可以的。关键技术点 WebAssembly

如何保证移动端媒体处理 SDK 跨平台?

如何保证实现效果一致?

如何降低开发效率成本?

渲染

  • ios / android 渲染使用 OpenGL ES 2.0 Native c++ 接口,各自使用 EGL 环境即可,特效与滤镜渲染共用

编解码

  • FFmpeg 内置 IOS VideoToolBox 原生编解码,Android 统一在 native 层实现 AMediaCodec

跨平台编辑播放预览

  • 参考 ijkplayer 内部设计原理,基于 ijkplayer 二次开发(分模块根据业务定制设计), 通用编解码、渲染接口,各平台实现即可

性能指标

快速合成:

FFmpeg.c 合成原理是串行模式,对于多段合成或者添加 BGM 的话,效率就会大大降低。它内部是同步解码->特效处理->编码->封装。

1、为了解决快速合成,我们使用了多线程模型,模型图如下: 通过上图发现,咱们解封装->解码->归一化->编码->封装都使用了队列+多线程的模型来处理复杂媒体资源,通过多线程模型大大提升了生产效率

2、通过 libx264 编码参数调优,找到一个平衡点 preset,profile 等

预览无卡顿:

其实预览也是利用的多线程 + 缓存的模型也能达到无卡顿效果