iOS端保存带Alpha通道视频的实践

一、背景

最近Blurrr新版本需求出来了,需要iOS客户端可以保存带Alpha通道视频。 那什么是带Alpha通道的视频呢?举个栗子:

在视频编辑中,我们常常会将文字增加各种效果,然后和图片、视频等合成一个视频。
比如:

image.png

你想在上面图片上增加一个文字:世界和平 并合成一个新的视频。

你想要的效果应该是这样的吧:


image.png

但是如果世界和平是不带Alpha通道的,那就会是这样的:

image.png

你会发现,世界都没了,世界和平就是一句空话。

在我们之前的产品中,一直对保存带Alpha通道的视频有非常强烈的需求。但是之前一直没有特别好的解决方案,加上之前的产品规划调整,这个技术瓶颈也就一致没有解决。最近新版本需求中,对alpha通道视频的依赖非常严重,如果无法解决,会导致我们产品重点功能无法完成,产品完善度大大降低。

因此,就有了接下来的故事。

二、方案探索

接收到需求后,在和Unity组 @CC老师 讨论后,暂时制定了两种实现方案:

1.修改编码方式,使得视频输出支持Alpha通道

2.Unity除现有的视频渲染流程外,还需要再开启一个流程专门渲染Alpha图像,然后再由iOS客户端将两个结果叠加产生一帧图像。

方案二相比方案一在实现成本上会高很多,不仅工作量大,并且还需要降低渲染性能。

目前的技术方案使用AVAssetWirter采用H264编码方式生成视频。经过资料查找发现H264的特点就是编码输出的视频是不带有Alpha通道的。本着用最低成本和最高性能实现,并且基于AVAssetWirter编码及AVAssetReader解码,那么最简单的就是AVAssetWirter编码支持Alpha通道。所以就需要寻找其它编码方式。

正当我在查找资料却久久无果时,关键人物 -- @章哥,出现了。

image.png

章哥在了解相关情况后,通过查阅资料,发现苹果在2019的WWDC中,展示了iOS13后苹果新提供的新能力,可以基于HEVC编码的视频,保存带Alpha通道的视频的技术方案。

HEVCHigh Efficiency Video Coding的缩写,是一种新的视频压缩标准,用来替代H.264/AVC编码标准,2013年1月26号,HEVC正式成为国际标准。
苹果在iOS11后支持了HEVC编码能力,然后在iOS13上正式推出了HEVC.withAlpha。正好,我们Blurrr就是从iOS13开始适配的。那么接下来要做的就是实际论证了。

三、方案实现

HEVC编码方案实现带Apha通道视频的原理如下:


image.png

是不是有点熟悉,和@CC老师提出的方案一样,也是将一个图像层叠加上透明图层,得到最终的带Alpha的图层。不过,这里苹果帮我们做了封装,让我们方便直接使用。

官方Demo展示了三种不同的使用场景:

  • 使用AVAssetWirter,将视频帧写入到视频文件中;

  • 使用AVExportSession导出视频;

  • 使用VideoToolBox将视频帧转换为SampleBuffer

我们今天主要介绍第一种,也是我们目前使用的解决方案。对其它两种解决方案有兴趣的同学可以点击文末链接详细了解。

编码原理如下:
image.png

在获取到带Alpha通道的视频帧后,我们再通过AVAssetWriter就可以将其写入到mov格式的文件中了。

接下来,就是代码环节了。

H264编码设置如下:
  let outPath = "demo.mov"
        do {
            try assetWriter = AVAssetWriter(url: outPath, fileType: AVFileType.mp4)
        } catch {
            MSLog.info("--MSVideoEncoder create writer failed: \(error)")
        }
 let outputSettings: [String: Any] = [
            AVVideoCodecKey: AVVideoCodecType.h264,
            AVVideoWidthKey: outWidth,
            AVVideoHeightKey: outHeight,
            AVVideoCompressionPropertiesKey: [
                AVVideoAverageBitRateKey: bitRate,
                AVVideoProfileLevelKey: AVVideoProfileLevelH264HighAutoLevel
            ]
        ]
HEVC编码设置如下:
        let outPath = "demo.mov"
        do {
            try assetWriter = AVAssetWriter(url: outPath, fileType: AVFileType.mov)
        } catch {
            MSLog.info("--MSVideoEncoder create writer failed: \(error)")
        }
        let outputSettings: [String: Any] = [
            AVVideoCodecKey: AVVideoCodecType.hevcWithAlpha,
            AVVideoWidthKey: outWidth,
            AVVideoHeightKey: outHeight,
            AVVideoCompressionPropertiesKey:
            [kVTCompressionPropertyKey_AverageBitRate: bitRate,
            kVTCompressionPropertyKey_TargetQualityForAlpha: 1]
        ]

        let videoWriterInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: outputSettings)

前后对比,可以看出其中就三个关键设置项:

  • 初始化AVAssetWriter时,需要设置fileTypeAVFileType.mov
  • 初始化AVAssetWriterInputoutputSettings字典中,设置为AVVideoCodecKeyAVVideoCodecType.hevcWithAlpha
  • 初始化AVAssetWriterInputoutputSettings字典中,使用了VideoToolBoxAVVideoCompressionPropertiesKey设置为[kVTCompressionPropertyKey_AverageBitRate: bitRate, kVTCompressionPropertyKey_TargetQualityForAlpha: 1]

经过上面编码参数修改,最终生成的视频就是带有Alpha通道的视频了。

还是以上面的世界和平为例,基于H264编码和HEVC生成的视频视频对比。因为多了一个Alpha图层,体积确实有所增大。

image.png

但是,由于HEVC是在H264基础上升级的,苹果也做了支持。编码速度上几乎没有差别,但是在解码速度上,HEVC还是会比H264快大概10%的样子。

以上就是本期全部内容了,下期再见!

特别感谢:@章哥@CC 两位大佬鼎力支持。

参考资料:
https://developer.apple.com/videos/play/wwdc2019/506/
https://www.bilibili.com/video/av68104093

你可能感兴趣的:(iOS端保存带Alpha通道视频的实践)