{"id":13908623,"url":"https://github.com/ruanjx/VideoLab","last_synced_at":"2025-07-18T07:32:13.361Z","repository":{"id":41119943,"uuid":"340840202","full_name":"ruanjx/VideoLab","owner":"ruanjx","description":"High-performance and flexible video editing and effects framework, based on AVFoundation and Metal.","archived":false,"fork":false,"pushed_at":"2022-10-31T11:48:35.000Z","size":175050,"stargazers_count":848,"open_issues_count":19,"forks_count":177,"subscribers_count":19,"default_branch":"develop","last_synced_at":"2024-11-11T13:18:27.896Z","etag":null,"topics":["avfoundation","ios","metal","swift","video","video-processing","videoediting","videoeditor"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ruanjx.png","metadata":{"files":{"readme":"README-CN.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-02-21T07:07:34.000Z","updated_at":"2024-11-06T20:44:11.000Z","dependencies_parsed_at":"2022-07-12T18:17:37.645Z","dependency_job_id":null,"html_url":"https://github.com/ruanjx/VideoLab","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruanjx%2FVideoLab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruanjx%2FVideoLab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruanjx%2FVideoLab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ruanjx%2FVideoLab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ruanjx","download_url":"https://codeload.github.com/ruanjx/VideoLab/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226372295,"owners_count":17614661,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["avfoundation","ios","metal","swift","video","video-processing","videoediting","videoeditor"],"created_at":"2024-08-06T23:02:52.285Z","updated_at":"2025-07-18T07:32:13.145Z","avatar_url":"https://github.com/ruanjx.png","language":"Swift","readme":"# VideoLab\n\n高性能且灵活的视频剪辑与特效框架，基于 AVFoundation 与 Metal。\n\n[框架设计与实现介绍](./Document/README-DETAIL-CN.md)\n\n## 特性\n\n- [x] 高性能实时剪辑与导出。\n- [x] 高自由度组合视频，图片，音频\n- [x] 支持音频音高设置，音量调节。\n- [x] 支持 CALayer 矢量动画，可以支持复杂的文字动画。\n- [x] 支持关键帧动画。\n- [x] 支持类似于 After Effect 的预合成。\n- [x] 支持转场。\n- [x] 支持自定义各类特效，如 LUT 滤镜，zoom blur 等等（MSL 编写脚本）。\n\n以下是一些特性的 gif（多图层、文字动画、关键帧动画、预合成及转场）\n \n\u003cp align=\"left\"\u003e\n    \u003cimg src=\"./Document/Resource/multiple-layer-demo.gif\" width=\"240\"\u003e\n    \u003cimg src=\"./Document/Resource/text-animation-demo.gif\" width=\"240\"\u003e\n    \u003cimg src=\"./Document/Resource/keyframe-animation-demo.gif\" width=\"240\"\u003e\n    \u003cimg src=\"./Document/Resource/pre-compose-demo.gif\" width=\"240\"\u003e\n    \u003cimg src=\"./Document/Resource/transition-demo.gif\" width=\"240\"\u003e\n\u003c/p\u003e\n\n## 要求\n\n* iOS 11.0+\n* Swift 5.0+\n\n## 安装\n\n可以使用 [CocoaPods](https://cocoapods.org) 安装。只需指定如下语句到你的 `Podfile` 文件中。\n\n```ruby\nsource 'https://github.com/CocoaPods/Specs.git'\nplatform :ios, '11.0'\nuse_frameworks!\n\ntarget '\u003cYour Target\u003e' do\n  pod 'VideoLab'\nend\n```\n\n## 使用\n\n### 基础概念\n\n#### RenderLayer\n\n`RenderLayer` 是 `VideoLab` 框架中最基本的单元。一个视频、图片、音频都可以是一个 `RenderLayer`，甚至一个效果也可以是一个 `RenderLayer`。`RenderLayer` 类似于 After Effect 中图层的概念。\n\n#### RenderComposition\n\n`RenderComposition` 可以理解成一个视频作品，可以设置帧率、画布大小，包含多个 `RenderLayers`，可以设置 `CALayer` 支持矢量动画。\n\n\n#### VideoLab\n\n`VideoLab` 可以理解成一个实验室，基于 `RenderComposition` 生成 `AVPlayerItem`, `AVAssetExportSession`, `AVAssetImageGenerator`。\n\n### 基础使用\n\n```swift\n// 1. Layer 1\nvar url = Bundle.main.url(forResource: \"video1\", withExtension: \"MOV\")\nvar asset = AVAsset(url: url!)\nvar source = AVAssetSource(asset: asset)\nsource.selectedTimeRange = CMTimeRange(start: CMTime.zero, duration: asset.duration)\nvar timeRange = source.selectedTimeRange\nlet renderLayer1 = RenderLayer(timeRange: timeRange, source: source)\n    \n// 1. Layer 2\nurl = Bundle.main.url(forResource: \"video2\", withExtension: \"MOV\")\nasset = AVAsset(url: url!)\nsource = AVAssetSource(asset: asset)\nsource.selectedTimeRange = CMTimeRange(start: CMTime.zero, duration: asset.duration)\ntimeRange = source.selectedTimeRange\ntimeRange.start = CMTimeRangeGetEnd(renderLayer1.timeRange)\nlet renderLayer2 = RenderLayer(timeRange: timeRange, source: source)\n    \n// 2. Composition\nlet composition = RenderComposition()\ncomposition.renderSize = CGSize(width: 1280, height: 720)\ncomposition.layers = [renderLayer1, renderLayer2]\n\n// 3. VideoLab\nlet videoLab = VideoLab(renderComposition: composition)\n\n// 4. Make playerItem\nlet playerItem = videoLab.makePlayerItem()\n```\n\n1. 创建 `RenderLayer`\n2. 创建 `RenderComposition`，设置 `renderSize` 和 `layers`\n3. 使用 `renderComposition` 创建 `VideoLab`\n4. 生成 `AVPlayerItem` 或 `AVAssetExportSession`\n\n### 更高级的使用\n\n#### 变换\n\n```swift\nvar center = CGPoint(x: 0.25, y: 0.25)\nvar transform = Transform(center: center, rotation: 0, scale: 0.5)\nrenderLayer1.transform = transform\n```\n\n1. 使用 `center`、`rotation` 和 `scale` 创建 `Transform`\n2. `RenderLayer` 设置 `transform`\n\n#### 音频设置\n\n```swift\nlet audioConfiguration = AudioConfiguration()\nlet volumeRampTimeRange = CMTimeRange(start: CMTime.zero, duration: CMTime(seconds: 5, preferredTimescale: 600))\nlet volumeRamp1 = VolumeRamp(startVolume: 0.0, endVolume: 0.0, timeRange: volumeRampTimeRange)\naudioConfiguration.volumeRamps = [volumeRamp1]\nrenderLayer2.audioConfiguration = audioConfiguration\n```\n\n1. 创建 `AudioConfiguration`\n2. 使用 `startVolume`、`endVolume` 和 `timeRange` 创建\n `VolumeRamp` \n3. `AudioConfiguration`设置 `volumeRamps`\n4. `RenderLayer` 设置 `audioConfiguration`\n\n#### CALayer 动画\n\n导出时，为 `RenderComposition` 设置自定义的 `CALayer`\n\n```swift\ncomposition.animationLayer = \u003cYour customized CALayer\u003e\n```\n播放时，添加 `AVSynchronizedLayer` 到你显示视图的 layer 上，更多细节参考 **Text Animation Demo**.\n\n#### 关键帧动画\n\n```swift\n// 1. Keyframe animation\nlet keyTimes = [CMTime(seconds: 2, preferredTimescale: 600),\n                CMTime(seconds: 4, preferredTimescale: 600),\n                CMTime(seconds: 6, preferredTimescale: 600)]\nlet animation = KeyframeAnimation(keyPath: \"blendOpacity\",\n                                  values: [1.0, 0.2, 1.0],\n                                  keyTimes: keyTimes, timingFunctions: [.linear, .linear])\nrenderLayer1.animations = [animation]\n    \nvar transform = Transform.identity\nlet animation1 = KeyframeAnimation(keyPath: \"scale\",\n                                   values: [1.0, 1.3, 1.0],\n                                   keyTimes: keyTimes, timingFunctions: [.quadraticEaseInOut, .quadraticEaseInOut])\nlet animation2 = KeyframeAnimation(keyPath: \"rotation\",\n                                   values: [0, Float.pi / 2.0, 0],\n                                   keyTimes: keyTimes, timingFunctions: [.quadraticEaseInOut, .quadraticEaseInOut])\ntransform.animations = [animation1, animation2]\nrenderLayer1.transform = transform\n```\n\n1. 使用 `keyPath`、`values`、`keyTimes` 和  `timingFunctions` 创建 `KeyframeAnimation`。\n2. 为实现 `Animatable` 协议的结构体或者类设置 `animations`。\n\n#### 预合成\n\n```swift\nlet layerGroup = RenderLayerGroup(timeRange: timeRange)\nlayerGroup.layers = [renderLayer1, renderLayer2]\n```\n\n1. 使用 `timeRange` 创建 `RenderLayerGroup`\n2. 为 `layerGroup` 设置子 `layers`。更多细节参考 **Layer Group Demo**\n\n#### 转场\n\n我们没有转场的 layer，但是你可以添加一个给每个 RenderLayer 添加一个 transform 或者 operations，以此来创建一个转场。更多细节参考 **Transition Demo**\n\n#### 自定义特效\n\n```swift\n// Filter\nvar filter = LookupFilter()\nfilter.addTexture(lutTextures[0], at: 0)\nrenderLayer.operations = [filter]\n\n// Zoom Blur\nvar zoomblur = ZoomBlur()\nanimation = KeyframeAnimation(keyPath: \"blurSize\",\n                              values: [0.0, 3.0],\n                              keyTimes: keyTimes, timingFunctions: [.quarticEaseOut])\nzoomblur.animations = [animation]\nlayerGroup1.operations = [zoomblur]\n```\n\n1. 创建继承自 `BasicOperation` 的自定义 `Operation`。`BasicOperation` 同样实现 `Animatable` 协议。\n2. 为 `RenderLayer` 设置 `operations`。\n\n## 待办\n\n* 支持 Open GL 渲染\n* `RenderLayer` 增加速度控制\n* 提供更便捷的方式使用转场，可能是提供 `TransitionLayer`\n* 增加日志系统\n\n## 作者\n\n* 阮景雄, ruanjingxiong@gmail.com\n* 员凯, kayyyuan@gmail.com\n\n## 许可证\n\nVideoLab 使用 MIT 许可，详情请参考 [LICENSE](./LICENSE) 。\n\n","funding_links":[],"categories":["HarmonyOS"],"sub_categories":["Windows Manager"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fruanjx%2FVideoLab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fruanjx%2FVideoLab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fruanjx%2FVideoLab/lists"}