- Notifications
You must be signed in to change notification settings - Fork183
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.
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Contributors2
Uh oh!
There was an error while loading.Please reload this page.