VideoLab
基于 AVFoundation 和 Metal 的高性能和灵活的视频编辑和效果框架。
特点
- 高性能实时视频编辑和导出。
- 高度自由的视频、图片、音频组合。
- 支持音频音高设置和音量调整。
- 支持 CALayer 向量动画。因此支持复杂的文字动画。
- 支持关键帧动画。
- 支持类似 After Effects 的预合成。
- 支持转场。
- 支持自定义效果。例如 LUT 滤镜、缩放模糊等。
要求
- iOS 11.0+
- Swift 5.0+
安装
VideoLab 通过 CocoaPods 提供。在您的 Podfile
中指定以下内容:
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '11.0'
use_frameworks!
target '<Your Target>' do
pod 'VideoLab'
end
用法
基本概念
渲染层
RenderLayer
是VideoLab
框架中最基本的单元。视频、图像、音频可以是一个RenderLayer
,甚至效果也可以是RenderLayer
。RenderLayer
类似于After Effect中的层概念。
渲染合成
RenderComposition
作为一个合成器,可以设置帧率和画布大小,包含多个RenderLayers
,并支持设置CALayer
以实现矢量动画。
VideoLab
VideoLab
可以被认为是一个实验室,在这里可以基于RenderComposition
生成AVPlayerItem
,AVAssetExportSession
,AVAssetImageGenerator
。
基本用法
// 1. Layer 1
var url = Bundle.main.url(forResource: "video1", withExtension: "MOV")
var asset = AVAsset(url: url!)
var source = AVAssetSource(asset: asset)
source.selectedTimeRange = CMTimeRange(start: CMTime.zero, duration: asset.duration)
var timeRange = source.selectedTimeRange
let renderLayer1 = RenderLayer(timeRange: timeRange, source: source)
// 1. Layer 2
url = Bundle.main.url(forResource: "video2", withExtension: "MOV")
asset = AVAsset(url: url!)
source = AVAssetSource(asset: asset)
source.selectedTimeRange = CMTimeRange(start: CMTime.zero, duration: asset.duration)
timeRange = source.selectedTimeRange
timeRange.start = CMTimeRangeGetEnd(renderLayer1.timeRange)
let renderLayer2 = RenderLayer(timeRange: timeRange, source: source)
// 2. Composition
let composition = RenderComposition()
composition.renderSize = CGSize(width: 1280, height: 720)
composition.layers = [renderLayer1, renderLayer2]
// 3. VideoLab
let videoLab = VideoLab(renderComposition: composition)
// 4. Make playerItem
let playerItem = videoLab.makePlayerItem()
- 创建
RenderLayer
- 创建
RenderComposition
,设置renderSize
和layers
- 使用
renderComposition
创建VideoLab
- 创建
AVPlayerItem
或AVAssetExportSession
更高级的使用
变换
var center = CGPoint(x: 0.25, y: 0.25)
var transform = Transform(center: center, rotation: 0, scale: 0.5)
renderLayer1.transform = transform
- 使用
center
、rotation
和scale
创建Transform
RenderLayer
设置transform
音频配置
let audioConfiguration = AudioConfiguration()
let volumeRampTimeRange = CMTimeRange(start: CMTime.zero, duration: CMTime(seconds: 5, preferredTimescale: 600))
let volumeRamp1 = VolumeRamp(startVolume: 0.0, endVolume: 0.0, timeRange: volumeRampTimeRange)
audioConfiguration.volumeRamps = [volumeRamp1]
renderLayer2.audioConfiguration = audioConfiguration
- 创建
AudioConfiguration
- 使用
startVolume
、endVolume
和timeRange
创建VolumeRamp
AudioConfiguration
设置volumeRamps
RenderLayer
设置audioConfiguration
CALayer 动画
导出时,为合成设置自定义的 CALayer
composition.animationLayer = <Your customized CALayer>
播放时,将 AVSynchronizedLayer
添加到视图的层中,更多细节见 文本动画演示。
关键帧动画
// 1. Keyframe animation
let keyTimes = [CMTime(seconds: 2, preferredTimescale: 600),
CMTime(seconds: 4, preferredTimescale: 600),
CMTime(seconds: 6, preferredTimescale: 600)]
let animation = KeyframeAnimation(keyPath: "blendOpacity",
values: [1.0, 0.2, 1.0],
keyTimes: keyTimes, timingFunctions: [.linear, .linear])
renderLayer1.animations = [animation]
var transform = Transform.identity
let animation1 = KeyframeAnimation(keyPath: "scale",
values: [1.0, 1.3, 1.0],
keyTimes: keyTimes, timingFunctions: [.quadraticEaseInOut, .quadraticEaseInOut])
let animation2 = KeyframeAnimation(keyPath: "rotation",
values: [0, Float.pi / 2.0, 0],
keyTimes: keyTimes, timingFunctions: [.quadraticEaseInOut, .quadraticEaseInOut])
transform.animations = [animation1, animation2]
renderLayer1.transform = transform
- 设置
keyTimes
- 使用
keyPath
、values
、keyTimes
和timingFunctions
创建KeyframeAnimation
- 为
Animatable
对象设置animations
(例如RenderLayer
、Transform
)
RenderLayerGroup(类似 After Effect 的预合成)
let layerGroup = RenderLayerGroup(timeRange: timeRange)
layerGroup.layers = [renderLayer1, renderLayer2]
- 使用
timeRange
创建RenderLayerGroup
- 为
layerGroup
设置子layers
。更多信息请参阅图层组演示。
过渡
我们没有过渡图层,因此可以添加转换或操作到每个RenderLayer来创建过渡。更多信息请参阅过渡演示。
自定义效果
// Filter
var filter = LookupFilter()
filter.addTexture(lutTextures[0], at: 0)
renderLayer.operations = [filter]
// Zoom Blur
var zoomblur = ZoomBlur()
animation = KeyframeAnimation(keyPath: "blurSize",
values: [0.0, 3.0],
keyTimes: keyTimes, timingFunctions: [.quarticEaseOut])
zoomblur.animations = [animation]
layerGroup1.operations = [zoomblur]
- 创建自定义的继承自
BasicOperation
的Operation
。BasicOperation
也遵循Animatable
协议。 - 为
RenderLayer
设置operations
。
作者
BearRuan, [email protected]
许可证
VideoLab可在MIT许可证下使用。有关更多信息,请参阅LICENSE文件。