AVFoundation 基础上的高级视频合成框架。易于使用和扩展。如果您正在实现视频合成功能,请使用它,使生活更轻松。
本项目有一个时间线概念。任何资源都可以放入时间线中。资源可以是图片、视频、音频、Gif 等等。
功能
- 只需几步即可构建结果内容对象。
- 创建资源
- 设置配置
- 将它们放入时间线
- 使用时间线生成 AVPlayerItem/AVAssetImageGenerator/AVExportSession
- 资源:支持视频、音频和图片。资源可扩展,您可以创建自定义资源类型。例如,Gif 图像资源。
- 视频配置支持:转换、透明度等。配置可扩展。
- 音频配置支持:更改音量或实时处理音频原始数据。配置可扩展。
- 转场:片段可以与前一个和下一个片段进行转场。
用法
以下是最简单的示例。从 AVAsset 创建资源,设置视频帧的缩放模式为 aspect fill,然后向时间线插入 trackItem,之后使用 CompositionGenerator 构建 AVAssetExportSession/AVAssetImageGenerator/AVPlayerItem。
// 1. Create a resource
let asset: AVAsset = ...
let resource = AVAssetTrackResource(asset: asset)
// 2. Create a TrackItem instance, TrackItem can configure video&audio configuration
let trackItem = TrackItem(resource: resource)
// Set the video scale mode on canvas
trackItem.configuration.videoConfiguration.baseContentMode = .aspectFill
// 3. Add TrackItem to timeline
let timeline = Timeline()
timeline.videoChannel = [trackItem]
timeline.audioChannel = [trackItem]
// 4. Use CompositionGenerator to create AVAssetExportSession/AVAssetImageGenerator/AVPlayerItem
let compositionGenerator = CompositionGenerator(timeline: timeline)
// Set the video canvas's size
compositionGenerator.renderSize = CGSize(width: 1920, height: 1080)
let exportSession = compositionGenerator.buildExportSession(presetName: AVAssetExportPresetMediumQuality)
let playerItem = compositionGenerator.buildPlayerItem()
let imageGenerator = compositionGenerator.buildImageGenerator()
基本概念
时间线
用于构建资源,开发人员负责在正确的时间范围内放置资源。
CompositionGenerator
使用 CompositionGenerator 创建 AVAssetExportSession/AVAssetImageGenerator/AVPlayerItem
CompositionGenerator使用Timeline实例来转换AVFoundation API。
资源
资源提供者提供图像或音频数据。它还提供有关数据的时序信息。
当前支持
- 图像类型
ImageResource
:提供作为视频帧的CIImagePHAssetImageResource
:提供PHAsset,作为视频帧加载CIImageAVAssetReaderImageResource
:提供AVAsset,使用AVAssetReader将reader样本文本作为视频帧AVAssetReverseImageResource
:提供AVAsset,使用AVAssetReader的reader样本文本作为视频帧,但顺序相反
- 视频和音频类型
AVAssetTrackResource
:提供AVAsset,使用AVAssetTrack作为视频帧和音频帧PHAssetTrackResource
:提供PHAsset,从中加载AVAsset
TrackItem
一个TrackItem包含Resource、VideoConfiguration和AudioConfiguration。
当前支持
- 视频配置
- baseContentMode,视频帧的缩放模式基于画布大小
- 转换
- 不透明度
- 配置,可以在此处添加自定义过滤器。
- 音频配置
- 音量
- 节点,应用自定义音频处理操作,例如VolumeAudioConfiguration
- 视频过渡,音频过渡
高级用法
自定义资源
您可以通过继承Resource
来提供自定义资源类型,并实现func tracks(for type: AVMediaType) -> [AVAssetTrack]
。
通过继承ImageResource
,您可以使用CIImage作为视频帧。
自定义图像过滤
图像过滤需要实现VideoConfigurationProtocol
协议,然后可以将其添加到TrackItem.configuration.videoConfiguration.configurations
。
KeyframeVideoConfiguration
是一个具体类。
自定义音频混合器
音频混合器需要实现AudioConfigurationProtocol
协议,然后可以将其添加到TrackItem.configuration.audioConfiguration.nodes
。
VolumeAudioConfiguration
是一个具体类。
为什么创建这个项目
AVFoundation已经提供了强大的视频和音频合成API,但这些API的易用性较差。
1.AVComposition
我们需要知道何时以及如何连接不同的轨道。比如说,我们保存了一个轨道的时间范围信息,最终我们会发现时间范围信息很容易被破坏,考虑以下场景
- 更改前一个轨道的时间范围信息
- 更改速度
- 添加新轨道
- 添加/移除过渡
这些操作将影响时间线,并且所有轨道的时间范围信息都需要更新。
不利之处在于AVComposition只支持视频轨道和音频轨道。如果我们想在视频和照片中组合,实现起来非常困难。
2.AVVideoCompostion
使用AVVideoCompositionInstruction
来构造时间线,使用AVVideoCompositionLayerInstruction
来配置轨道的变换。如果我们想操作原始视频帧数据,需要实现AVVideoCompositing
协议。
在我编写代码之后,我意识到有很多代码与业务逻辑无关,它们应该被封装。
3.难以扩展功能
AVFoundation只支持少数基本合成功能。据我所知,它只能改变视频帧变换和音频音量。如果开发者想实现其他功能,例如将滤镜应用于视频帧,那么需要重写AVVideoCompostion的AVVideoCompositing
协议。工作量突然变得非常大。
生活不易,为什么还要编写难以理解的代码呢?所以,我创建了Cabbage,易于理解的API,灵活的功能扩展性。
安装
Cocoapods
platform :ios, '9.0'
use_frameworks!
target 'MyApp' do
# your other pod
# ...
pod 'VFCabbage'
end
手动
不建议手动安装框架,但如果您必须手动安装。您可以使用以下步骤:
- 将
Cabbage/Sources
文件夹简单拖拽到您的项目中。 - 或者将Cabbage作为子模块添加。
$ git submodule add https://github.com/VideoFlint/Cabbage.git
技术要求
- iOS 9.0+
- Swift 4.x
使用Cabbage的项目
- VideoCat:一个演示项目演示如何使用Cabbage。
授权协议
根据MIT协议
特别感谢
- 图标由熊猫先生设计