- Notifications
You must be signed in to change notification settings - Fork180
High-performance and flexible video editing and effects framework, based on AVFoundation and Metal.
License
ruanjx/VideoLab
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
High-performance and flexible video editing and effects framework, based on AVFoundation and Metal.
Framework design and implementation
- High-performance real-time video editing and exporting.
- Highly free combination of video, image, audio.
- Support audio pitch setting and volume adjustment.
- Support CALayer vector animations, so complex text animations are supported.
- Support keyframe animation.
- Support After Effect-like pre-compose.
- Support transitions.
- Support custom effects. Such as LUT filter, zoom blur, etc.
The following are some GIFs of features(multiple layers, text animation, keyframe animation, pre compose, and transition)
- iOS 11.0+
- Swift 5.0+
VideoLab is available throughCocoaPods. Specify the following in yourPodfile
:
source'https://github.com/CocoaPods/Specs.git'platform:ios,'11.0'use_frameworks!target'<Your Target>'dopod'VideoLab'end
RenderLayer
is the most basic unit in theVideoLab
framework. A video, image, audio can be aRenderLayer
, or even just an effect can be aRenderLayer
.RenderLayer
is more like the concept of the layer in After Effect.
RenderComposition
works as a composite, can set frame rate, canvas size, contains multipleRenderLayers
, can setCALayer
to support vector animations.
VideoLab
can be considered as a lab whereAVPlayerItem
,AVAssetExportSession
,AVAssetImageGenerator
can be generated according toRenderComposition
.
// 1. Layer 1varurl=Bundle.main.url(forResource:"video1", withExtension:"MOV")varasset=AVAsset(url: url!)varsource=AVAssetSource(asset: asset)source.selectedTimeRange=CMTimeRange(start:CMTime.zero, duration: asset.duration)vartimeRange= source.selectedTimeRangeletrenderLayer1=RenderLayer(timeRange: timeRange, source: source) // 1. Layer 2url=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.selectedTimeRangetimeRange.start=CMTimeRangeGetEnd(renderLayer1.timeRange)letrenderLayer2=RenderLayer(timeRange: timeRange, source: source) // 2. Compositionletcomposition=RenderComposition()composition.renderSize=CGSize(width:1280, height:720)composition.layers=[renderLayer1, renderLayer2]// 3. VideoLabletvideoLab=VideoLab(renderComposition: composition)// 4. Make playerItemletplayerItem= videoLab.makePlayerItem()
- Create
RenderLayer
- Create
RenderComposition
, setrenderSize
andlayers
- Create
VideoLab
withrenderComposition
- Make
AVPlayerItem
orAVAssetExportSession
varcenter=CGPoint(x:0.25, y:0.25)vartransform=Transform(center: center, rotation:0, scale:0.5)renderLayer1.transform= transform
- Create
Transform
withcenter
,rotation
andscale
RenderLayer
settransform
letaudioConfiguration=AudioConfiguration()letvolumeRampTimeRange=CMTimeRange(start:CMTime.zero, duration:CMTime(seconds:5, preferredTimescale:600))letvolumeRamp1=VolumeRamp(startVolume:0.0, endVolume:0.0, timeRange: volumeRampTimeRange)audioConfiguration.volumeRamps=[volumeRamp1]renderLayer2.audioConfiguration= audioConfiguration
- Create
AudioConfiguration
- Create
VolumeRamp
withstartVolume
,endVolume
andtimeRange
AudioConfiguration
setvolumeRamps
RenderLayer
setaudioConfiguration
For exporting set your customizedCALayer
forRenderComposition
composition.animationLayer=<Your customized CALayer>
For playback addAVSynchronizedLayer
to your view's layer, See more detail inText Animation Demo.
// 1. Keyframe animationletkeyTimes=[CMTime(seconds:2, preferredTimescale:600),CMTime(seconds:4, preferredTimescale:600),CMTime(seconds:6, preferredTimescale:600)]letanimation=KeyframeAnimation(keyPath:"blendOpacity", values:[1.0,0.2,1.0], keyTimes: keyTimes, timingFunctions:[.linear,.linear])renderLayer1.animations=[animation]vartransform=Transform.identityletanimation1=KeyframeAnimation(keyPath:"scale", values:[1.0,1.3,1.0], keyTimes: keyTimes, timingFunctions:[.quadraticEaseInOut,.quadraticEaseInOut])letanimation2=KeyframeAnimation(keyPath:"rotation", values:[0,Float.pi/2.0,0], keyTimes: keyTimes, timingFunctions:[.quadraticEaseInOut,.quadraticEaseInOut])transform.animations=[animation1, animation2]renderLayer1.transform= transform
- Create
KeyframeAnimation
withkeyPath
,values
,keyTimes
andtimingFunctions
- Set
animations
for astruct
orclass
that implements theAnimatable
protocol (e.g.Transform
struct,RenderLayer
class)
letlayerGroup=RenderLayerGroup(timeRange: timeRange)layerGroup.layers=[renderLayer1, renderLayer2]
- Create
RenderLayerGroup
withtimeRange
- Set sub
layers
forlayerGroup
. See more detail inLayer Group Demo.
We don't have a transition layer, so instead, you can add a transform or operations to each RenderLayer to create a transition. See more detail inTransition Demo.
// Filtervarfilter=LookupFilter()filter.addTexture(lutTextures[0], at:0)renderLayer.operations=[filter]// Zoom Blurvarzoomblur=ZoomBlur()animation=KeyframeAnimation(keyPath:"blurSize", values:[0.0,3.0], keyTimes: keyTimes, timingFunctions:[.quarticEaseOut])zoomblur.animations=[animation]layerGroup1.operations=[zoomblur]
- Create customize
Operation
inherited fromBasicOperation
.BasicOperation
also conforms to theAnimatable
protocol - Set
operations
forRenderLayer
.
- Support Open GL render
- Add speed adjustment for
RenderLayer
. - Provide a more convenient way to use transitions, possibly providing
TransitionLayer
. - Add log system.
- BearRuan,ruanjingxiong@gmail.com
- Kay,kayyyuan@gmail.com
VideoLab is available under the MIT license. See theLICENSE file for more info.
About
High-performance and flexible video editing and effects framework, based on AVFoundation and Metal.