├── .gitignore ├── Document ├── README-DETAIL-CN.md ├── README-DETAIL-EN.md └── Resource │ ├── After-Effects.jpg │ ├── VideoLab-AVAudioMix-AVAudioMixInputParameters.png │ ├── VideoLab-AVAudioMix.png │ ├── VideoLab-AVComposition-AudioRenderLayer.png │ ├── VideoLab-AVComposition-AudioTrack.png │ ├── VideoLab-AVComposition-RenderComposition.png │ ├── VideoLab-AVComposition-VideoRenderLayer.png │ ├── VideoLab-AVComposition-VideoTrack.png │ ├── VideoLab-AVComposition.png │ ├── VideoLab-AVComposition2.png │ ├── VideoLab-AVVideoCompositing.png │ ├── VideoLab-AVVideoComposition-Instruction.png │ ├── VideoLab-AVVideoComposition-Render.png │ ├── VideoLab-AVVideoComposition-Render2.png │ ├── VideoLab-AVVideoComposition.png │ ├── VideoLab-Editing-with-AVFoundation-Workflow.png │ ├── VideoLab-RenderComposition.png │ ├── VideoLab-VideoLab-Workflow.png │ ├── keyframe-animation-demo.gif │ ├── multiple-layer-demo.gif │ ├── pre-compose-demo.gif │ ├── text-animation-demo.gif │ └── transition-demo.gif ├── Example ├── Podfile ├── Podfile.lock ├── Pods │ ├── Local Podspecs │ │ └── VideoLab.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ ├── project.pbxproj │ │ └── xcuserdata │ │ │ └── ruanjingxiong.xcuserdatad │ │ │ └── xcschemes │ │ │ ├── Pods-VideoLab_Example.xcscheme │ │ │ ├── Pods-VideoLab_Tests.xcscheme │ │ │ ├── VideoLab.xcscheme │ │ │ └── xcschememanagement.plist │ └── Target Support Files │ │ ├── Pods-VideoLab_Example │ │ ├── Info.plist │ │ ├── Pods-VideoLab_Example-Info.plist │ │ ├── Pods-VideoLab_Example-acknowledgements.markdown │ │ ├── Pods-VideoLab_Example-acknowledgements.plist │ │ ├── Pods-VideoLab_Example-dummy.m │ │ ├── Pods-VideoLab_Example-frameworks.sh │ │ ├── Pods-VideoLab_Example-resources.sh │ │ ├── Pods-VideoLab_Example-umbrella.h │ │ ├── Pods-VideoLab_Example.debug.xcconfig │ │ ├── Pods-VideoLab_Example.modulemap │ │ └── Pods-VideoLab_Example.release.xcconfig │ │ ├── Pods-VideoLab_Tests │ │ ├── Info.plist │ │ ├── Pods-VideoLab_Tests-Info.plist │ │ ├── Pods-VideoLab_Tests-acknowledgements.markdown │ │ ├── Pods-VideoLab_Tests-acknowledgements.plist │ │ ├── Pods-VideoLab_Tests-dummy.m │ │ ├── Pods-VideoLab_Tests-frameworks.sh │ │ ├── Pods-VideoLab_Tests-resources.sh │ │ ├── Pods-VideoLab_Tests-umbrella.h │ │ ├── Pods-VideoLab_Tests.debug.xcconfig │ │ ├── Pods-VideoLab_Tests.modulemap │ │ └── Pods-VideoLab_Tests.release.xcconfig │ │ └── VideoLab │ │ ├── Info.plist │ │ ├── VideoLab-Info.plist │ │ ├── VideoLab-dummy.m │ │ ├── VideoLab-prefix.pch │ │ ├── VideoLab-umbrella.h │ │ ├── VideoLab.debug.xcconfig │ │ ├── VideoLab.modulemap │ │ ├── VideoLab.release.xcconfig │ │ └── VideoLab.xcconfig ├── Tests │ ├── Info.plist │ └── Tests.swift ├── VideoLab.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── VideoLab-Example.xcscheme ├── VideoLab.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ ├── IDEWorkspaceChecks.plist │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ └── ruanjingxiong.xcuserdatad │ │ ├── IDEFindNavigatorScopes.plist │ │ ├── WorkspaceSettings.xcsettings │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist └── VideoLab │ ├── AppDelegate.swift │ ├── AppDemo │ ├── Effect │ │ ├── Controller │ │ │ └── VLEEffectViewController.swift │ │ ├── Model │ │ │ └── VLEEffectItemModel.swift │ │ └── View │ │ │ ├── VLEEffectFirstLevelView.swift │ │ │ └── VLEEffectIconView.swift │ ├── Export │ │ ├── Controller │ │ │ └── VLEExportViewController.swift │ │ └── View │ │ │ ├── VLEExportConfigFrameDurationView.swift │ │ │ ├── VLEExportConfigResolutionView.swift │ │ │ ├── VLEExportNavigatorView.swift │ │ │ ├── VLEExportSaveView.swift │ │ │ └── VLEExportShareView.swift │ ├── Extension │ │ └── UIColor+Extension.swift │ ├── Main │ │ ├── VLEConstants.swift │ │ ├── VLEMainMediator.swift │ │ ├── VLEMainViewController.swift │ │ └── VLENavViewController.swift │ ├── Picker │ │ ├── Controller │ │ │ └── VLEPickerViewController.swift │ │ ├── Model │ │ │ ├── VLEPickerAlbumListModel.swift │ │ │ ├── VLEPickerAssetModel.swift │ │ │ ├── VLEPickerAudioListModel.swift │ │ │ ├── VLEPickerFetchAssetManager.swift │ │ │ └── VLEPickerStickerListModel.swift │ │ └── View │ │ │ ├── VLEPickerAlbumListView.swift │ │ │ ├── VLEPickerAlbumPhotoCell.swift │ │ │ ├── VLEPickerAlbumSwitchView.swift │ │ │ ├── VLEPickerAlbumVideoCell.swift │ │ │ ├── VLEPickerAudioCell.swift │ │ │ ├── VLEPickerAudioListView.swift │ │ │ ├── VLEPickerBottomView.swift │ │ │ ├── VLEPickerNavigatorView.swift │ │ │ ├── VLEPickerStickerCell.swift │ │ │ └── VLEPickerStickerListView.swift │ ├── Playback │ │ ├── Controller │ │ │ └── VLEPlaybackViewController.swift │ │ └── View │ │ │ ├── VLEPlaybackControlView.swift │ │ │ └── VLEPlaybackView.swift │ └── Timeline │ │ ├── Controller │ │ └── VLETimeLineViewController.swift │ │ ├── Model │ │ ├── VLETimeLineConfig.swift │ │ ├── VLETimeLineItemModel.swift │ │ └── VLETimeLineStateModel.swift │ │ └── View │ │ ├── VLETimeLineDragSortGridView.swift │ │ ├── VLETimeLineDragSortMoveItemView.swift │ │ ├── VLETimeLineDragSortView.swift │ │ ├── VLETimeLineGeneralEffectTrackView.swift │ │ ├── VLETimeLineRenderTrackDragView.swift │ │ ├── VLETimeLineRenderTrackSegmentView.swift │ │ ├── VLETimeLineRenderTrackView.swift │ │ ├── VLETimeLineScaleView.swift │ │ ├── VLETimeLineSeparateRenderTrackView.swift │ │ ├── VLETimeLineToolBarView.swift │ │ └── VLETimeLineTrackLongPressTipView.swift │ ├── FeaturesDemo │ ├── VLEDemoViewController.swift │ ├── VLEPlayerViewController.swift │ └── ViewController.swift │ ├── Info.plist │ └── Resource │ ├── Audio │ ├── effect_audio_1.m4a │ ├── effect_audio_10.m4a │ ├── effect_audio_11.m4a │ ├── effect_audio_12.m4a │ ├── effect_audio_13.m4a │ ├── effect_audio_14.m4a │ ├── effect_audio_15.m4a │ ├── effect_audio_16.m4a │ ├── effect_audio_2.m4a │ ├── effect_audio_3.m4a │ ├── effect_audio_4.m4a │ ├── effect_audio_5.m4a │ ├── effect_audio_6.m4a │ ├── effect_audio_7.m4a │ ├── effect_audio_8.m4a │ └── effect_audio_9.m4a │ ├── Filters │ ├── LUT_M01.png │ ├── LUT_M02.png │ ├── LUT_M03.png │ ├── LUT_M05.png │ ├── LUT_M06.png │ ├── LUT_M07.png │ ├── LUT_M08.png │ ├── LUT_M09.png │ ├── LUT_M11.png │ └── LUT_M12.png │ ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ ├── Contents.json │ ├── effect_level1_audio.imageset │ │ ├── Contents.json │ │ ├── effect_level1_audio.png │ │ ├── effect_level1_audio@2x.png │ │ └── effect_level1_audio@3x.png │ ├── effect_level1_canvas.imageset │ │ ├── Contents.json │ │ ├── effect_level1_canvas.png │ │ ├── effect_level1_canvas@2x.png │ │ └── effect_level1_canvas@3x.png │ ├── effect_level1_filter.imageset │ │ ├── Contents.json │ │ ├── effect_level1_filter.png │ │ ├── effect_level1_filter@2x.png │ │ └── effect_level1_filter@3x.png │ ├── effect_level1_specialeffect.imageset │ │ ├── Contents.json │ │ ├── effect_level1_specialeffects.png │ │ ├── effect_level1_specialeffects@2x.png │ │ └── effect_level1_specialeffects@3x.png │ ├── effect_level1_sticker.imageset │ │ ├── Contents.json │ │ ├── effect_level1_sticker.png │ │ ├── effect_level1_sticker@2x.png │ │ └── effect_level1_sticker@3x.png │ ├── effect_level1_text.imageset │ │ ├── Contents.json │ │ ├── effect_level1_text.png │ │ ├── effect_level1_text@2x.png │ │ └── effect_level1_text@3x.png │ ├── effect_sticker_1.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_1.png │ │ ├── effect_sticker_1@2x.png │ │ └── effect_sticker_1@3x.png │ ├── effect_sticker_10.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_10.png │ │ ├── effect_sticker_10@2x.png │ │ └── effect_sticker_10@3x.png │ ├── effect_sticker_11.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_11.png │ │ ├── effect_sticker_11@2x.png │ │ └── effect_sticker_11@3x.png │ ├── effect_sticker_12.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_12.png │ │ ├── effect_sticker_12@2x.png │ │ └── effect_sticker_12@3x.png │ ├── effect_sticker_13.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_13.png │ │ ├── effect_sticker_13@2x.png │ │ └── effect_sticker_13@3x.png │ ├── effect_sticker_14.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_14.png │ │ ├── effect_sticker_14@2x.png │ │ └── effect_sticker_14@3x.png │ ├── effect_sticker_15.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_15.png │ │ ├── effect_sticker_15@2x.png │ │ └── effect_sticker_15@3x.png │ ├── effect_sticker_16.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_16.png │ │ ├── effect_sticker_16@2x.png │ │ └── effect_sticker_16@3x.png │ ├── effect_sticker_17.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_17.png │ │ ├── effect_sticker_17@2x.png │ │ └── effect_sticker_17@3x.png │ ├── effect_sticker_18.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_18@2x.png │ │ └── effect_sticker_18@3x.png │ ├── effect_sticker_2.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_2.png │ │ ├── effect_sticker_2@2x.png │ │ └── effect_sticker_2@3x.png │ ├── effect_sticker_3.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_3.png │ │ ├── effect_sticker_3@2x.png │ │ └── effect_sticker_3@3x.png │ ├── effect_sticker_4.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_4.png │ │ ├── effect_sticker_4@2x.png │ │ └── effect_sticker_4@3x.png │ ├── effect_sticker_5.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_5.png │ │ ├── effect_sticker_5@2x.png │ │ └── effect_sticker_5@3x.png │ ├── effect_sticker_6.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_6.png │ │ ├── effect_sticker_6@2x.png │ │ └── effect_sticker_6@3x.png │ ├── effect_sticker_7.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_7.png │ │ ├── effect_sticker_7@2x.png │ │ └── effect_sticker_7@3x.png │ ├── effect_sticker_8.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_8.png │ │ ├── effect_sticker_8@2x.png │ │ └── effect_sticker_8@3x.png │ ├── effect_sticker_9.imageset │ │ ├── Contents.json │ │ ├── effect_sticker_9.png │ │ ├── effect_sticker_9@2x.png │ │ └── effect_sticker_9@3x.png │ ├── export_share_pengyouquan.imageset │ │ ├── Contents.json │ │ ├── export_share_pengyouquan.png │ │ ├── export_share_pengyouquan@2x.png │ │ └── export_share_pengyouquan@3x.png │ ├── export_share_qq.imageset │ │ ├── Contents.json │ │ ├── export_share_qq.png │ │ ├── export_share_qq@2x.png │ │ └── export_share_qq@3x.png │ ├── export_share_qqzone.imageset │ │ ├── Contents.json │ │ ├── export_share_qqzone.png │ │ ├── export_share_qqzone@2x.png │ │ └── export_share_qqzone@3x.png │ ├── export_share_wechat.imageset │ │ ├── Contents.json │ │ ├── export_share_wechat.png │ │ ├── export_share_wechat@2x.png │ │ └── export_share_wechat@3x.png │ ├── export_share_weibo.imageset │ │ ├── Contents.json │ │ ├── export_share_weibo.png │ │ ├── export_share_weibo@2x.png │ │ └── export_share_weibo@3x.png │ ├── nav_close_button.imageset │ │ ├── Contents.json │ │ ├── nav_close_button.png │ │ ├── nav_close_button@2x.png │ │ └── nav_close_button@3x.png │ ├── nav_export_button.imageset │ │ ├── Contents.json │ │ ├── nav_export_button.png │ │ ├── nav_export_button@2x.png │ │ └── nav_export_button@3x.png │ ├── nav_help_button.imageset │ │ ├── Contents.json │ │ ├── nav_help_button.png │ │ ├── nav_help_button@2x.png │ │ └── nav_help_button@3x.png │ ├── nav_projectlist_button.imageset │ │ ├── Contents.json │ │ ├── nav_projectlist_button.png │ │ ├── nav_projectlist_button@2x.png │ │ └── nav_projectlist_button@3x.png │ ├── nav_set_button.imageset │ │ ├── Contents.json │ │ ├── nav_set_button.png │ │ ├── nav_set_button@2x.png │ │ └── nav_set_button@3x.png │ ├── picker_album_selecticon.imageset │ │ ├── Contents.json │ │ ├── export_album_selecticon.png │ │ ├── export_album_selecticon@2x.png │ │ └── export_album_selecticon@3x.png │ ├── picker_nav_close.imageset │ │ ├── Contents.json │ │ ├── export_nav_close.png │ │ ├── export_nav_close@2x.png │ │ └── export_nav_close@3x.png │ ├── picker_nav_set.imageset │ │ ├── Contents.json │ │ ├── export_nav_set.png │ │ ├── export_nav_set@2x.png │ │ └── export_nav_set@3x.png │ ├── playback_fullscreen_button.imageset │ │ ├── Contents.json │ │ ├── playback_fullscreen_button.png │ │ ├── playback_fullscreen_button@2x.png │ │ └── playback_fullscreen_button@3x.png │ ├── playback_pause_button.imageset │ │ ├── Contents.json │ │ ├── playback_pause_button@2x.png │ │ └── playback_pause_button@3x.png │ ├── playback_play_button.imageset │ │ ├── Contents.json │ │ ├── playback_play_button.png │ │ ├── playback_play_button@2x.png │ │ └── playback_play_button@3x.png │ ├── timeline_addresource_button.imageset │ │ ├── Contents.json │ │ ├── timeline_addresource_button.png │ │ ├── timeline_addresource_button@2x.png │ │ └── timeline_addresource_button@3x.png │ ├── timeline_clip_button.imageset │ │ ├── Contents.json │ │ ├── timeline_cat_button.png │ │ ├── timeline_cat_button@2x.png │ │ └── timeline_cat_button@3x.png │ ├── timeline_dragsort_delete.imageset │ │ ├── Contents.json │ │ ├── timeline_dragsort_delete.png │ │ ├── timeline_dragsort_delete@2x.png │ │ └── timeline_dragsort_delete@3x.png │ ├── timeline_redo_button.imageset │ │ ├── Contents.json │ │ ├── timeline_redo_button.png │ │ ├── timeline_redo_button@2x.png │ │ └── timeline_redo_button@3x.png │ └── timeline_undo_button.imageset │ │ ├── Contents.json │ │ ├── timeline_undo_button.png │ │ ├── timeline_undo_button@2x.png │ │ └── timeline_undo_button@3x.png │ ├── Storyboard │ ├── LaunchScreen.xib │ └── Main.storyboard │ ├── Video │ ├── video1.MOV │ ├── video2.MOV │ ├── video3.MOV │ └── video4.MOV │ ├── image1.JPG │ ├── image2.HEIC │ └── image3.HEIC ├── LICENSE ├── README-CN.md ├── README.md ├── VideoLab.podspec └── VideoLab ├── Audio ├── AudioRenderLayer.swift └── AudioRenderLayerGroup.swift ├── AudioConfiguration.swift ├── KeyframeAnimation.swift ├── Render ├── Base │ ├── Color.swift │ ├── MathLibrary.swift │ ├── MetalRendering.swift │ ├── MetalRenderingDevice.swift │ ├── Position.swift │ ├── ShaderUniformSettings.swift │ ├── Size.swift │ ├── Texture.swift │ └── TextureCache.swift └── Operations │ ├── BasicOperation.swift │ ├── BlendModeConstants.h │ ├── BlendOperation.metal │ ├── BlendOperation.swift │ ├── BrightnessAdjustment.metal │ ├── BrightnessAdjustment.swift │ ├── ChromaKeying.metal │ ├── ChromaKeying.swift │ ├── LookupFilter.metal │ ├── LookupFilter.swift │ ├── OperationConstants.h │ ├── OperationShaderTypes.h │ ├── Passthrough.metal │ ├── Passthrough.swift │ ├── YUVToRGBConversion.metal │ ├── YUVToRGBConversion.swift │ ├── ZoomBlur.metal │ └── ZoomBlur.swift ├── RenderComposition.swift ├── RenderLayer.swift ├── RenderLayerGroup.swift ├── Source ├── AVAssetSource.swift ├── ImageSource.swift ├── PHAssetImageSource.swift ├── PHAssetVideoSource.swift └── Source.swift ├── Text ├── TextAnimationLayer.swift └── TextOpacityAnimationLayer.swift ├── TimingFunction.swift ├── Transform.swift ├── Video ├── LayerCompositor.swift ├── VideoCompositionInstruction.swift ├── VideoCompositor.swift ├── VideoRenderLayer.swift └── VideoRenderLayerGroup.swift ├── VideoLab.bundle └── BlankVideo.mov └── VideoLab.swift /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | # Created by https://www.gitignore.io/api/swift 3 | # Edit at https://www.gitignore.io/?templates=swift 4 | 5 | ### Swift ### 6 | # Xcode 7 | # 8 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 9 | 10 | ## Build generated 11 | build/ 12 | DerivedData/ 13 | 14 | ## Various settings 15 | *.pbxuser 16 | !default.pbxuser 17 | *.mode1v3 18 | !default.mode1v3 19 | *.mode2v3 20 | !default.mode2v3 21 | *.perspectivev3 22 | !default.perspectivev3 23 | xcuserdata/ 24 | 25 | ## Other 26 | *.moved-aside 27 | *.xccheckout 28 | *.xcscmblueprint 29 | 30 | ## Obj-C/Swift specific 31 | *.hmap 32 | *.ipa 33 | *.dSYM.zip 34 | *.dSYM 35 | 36 | ## Playgrounds 37 | timeline.xctimeline 38 | playground.xcworkspace 39 | 40 | # Swift Package Manager 41 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 42 | # Packages/ 43 | # Package.pins 44 | # Package.resolved 45 | .build/ 46 | # Add this line if you want to avoid checking in Xcode SPM integration. 47 | # .swiftpm/xcode 48 | 49 | # CocoaPods 50 | # We recommend against adding the Pods directory to your .gitignore. However 51 | # you should judge for yourself, the pros and cons are mentioned at: 52 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 53 | Pods/ 54 | # Add this line if you want to avoid checking in source code from the Xcode workspace 55 | # *.xcworkspace 56 | 57 | # Carthage 58 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 59 | # Carthage/Checkouts 60 | 61 | Carthage/Build 62 | 63 | # Accio dependency management 64 | Dependencies/ 65 | .accio/ 66 | 67 | # fastlane 68 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 69 | # screenshots whenever they are needed. 70 | # For more information about the recommended setup visit: 71 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 72 | 73 | fastlane/report.xml 74 | fastlane/Preview.html 75 | fastlane/screenshots/**/*.png 76 | fastlane/test_output 77 | 78 | # Code Injection 79 | # After new code Injection tools there's a generated folder /iOSInjectionProject 80 | # https://github.com/johnno1962/injectionforxcode 81 | 82 | iOSInjectionProject/ 83 | 84 | # End of https://www.gitignore.io/api/swift -------------------------------------------------------------------------------- /Document/Resource/After-Effects.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/After-Effects.jpg -------------------------------------------------------------------------------- /Document/Resource/VideoLab-AVAudioMix-AVAudioMixInputParameters.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-AVAudioMix-AVAudioMixInputParameters.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-AVAudioMix.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-AVAudioMix.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-AVComposition-AudioRenderLayer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-AVComposition-AudioRenderLayer.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-AVComposition-AudioTrack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-AVComposition-AudioTrack.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-AVComposition-RenderComposition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-AVComposition-RenderComposition.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-AVComposition-VideoRenderLayer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-AVComposition-VideoRenderLayer.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-AVComposition-VideoTrack.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-AVComposition-VideoTrack.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-AVComposition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-AVComposition.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-AVComposition2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-AVComposition2.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-AVVideoCompositing.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-AVVideoCompositing.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-AVVideoComposition-Instruction.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-AVVideoComposition-Instruction.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-AVVideoComposition-Render.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-AVVideoComposition-Render.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-AVVideoComposition-Render2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-AVVideoComposition-Render2.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-AVVideoComposition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-AVVideoComposition.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-Editing-with-AVFoundation-Workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-Editing-with-AVFoundation-Workflow.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-RenderComposition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-RenderComposition.png -------------------------------------------------------------------------------- /Document/Resource/VideoLab-VideoLab-Workflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/VideoLab-VideoLab-Workflow.png -------------------------------------------------------------------------------- /Document/Resource/keyframe-animation-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/keyframe-animation-demo.gif -------------------------------------------------------------------------------- /Document/Resource/multiple-layer-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/multiple-layer-demo.gif -------------------------------------------------------------------------------- /Document/Resource/pre-compose-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/pre-compose-demo.gif -------------------------------------------------------------------------------- /Document/Resource/text-animation-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/text-animation-demo.gif -------------------------------------------------------------------------------- /Document/Resource/transition-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Document/Resource/transition-demo.gif -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | platform :ios, '11.0' 3 | use_frameworks! 4 | 5 | target 'VideoLab_Example' do 6 | pod 'VideoLab', :path => '../' 7 | pod 'LookinServer', :configurations => ['Debug'] 8 | pod 'SnapKit' 9 | pod 'PKHUD', '~> 5.0' 10 | 11 | target 'VideoLab_Tests' do 12 | inherit! :search_paths 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - LookinServer (1.0.5) 3 | - PKHUD (5.3.0) 4 | - SnapKit (5.6.0) 5 | - VideoLab (0.0.1) 6 | 7 | DEPENDENCIES: 8 | - LookinServer 9 | - PKHUD (~> 5.0) 10 | - SnapKit 11 | - VideoLab (from `../`) 12 | 13 | SPEC REPOS: 14 | https://github.com/CocoaPods/Specs.git: 15 | - LookinServer 16 | - PKHUD 17 | - SnapKit 18 | 19 | EXTERNAL SOURCES: 20 | VideoLab: 21 | :path: "../" 22 | 23 | SPEC CHECKSUMS: 24 | LookinServer: 3d9a02529ed94a6a08154440c26f6d7f453bb1e7 25 | PKHUD: 98f3e4bc904b9c916f1c5bb6d765365b5357291b 26 | SnapKit: e01d52ebb8ddbc333eefe2132acf85c8227d9c25 27 | VideoLab: 1665165e7c258f118b7b37cea7a5597359353ffb 28 | 29 | PODFILE CHECKSUM: 472dcce9a6d5e812619b55163e342d558fbd6045 30 | 31 | COCOAPODS: 1.11.3 32 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/VideoLab.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "VideoLab", 3 | "version": "0.0.1", 4 | "summary": "High-performance and flexible video editing and effects framework, based on AVFoundation and Metal.", 5 | "description": "High-performance and flexible video editing and effects framework, based on AVFoundation and Metal.\n* High-performance real-time video editing and exporting.\n* Highly free to combination of video, picture, audio.\n* Support audio pitch setting and volume adjustment.\n* Support for CALayer vector animations. So support complex text animations.\n* Support keyframe animation.\n* Support for After Effect-like pre-compose.\n* Support transitions.\n* Support custom effects. Such as lut filter, zoom blur, etc.", 6 | "homepage": "https://github.com/ruanjx/VideoLab", 7 | "license": { 8 | "type": "MIT", 9 | "file": "LICENSE" 10 | }, 11 | "authors": { 12 | "bear": "ruanjingxiong@gmail.com" 13 | }, 14 | "source": { 15 | "git": "https://github.com/ruanjx/VideoLab.git", 16 | "tag": "0.0.1" 17 | }, 18 | "platforms": { 19 | "ios": "11.0" 20 | }, 21 | "swift_versions": "5", 22 | "source_files": "VideoLab/**/*.{swift,h,m,metal}", 23 | "resources": "VideoLab/VideoLab.bundle", 24 | "swift_version": "5" 25 | } 26 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - LookinServer (1.0.5) 3 | - PKHUD (5.3.0) 4 | - SnapKit (5.6.0) 5 | - VideoLab (0.0.1) 6 | 7 | DEPENDENCIES: 8 | - LookinServer 9 | - PKHUD (~> 5.0) 10 | - SnapKit 11 | - VideoLab (from `../`) 12 | 13 | SPEC REPOS: 14 | https://github.com/CocoaPods/Specs.git: 15 | - LookinServer 16 | - PKHUD 17 | - SnapKit 18 | 19 | EXTERNAL SOURCES: 20 | VideoLab: 21 | :path: "../" 22 | 23 | SPEC CHECKSUMS: 24 | LookinServer: 3d9a02529ed94a6a08154440c26f6d7f453bb1e7 25 | PKHUD: 98f3e4bc904b9c916f1c5bb6d765365b5357291b 26 | SnapKit: e01d52ebb8ddbc333eefe2132acf85c8227d9c25 27 | VideoLab: 1665165e7c258f118b7b37cea7a5597359353ffb 28 | 29 | PODFILE CHECKSUM: 472dcce9a6d5e812619b55163e342d558fbd6045 30 | 31 | COCOAPODS: 1.11.3 32 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcuserdata/ruanjingxiong.xcuserdatad/xcschemes/Pods-VideoLab_Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 53 | 54 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcuserdata/ruanjingxiong.xcuserdatad/xcschemes/Pods-VideoLab_Tests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 50 | 51 | 53 | 54 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcuserdata/ruanjingxiong.xcuserdatad/xcschemes/VideoLab.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/xcuserdata/ruanjingxiong.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Pods-VideoLab_Example.xcscheme 8 | 9 | isShown 10 | 11 | 12 | Pods-VideoLab_Tests.xcscheme 13 | 14 | isShown 15 | 16 | 17 | VideoLab.xcscheme 18 | 19 | isShown 20 | 21 | 22 | 23 | SuppressBuildableAutocreation 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Example/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Example/Pods-VideoLab_Example-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Example/Pods-VideoLab_Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_VideoLab_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_VideoLab_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Example/Pods-VideoLab_Example-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_VideoLab_ExampleVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_VideoLab_ExampleVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Example/Pods-VideoLab_Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LookinServer" "${PODS_CONFIGURATION_BUILD_DIR}/PKHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/VideoLab" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LookinServer/LookinServer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PKHUD/PKHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/VideoLab/VideoLab.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_LDFLAGS = $(inherited) -framework "LookinServer" -framework "PKHUD" -framework "SnapKit" -framework "UIKit" -framework "VideoLab" 9 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 10 | PODS_BUILD_DIR = ${BUILD_DIR} 11 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 12 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 13 | PODS_ROOT = ${SRCROOT}/Pods 14 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Example/Pods-VideoLab_Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_VideoLab_Example { 2 | umbrella header "Pods-VideoLab_Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Example/Pods-VideoLab_Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 3 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PKHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/VideoLab" 4 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 5 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PKHUD/PKHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/VideoLab/VideoLab.framework/Headers" 6 | LD_RUNPATH_SEARCH_PATHS = $(inherited) /usr/lib/swift '@executable_path/Frameworks' '@loader_path/Frameworks' 7 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 8 | OTHER_LDFLAGS = $(inherited) -framework "PKHUD" -framework "SnapKit" -framework "VideoLab" 9 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 10 | PODS_BUILD_DIR = ${BUILD_DIR} 11 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 12 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 13 | PODS_ROOT = ${SRCROOT}/Pods 14 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 15 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 16 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Tests/Pods-VideoLab_Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Tests/Pods-VideoLab_Tests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Tests/Pods-VideoLab_Tests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Tests/Pods-VideoLab_Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_VideoLab_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_VideoLab_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Tests/Pods-VideoLab_Tests-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_VideoLab_TestsVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_VideoLab_TestsVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Tests/Pods-VideoLab_Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LookinServer" "${PODS_CONFIGURATION_BUILD_DIR}/PKHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/VideoLab" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/LookinServer/LookinServer.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/PKHUD/PKHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/VideoLab/VideoLab.framework/Headers" 5 | OTHER_LDFLAGS = $(inherited) -framework "LookinServer" -framework "PKHUD" -framework "SnapKit" -framework "UIKit" -framework "VideoLab" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Tests/Pods-VideoLab_Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_VideoLab_Tests { 2 | umbrella header "Pods-VideoLab_Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-VideoLab_Tests/Pods-VideoLab_Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PKHUD" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit" "${PODS_CONFIGURATION_BUILD_DIR}/VideoLab" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PKHUD/PKHUD.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/SnapKit/SnapKit.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/VideoLab/VideoLab.framework/Headers" 5 | OTHER_LDFLAGS = $(inherited) -framework "PKHUD" -framework "SnapKit" -framework "VideoLab" 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 9 | PODS_ROOT = ${SRCROOT}/Pods 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 12 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/VideoLab/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/VideoLab/VideoLab-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 0.0.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/VideoLab/VideoLab-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_VideoLab : NSObject 3 | @end 4 | @implementation PodsDummy_VideoLab 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/VideoLab/VideoLab-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/VideoLab/VideoLab-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "BlendModeConstants.h" 14 | #import "OperationConstants.h" 15 | #import "OperationShaderTypes.h" 16 | 17 | FOUNDATION_EXPORT double VideoLabVersionNumber; 18 | FOUNDATION_EXPORT const unsigned char VideoLabVersionString[]; 19 | 20 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/VideoLab/VideoLab.debug.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/VideoLab 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 12 | SKIP_INSTALL = YES 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/VideoLab/VideoLab.modulemap: -------------------------------------------------------------------------------- 1 | framework module VideoLab { 2 | umbrella header "VideoLab-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/VideoLab/VideoLab.release.xcconfig: -------------------------------------------------------------------------------- 1 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = NO 2 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/VideoLab 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LIBRARY_SEARCH_PATHS = $(inherited) "${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" /usr/lib/swift 5 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 6 | PODS_BUILD_DIR = ${BUILD_DIR} 7 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT} 9 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 10 | PODS_XCFRAMEWORKS_BUILD_DIR = $(PODS_CONFIGURATION_BUILD_DIR)/XCFrameworkIntermediates 11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 12 | SKIP_INSTALL = YES 13 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 14 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/VideoLab/VideoLab.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/VideoLab 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /Example/Tests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /Example/Tests/Tests.swift: -------------------------------------------------------------------------------- 1 | import XCTest 2 | 3 | class Tests: XCTestCase { 4 | 5 | override func setUp() { 6 | super.setUp() 7 | // Put setup code here. This method is called before the invocation of each test method in the class. 8 | } 9 | 10 | override func tearDown() { 11 | // Put teardown code here. This method is called after the invocation of each test method in the class. 12 | super.tearDown() 13 | } 14 | 15 | func testExample() { 16 | // This is an example of a functional test case. 17 | XCTAssert(true, "Pass") 18 | } 19 | 20 | func testPerformanceExample() { 21 | // This is an example of a performance test case. 22 | self.measure() { 23 | // Put the code you want to measure the time of here. 24 | } 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /Example/VideoLab.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/VideoLab.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/VideoLab.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/VideoLab.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Example/VideoLab.xcworkspace/xcuserdata/ruanjingxiong.xcuserdatad/IDEFindNavigatorScopes.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Example/VideoLab.xcworkspace/xcuserdata/ruanjingxiong.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildLocationStyle 6 | UseAppPreferences 7 | CustomBuildLocationType 8 | RelativeToDerivedData 9 | DerivedDataLocationStyle 10 | Default 11 | IssueFilterStyle 12 | ShowActiveSchemeOnly 13 | LiveSourceIssuesEnabled 14 | 15 | ShowSharedSchemesAutomaticallyEnabled 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Example/VideoLab.xcworkspace/xcuserdata/ruanjingxiong.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 16 | 17 | 18 | 20 | 25 | 26 | 27 | 29 | 41 | 42 | 43 | 45 | 55 | 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/3. 6 | // Copyright (c) 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 24 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Effect/Controller/VLEEffectViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEEffectViewController.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/7/21. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class VLEEffectViewController: UIViewController{ 13 | 14 | let model: VLEEffectItemModel = VLEEffectItemModel.init() 15 | lazy var firstLevelView: VLEEffectFirstLevelView = { 16 | let view = VLEEffectFirstLevelView.init(with: model) 17 | return view 18 | }() 19 | 20 | override func viewDidLoad() { 21 | self.view.backgroundColor = UIColor.init(hexString: "#212123") 22 | self.view.addSubview(firstLevelView) 23 | firstLevelView.snp.makeConstraints { make in 24 | make.height.equalTo(52) 25 | make.width.top.left.equalToSuperview() 26 | } 27 | addObserverFromNotification() 28 | } 29 | 30 | func addObserverFromNotification() { 31 | let name1 = Notification.Name.init(rawValue: VLEConstants.VLETImeLineShowDragSortViewNotification) 32 | NotificationCenter.default.addObserver(self, selector: #selector(showDragSortViewAction), name: name1, object: nil) 33 | let name2 = Notification.Name.init(rawValue: VLEConstants.VLETimeLineRemoveDragSortViewNotification) 34 | NotificationCenter.default.addObserver(self, selector: #selector(removeDragSortViewAction), name: name2, object: nil) 35 | } 36 | 37 | @objc func showDragSortViewAction() { 38 | self.view.isHidden = true 39 | } 40 | 41 | @objc func removeDragSortViewAction() { 42 | self.view.isHidden = false 43 | } 44 | 45 | deinit { 46 | NotificationCenter.default.removeObserver(self) 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Effect/Model/VLEEffectItemModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEEffectItemModel.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/10/9. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | enum VLEEffectFirstLevelItemType { 12 | case canvas 13 | case text 14 | case sticker 15 | case audio 16 | case filter 17 | case specialeffect 18 | } 19 | 20 | class VLEEffectItemModel { 21 | 22 | static let kIconKey = "icon" 23 | static let kIconType = "type" 24 | static let kIconTitleKey = "iconTitle" 25 | 26 | let firstLevelItemArray = [[kIconKey: "effect_level1_canvas", kIconTitleKey: "画布", kIconType: VLEEffectFirstLevelItemType.canvas], 27 | [kIconKey: "effect_level1_text", kIconTitleKey: "文本", kIconType: VLEEffectFirstLevelItemType.text], 28 | [kIconKey: "effect_level1_sticker", kIconTitleKey: "贴纸", kIconType: VLEEffectFirstLevelItemType.sticker], 29 | [kIconKey: "effect_level1_audio", kIconTitleKey: "音频", kIconType: VLEEffectFirstLevelItemType.audio], 30 | [kIconKey: "effect_level1_filter", kIconTitleKey: "滤镜", kIconType:VLEEffectFirstLevelItemType.filter], 31 | [kIconKey: "effect_level1_specialeffect", kIconTitleKey: "特效", kIconType: VLEEffectFirstLevelItemType.specialeffect]] 32 | } 33 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Effect/View/VLEEffectIconView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEEffectIconView.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/10/9. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class VLEEffectIconView: UIView { 13 | 14 | lazy var iconImageView: UIImageView = { 15 | let imageView = UIImageView.init() 16 | return imageView 17 | }() 18 | 19 | lazy var titleLabel: UILabel = { 20 | let label = UILabel.init() 21 | label.font = UIFont.systemFont(ofSize: 12) 22 | label.textColor = UIColor.init(hexString: "#D8D8D8") 23 | return label 24 | }() 25 | 26 | init(with iconImage: String, title: String) { 27 | super.init(frame: CGRect.zero) 28 | iconImageView.image = UIImage.init(named: iconImage) 29 | titleLabel.text = title 30 | self.addSubview(iconImageView) 31 | iconImageView.snp.makeConstraints { make in 32 | make.size.equalTo(CGSize.init(width: 32, height: 32)) 33 | make.centerX.equalToSuperview() 34 | make.top.equalToSuperview() 35 | } 36 | self.addSubview(titleLabel) 37 | titleLabel.snp.makeConstraints { make in 38 | make.top.equalTo(iconImageView.snp.bottom).offset(0) 39 | make.centerX.equalToSuperview() 40 | make.height.equalTo(17) 41 | } 42 | } 43 | 44 | required init?(coder: NSCoder) { 45 | fatalError("") 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Export/View/VLEExportNavigatorView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEExportNavigatorView.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/9/22. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class VLEExportNavigatorView: UIView { 13 | 14 | lazy var titleLabel: UILabel = { 15 | let label = UILabel.init() 16 | label.textColor = UIColor.init(hexString: "#BABABA") 17 | label.text = "导出" 18 | label.font = UIFont.boldSystemFont(ofSize: 14) 19 | return label 20 | }() 21 | 22 | lazy var closeButton: UIButton = { 23 | let button = UIButton.init() 24 | button.setBackgroundImage(UIImage.init(named: "nav_close_button"), for: UIControl.State.normal) 25 | button.addTarget(self, action: #selector(closeButtonClickAction), for: UIControl.Event.touchUpInside) 26 | return button 27 | }() 28 | 29 | var clickCloseButtonBlock: (() -> Void)? 30 | 31 | override init(frame: CGRect) { 32 | super.init(frame: frame) 33 | 34 | self.addSubview(titleLabel) 35 | titleLabel.snp.makeConstraints { make in 36 | make.center.equalToSuperview() 37 | } 38 | 39 | self.addSubview(closeButton) 40 | closeButton.snp.makeConstraints { make in 41 | make.size.equalTo(CGSize.init(width: 30, height: 30)) 42 | make.centerY.equalToSuperview() 43 | make.left.equalTo(self.snp.left).offset(21) 44 | } 45 | } 46 | 47 | required init?(coder: NSCoder) { 48 | fatalError("") 49 | } 50 | 51 | @objc func closeButtonClickAction() { 52 | self.clickCloseButtonBlock?() 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Export/View/VLEExportSaveView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEExportSaveView.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/9/22. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | protocol VLEExportSaveViewDelegate: NSObjectProtocol { 13 | func exportSaveViewClickSaveButton(_ button: UIButton) 14 | } 15 | 16 | class VLEExportSaveView: UIView { 17 | weak var delegate: VLEExportSaveViewDelegate? 18 | 19 | lazy var saveButton: UIButton = { 20 | let button = UIButton.init() 21 | button.setBackgroundImage(UIImage.init(named: "nav_export_button"), for: UIControl.State.normal) 22 | button.addTarget(self, action: #selector(saveButtonClickAction(sender:)), for: UIControl.Event.touchUpInside) 23 | return button 24 | }() 25 | 26 | lazy var saveLabel: UILabel = { 27 | let label = UILabel.init() 28 | label.font = UIFont.systemFont(ofSize: 15) 29 | label.textColor = UIColor.init(hexString: "#FFFFFF", alpha: 0.7) 30 | label.text = "导出至本地" 31 | return label 32 | }() 33 | 34 | init(delegate: VLEExportSaveViewDelegate) { 35 | self.delegate = delegate 36 | super.init(frame: CGRect.zero) 37 | self.addSubview(saveButton) 38 | saveButton.snp.makeConstraints { make in 39 | make.size.equalTo(CGSize.init(width: 60, height: 60)) 40 | make.centerX.equalToSuperview() 41 | make.top.equalTo(self.snp.top).offset(10) 42 | } 43 | 44 | self.addSubview(saveLabel) 45 | saveLabel.snp.makeConstraints { make in 46 | make.centerX.equalTo(saveButton) 47 | make.top.equalTo(saveButton.snp.bottom) 48 | } 49 | } 50 | 51 | required init?(coder: NSCoder) { 52 | fatalError("") 53 | } 54 | 55 | @objc func saveButtonClickAction(sender: UIButton) { 56 | self.delegate?.exportSaveViewClickSaveButton(sender) 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Main/VLEConstants.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEConstants.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/10/19. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class VLEConstants { 12 | static let VLETimeLineAssetDidIsEmptyNotification = "VLETimeLineAssetIsEmptyNotification" 13 | static let VLETimeLineAssetDidIsNonemptyNotification = "VLETimeLineAssetIsNonemptyNotification" 14 | static let VLETImeLineShowDragSortViewNotification = "VLETImeLineShowDragSortViewNotification" 15 | static let VLETimeLineRemoveDragSortViewNotification = "VLETimeLineRemoveDragSortViewNotification" 16 | } 17 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Picker/Model/VLEPickerAlbumListModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEPickerAlbumListModel.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/9/14. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Photos 11 | 12 | class VLEPickerAlbumListModel: NSObject { 13 | 14 | let title: String 15 | var count: Int { 16 | return result.count 17 | } 18 | let option: PHFetchOptions 19 | var result: PHFetchResult 20 | var models: [VLEPickerAssetModel] = [] 21 | let collection: PHAssetCollection 22 | 23 | public init( 24 | title: String, 25 | result: PHFetchResult, 26 | collection: PHAssetCollection, 27 | option: PHFetchOptions, 28 | isCameraRoll: Bool 29 | ) { 30 | self.title = title 31 | self.result = result 32 | self.collection = collection 33 | self.option = option 34 | } 35 | 36 | func refetchPhotos() { 37 | let models = VLEPickerFetchAssetManager.fetchPhoto(in: result) 38 | self.models.removeAll() 39 | self.models.append(contentsOf: models) 40 | } 41 | 42 | func refreshResult() { 43 | result = PHAsset.fetchAssets(in: collection, options: option) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Picker/Model/VLEPickerAudioListModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEPickerAudioListModel.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/10/11. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import AVFoundation 11 | 12 | class VLEPickerAudioItemModel { 13 | var url: URL 14 | var title: String 15 | var asset: AVAsset 16 | 17 | init(title: String, url: URL) { 18 | self.url = url 19 | self.title = title 20 | self.asset = AVAsset.init(url: self.url) 21 | } 22 | } 23 | 24 | class VLEPickerAudioListModel { 25 | 26 | var itemModelArray: [VLEPickerAudioItemModel] = [] 27 | 28 | init() { 29 | for index in (1...16).reversed() { 30 | let name = "effect_audio_" + String(index) 31 | let url = Bundle.main.url(forResource: name, withExtension: "m4a") 32 | let itemModel = VLEPickerAudioItemModel.init(title: name, url: url!) 33 | itemModelArray.append(itemModel) 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Picker/Model/VLEPickerFetchAssetManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEPickerFetchAssetManager.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/9/14. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Photos 11 | 12 | class VLEPickerFetchAssetManager: NSObject { 13 | 14 | class func fetchAlbums() -> VLEPickerAlbumListModel { 15 | var model: VLEPickerAlbumListModel? 16 | let option = PHFetchOptions() 17 | let smartAlbums = PHAssetCollection.fetchAssetCollections(with: PHAssetCollectionType.smartAlbum, subtype: PHAssetCollectionSubtype.albumRegular, options: nil) 18 | smartAlbums.enumerateObjects { collection, _, stop in 19 | if collection.assetCollectionSubtype == .smartAlbumUserLibrary { 20 | let result = PHAsset.fetchAssets(in: collection, options: option) 21 | let albumModel = VLEPickerAlbumListModel.init(title: collection.localizedTitle ?? "所有照片", result: result, collection: collection, option: option, isCameraRoll: true) 22 | model = albumModel 23 | stop.pointee = true 24 | } 25 | } 26 | return model! 27 | } 28 | 29 | class func fetchPhoto(in result: PHFetchResult) -> [VLEPickerAssetModel] { 30 | var models: [VLEPickerAssetModel] = [] 31 | result.enumerateObjects { asset, _, _ in 32 | models.append(VLEPickerAssetModel(asset: asset)) 33 | } 34 | return models 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Picker/Model/VLEPickerStickerListModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEPickerStickerListModel.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/10/11. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class VLEPickerStickerListModel { 13 | var stickerArray: [UIImage] = [] 14 | init() { 15 | for index in (1...18) { 16 | let name = "effect_sticker_" + String(index) 17 | let image = UIImage.init(named: name) 18 | stickerArray.append(image!) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Picker/View/VLEPickerAlbumPhotoCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEPickerAlbumPhotoCell.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/9/13. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class VLEPickerAlbumPhotoCell: UICollectionViewCell{ 12 | lazy var thumbnailImage: UIImageView = { 13 | let imageView = UIImageView.init() 14 | imageView.backgroundColor = UIColor.clear 15 | return imageView 16 | }() 17 | 18 | lazy var selectedView: VLEPickerAlbumSelectedView = { 19 | let selectedView = VLEPickerAlbumSelectedView.init() 20 | return selectedView 21 | }() 22 | 23 | override init(frame: CGRect) { 24 | super.init(frame: frame) 25 | self.contentView.layer.cornerRadius = 10 26 | self.contentView.layer.masksToBounds = true 27 | self.contentView.addSubview(thumbnailImage) 28 | thumbnailImage.snp.makeConstraints { make in 29 | make.size.equalToSuperview() 30 | make.center.equalToSuperview() 31 | } 32 | 33 | self.contentView.addSubview(selectedView) 34 | selectedView.snp.makeConstraints { make in 35 | make.size.equalToSuperview() 36 | make.center.equalToSuperview() 37 | } 38 | } 39 | 40 | required init?(coder: NSCoder) { 41 | fatalError("init(coder:) has not been implemented") 42 | } 43 | 44 | func pushData(model: VLEPickerAssetModel) { 45 | var size: CGSize 46 | let maxSideLength = bounds.width * 1.2 47 | if model.whRatio > 1 { 48 | let weight = maxSideLength * model.whRatio 49 | size = CGSize(width: weight, height: maxSideLength) 50 | } else { 51 | let height = maxSideLength / model.whRatio 52 | size = CGSize(width: maxSideLength, height: height) 53 | } 54 | model.getAssetThumbnail(size: size) { [weak self] image in 55 | self?.thumbnailImage.image = image 56 | } 57 | self.refreshSelectState(model.isSelected) 58 | } 59 | 60 | func refreshSelectState(_ isSelected: Bool) { 61 | if isSelected == true { 62 | self.selectedView.isHidden = false 63 | } else { 64 | self.selectedView.isHidden = true 65 | } 66 | } 67 | } 68 | 69 | extension VLEPickerAlbumPhotoCell { 70 | static var identifier: String { 71 | return NSStringFromClass(self)+"CellId" 72 | } 73 | 74 | static func register(_ collectionView: UICollectionView) { 75 | collectionView.register(self, forCellWithReuseIdentifier: identifier) 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Picker/View/VLEPickerAudioCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEPickerAudioCell.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/10/11. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class VLEPickerAudioCell: UICollectionViewCell { 13 | 14 | lazy var titleLabel: UILabel = { 15 | let label = UILabel.init() 16 | label.textColor = UIColor.white 17 | label.font = UIFont.boldSystemFont(ofSize: 19) 18 | return label 19 | }() 20 | 21 | lazy var durationLabel: UILabel = { 22 | let label = UILabel.init() 23 | label.textColor = UIColor.white 24 | label.font = UIFont.systemFont(ofSize: 14) 25 | return label 26 | }() 27 | 28 | override init(frame: CGRect) { 29 | super.init(frame: frame) 30 | self.backgroundColor = UIColor.init(hexString: "#212123") 31 | self.addSubview(titleLabel) 32 | titleLabel.snp.makeConstraints { make in 33 | make.left.equalTo(self.snp.left).offset(30) 34 | make.centerY.equalToSuperview() 35 | } 36 | 37 | self.addSubview(durationLabel) 38 | durationLabel.snp.makeConstraints { make in 39 | make.left.equalTo(titleLabel) 40 | make.top.equalTo(titleLabel.snp.bottom).offset(5) 41 | } 42 | } 43 | 44 | required init?(coder: NSCoder) { 45 | fatalError("") 46 | } 47 | 48 | func pushModel(model: VLEPickerAudioItemModel) { 49 | titleLabel.text = model.title 50 | durationLabel.text = String(model.asset.duration.value) 51 | } 52 | } 53 | 54 | extension VLEPickerAudioCell { 55 | static var identifier: String { 56 | return NSStringFromClass(self)+"CellId" 57 | } 58 | 59 | static func register(_ collectionView: UICollectionView) { 60 | collectionView.register(self, forCellWithReuseIdentifier: identifier) 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Picker/View/VLEPickerBottomView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEPickerBottomView.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/9/11. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class VLEPickerBottomView: UIView { 12 | 13 | lazy var addButton: UIButton = { 14 | let button = UIButton.init() 15 | button.backgroundColor = UIColor.init(hexString: "#FF504E") 16 | let normalAttributedTitle = NSAttributedString(string: "添加", attributes: [NSAttributedString.Key.foregroundColor: UIColor.init(hexString: "#FFFFFF")!, NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 15)]) 17 | button.setAttributedTitle(normalAttributedTitle, for: UIControl.State.normal) 18 | button.layer.cornerRadius = 15 19 | button.layer.masksToBounds = true 20 | button.addTarget(self, action: #selector(addButtonClickAction), for: UIControl.Event.touchUpInside) 21 | return button 22 | }() 23 | 24 | lazy var preViewButton: UIButton = { 25 | let button = UIButton.init() 26 | button.backgroundColor = UIColor.init(hexString: "#212123") 27 | button.setTitle("预览", for: UIControl.State.normal) 28 | button.setTitleColor(UIColor.init(hexString: "#FFFFFF"), for: UIControl.State.normal) 29 | button.addTarget(self, action: #selector(preViewButtonClickAction), for: UIControl.Event.touchUpInside) 30 | return button 31 | }() 32 | 33 | override init(frame: CGRect) { 34 | super.init(frame: frame) 35 | self.backgroundColor = UIColor.init(hexString: "#212123") 36 | self.addSubview(preViewButton) 37 | preViewButton.snp.makeConstraints { make in 38 | make.width.equalTo(80) 39 | make.height.equalTo(30) 40 | make.left.equalTo(self.snp.left).offset(18) 41 | make.top.equalTo(self.snp.top).offset(10) 42 | } 43 | preViewButton.isHidden = true 44 | self.addSubview(addButton) 45 | addButton.snp.makeConstraints { make in 46 | make.width.equalTo(80) 47 | make.height.equalTo(30) 48 | make.right.equalTo(self.snp.right).offset(-18) 49 | make.top.equalTo(self.snp.top).offset(10) 50 | } 51 | } 52 | 53 | var clickAddButtonBlock: (() -> Void)? 54 | var clickPreViewButtonBlock: (() -> Void)? 55 | 56 | required init?(coder: NSCoder) { 57 | fatalError("init(coder:) has not been implemented") 58 | } 59 | 60 | @objc func addButtonClickAction() { 61 | self.clickAddButtonBlock?() 62 | } 63 | 64 | @objc func preViewButtonClickAction() { 65 | self.clickPreViewButtonBlock?() 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Picker/View/VLEPickerNavigatorView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEPickerNavView.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/9/11. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class VLEPickerNavigatorView: UIView { 12 | 13 | lazy var closeButton: UIButton = { 14 | let button = UIButton.init() 15 | button.setBackgroundImage(UIImage.init(named: "picker_nav_close"), for: UIControl.State.normal) 16 | button.addTarget(self, action: #selector(closeButtionClickAction), for: UIControl.Event.touchUpInside) 17 | return button 18 | }() 19 | 20 | lazy var titleLabel: UILabel = { 21 | let label = UILabel.init() 22 | label.text = "导入" 23 | label.textColor = UIColor.init(hexString: "#BABABC") 24 | return label 25 | }() 26 | 27 | lazy var setButton: UIButton = { 28 | let button = UIButton.init() 29 | button.setBackgroundImage(UIImage.init(named: "picker_nav_set"), for: UIControl.State.normal) 30 | button.addTarget(self, action: #selector(setButtonClickAction), for: UIControl.Event.touchUpInside) 31 | return button 32 | }() 33 | 34 | var clickCloseButtonBlock: (() -> Void)? 35 | var clickSetButtonBlock: (() -> Void)? 36 | 37 | override init(frame: CGRect) { 38 | super.init(frame: frame) 39 | self.backgroundColor = UIColor.init(hexString: "#212123") 40 | self.addSubview(closeButton) 41 | closeButton.snp.makeConstraints { make in 42 | make.size.equalTo(32) 43 | make.left.equalTo(self.snp.left).offset(12) 44 | make.top.equalTo(self.snp.top).offset(8) 45 | } 46 | self.addSubview(titleLabel) 47 | titleLabel.snp.makeConstraints { make in 48 | make.center.equalToSuperview() 49 | } 50 | self.addSubview(setButton) 51 | setButton.snp.makeConstraints { make in 52 | make.size.equalTo(32) 53 | make.right.equalTo(self.snp.right).offset(-12) 54 | make.top.equalTo(self.snp.top).offset(8) 55 | } 56 | } 57 | 58 | required init?(coder: NSCoder) { 59 | fatalError("init(coder:) has not been implemented") 60 | } 61 | 62 | @objc func closeButtionClickAction() { 63 | self.clickCloseButtonBlock?() 64 | } 65 | 66 | @objc func setButtonClickAction() { 67 | self.clickSetButtonBlock?() 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Picker/View/VLEPickerStickerCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEPickerStickerCell.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/10/11. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | 12 | class VLEPickerStickerCell: UICollectionViewCell { 13 | 14 | lazy var imageView: UIImageView = { 15 | let view = UIImageView.init() 16 | return view 17 | }() 18 | 19 | override init(frame: CGRect) { 20 | super.init(frame: frame) 21 | self.addSubview(imageView) 22 | imageView.snp.makeConstraints { make in 23 | make.edges.equalToSuperview() 24 | } 25 | } 26 | 27 | required init?(coder: NSCoder) { 28 | fatalError("") 29 | } 30 | 31 | func pushImage(image: UIImage) { 32 | imageView.image = image 33 | } 34 | } 35 | 36 | extension VLEPickerStickerCell { 37 | static var identifier: String { 38 | return NSStringFromClass(self)+"CellId" 39 | } 40 | 41 | static func register(_ collectionView: UICollectionView) { 42 | collectionView.register(self, forCellWithReuseIdentifier: identifier) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Playback/View/VLEPlaybackView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLEPlaybackView.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/10/10. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import AVFoundation 12 | 13 | class VLEPlaybackView: UIView { 14 | 15 | override init(frame: CGRect) { 16 | super.init(frame: frame) 17 | } 18 | 19 | required init?(coder: NSCoder) { 20 | fatalError("") 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Timeline/Model/VLETimeLineConfig.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLETimeLineConfigModel.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/10/10. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreMedia 11 | import UIKit 12 | 13 | class VLETimeLineConfig { 14 | 15 | static let framesPerSecond: Float = 30 16 | static let ptPerFrames: CGFloat = 1 17 | static let frontMargin: CGFloat = UIScreen.main.bounds.width/2 18 | static let backMargin: CGFloat = UIScreen.main.bounds.width/2 19 | static let framesPerSpace: Int = 30 20 | 21 | class func convertToSecond(value time: CMTime) -> Float { 22 | return Float(time.value)/Float(time.timescale) 23 | } 24 | 25 | class func convertToPt(value second: Float) -> CGFloat { 26 | return CGFloat.init(second) * CGFloat.init(VLETimeLineConfig.framesPerSecond) * VLETimeLineConfig.ptPerFrames 27 | } 28 | 29 | class func convertToPt(value time: CMTime) -> CGFloat { 30 | return convertToPt(value: VLETimeLineConfig.convertToSecond(value: time)) 31 | } 32 | 33 | class func convertToSecond(value pt: CGFloat) -> Float { 34 | return Float(pt/VLETimeLineConfig.ptPerFrames)/framesPerSecond 35 | } 36 | 37 | class func secondsToMinutesSeconds(sourceSeconds: Int) -> String { 38 | let minute = (sourceSeconds % 3600) / 60 39 | let second = (sourceSeconds % 3600) % 60 40 | let mStr = minute >= 10 ? String(minute) : "0"+String(minute) 41 | let sStr = second >= 10 ? String(second) : "0"+String(second) 42 | return "\(mStr):\(sStr)" 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Timeline/View/VLETimeLineDragSortMoveItemView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLETimeLineLongPressMoveItemView.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/9/21. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import UIKit 11 | import SnapKit 12 | 13 | class VLETimeLineDragSortMoveItemView: UIView{ 14 | 15 | let longPressDragDisable: Bool = false 16 | var index: Int = Int.max 17 | lazy var backImageView: UIImageView = { 18 | let imageView = UIImageView.init() 19 | return imageView 20 | }() 21 | 22 | override init(frame: CGRect) { 23 | super.init(frame: frame) 24 | 25 | self.addSubview(backImageView) 26 | backImageView.snp.makeConstraints { make in 27 | make.size.equalToSuperview() 28 | make.center.equalToSuperview() 29 | } 30 | 31 | let tapGesture = UITapGestureRecognizer.init() 32 | tapGesture.addTarget(self, action: #selector(tapGestureRecognizerAction(tapGesture:))) 33 | self.addGestureRecognizer(tapGesture) 34 | } 35 | 36 | required init?(coder: NSCoder) { 37 | fatalError("init(coder:) has not been implemented") 38 | } 39 | 40 | @objc func tapGestureRecognizerAction(tapGesture: UITapGestureRecognizer) { 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Timeline/View/VLETimeLineGeneralEffectTrackView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLETimeLineGeneralEffectTrackView.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/9/16. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | -------------------------------------------------------------------------------- /Example/VideoLab/AppDemo/Timeline/View/VLETimeLineTrackLongPressTipView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VLETimeLineTrackLongPressTipView.swift 3 | // VideoLab_Example 4 | // 5 | // Created by Kay on 2022/9/16. 6 | // Copyright © 2022 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | -------------------------------------------------------------------------------- /Example/VideoLab/FeaturesDemo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/3. 6 | // Copyright (c) 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UITableViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | 16 | } 17 | 18 | override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 19 | tableView.deselectRow(at: indexPath, animated: true) 20 | 21 | if indexPath.row == 0 { 22 | let controller = VLEDemoViewController.init() 23 | navigationController?.pushViewController(controller, animated: true) 24 | } else if indexPath.row == 1 { 25 | let controller = VLEMainViewController.init() 26 | navigationController?.pushViewController(controller, animated: true) 27 | } 28 | } 29 | } 30 | 31 | -------------------------------------------------------------------------------- /Example/VideoLab/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | NSPhotoLibraryAddUsageDescription 26 | 允许打开相册才能保存和编辑视频 27 | NSPhotoLibraryUsageDescription 28 | 允许打开相册才能保存和编辑视频 29 | UILaunchStoryboardName 30 | LaunchScreen 31 | UIMainStoryboardFile 32 | Main 33 | UIRequiredDeviceCapabilities 34 | 35 | armv7 36 | 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_1.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_1.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_10.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_10.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_11.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_11.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_12.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_12.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_13.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_13.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_14.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_14.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_15.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_15.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_16.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_16.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_2.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_2.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_3.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_3.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_4.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_4.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_5.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_5.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_6.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_6.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_7.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_7.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_8.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_8.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Audio/effect_audio_9.m4a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Audio/effect_audio_9.m4a -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Filters/LUT_M01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Filters/LUT_M01.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Filters/LUT_M02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Filters/LUT_M02.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Filters/LUT_M03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Filters/LUT_M03.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Filters/LUT_M05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Filters/LUT_M05.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Filters/LUT_M06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Filters/LUT_M06.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Filters/LUT_M07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Filters/LUT_M07.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Filters/LUT_M08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Filters/LUT_M08.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Filters/LUT_M09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Filters/LUT_M09.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Filters/LUT_M11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Filters/LUT_M11.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Filters/LUT_M12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Filters/LUT_M12.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ios-marketing", 45 | "size" : "1024x1024", 46 | "scale" : "1x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_audio.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_level1_audio.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_level1_audio@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_level1_audio@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_audio.imageset/effect_level1_audio.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_audio.imageset/effect_level1_audio.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_audio.imageset/effect_level1_audio@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_audio.imageset/effect_level1_audio@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_audio.imageset/effect_level1_audio@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_audio.imageset/effect_level1_audio@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_canvas.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_level1_canvas.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_level1_canvas@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_level1_canvas@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_canvas.imageset/effect_level1_canvas.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_canvas.imageset/effect_level1_canvas.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_canvas.imageset/effect_level1_canvas@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_canvas.imageset/effect_level1_canvas@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_canvas.imageset/effect_level1_canvas@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_canvas.imageset/effect_level1_canvas@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_filter.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_level1_filter.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_level1_filter@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_level1_filter@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_filter.imageset/effect_level1_filter.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_filter.imageset/effect_level1_filter.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_filter.imageset/effect_level1_filter@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_filter.imageset/effect_level1_filter@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_filter.imageset/effect_level1_filter@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_filter.imageset/effect_level1_filter@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_specialeffect.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_level1_specialeffects.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_level1_specialeffects@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_level1_specialeffects@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_specialeffect.imageset/effect_level1_specialeffects.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_specialeffect.imageset/effect_level1_specialeffects.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_specialeffect.imageset/effect_level1_specialeffects@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_specialeffect.imageset/effect_level1_specialeffects@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_specialeffect.imageset/effect_level1_specialeffects@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_specialeffect.imageset/effect_level1_specialeffects@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_sticker.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_level1_sticker.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_level1_sticker@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_level1_sticker@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_sticker.imageset/effect_level1_sticker.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_sticker.imageset/effect_level1_sticker.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_sticker.imageset/effect_level1_sticker@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_sticker.imageset/effect_level1_sticker@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_sticker.imageset/effect_level1_sticker@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_sticker.imageset/effect_level1_sticker@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_text.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_level1_text.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_level1_text@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_level1_text@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_text.imageset/effect_level1_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_text.imageset/effect_level1_text.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_text.imageset/effect_level1_text@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_text.imageset/effect_level1_text@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_level1_text.imageset/effect_level1_text@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_level1_text.imageset/effect_level1_text@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_1.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_1.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_1@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_1@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_1.imageset/effect_sticker_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_1.imageset/effect_sticker_1.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_1.imageset/effect_sticker_1@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_1.imageset/effect_sticker_1@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_1.imageset/effect_sticker_1@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_1.imageset/effect_sticker_1@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_10.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_10.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_10@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_10@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_10.imageset/effect_sticker_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_10.imageset/effect_sticker_10.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_10.imageset/effect_sticker_10@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_10.imageset/effect_sticker_10@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_10.imageset/effect_sticker_10@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_10.imageset/effect_sticker_10@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_11.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_11.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_11@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_11@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_11.imageset/effect_sticker_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_11.imageset/effect_sticker_11.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_11.imageset/effect_sticker_11@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_11.imageset/effect_sticker_11@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_11.imageset/effect_sticker_11@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_11.imageset/effect_sticker_11@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_12.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_12.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_12@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_12@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_12.imageset/effect_sticker_12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_12.imageset/effect_sticker_12.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_12.imageset/effect_sticker_12@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_12.imageset/effect_sticker_12@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_12.imageset/effect_sticker_12@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_12.imageset/effect_sticker_12@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_13.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_13.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_13@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_13@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_13.imageset/effect_sticker_13.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_13.imageset/effect_sticker_13.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_13.imageset/effect_sticker_13@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_13.imageset/effect_sticker_13@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_13.imageset/effect_sticker_13@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_13.imageset/effect_sticker_13@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_14.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_14.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_14@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_14@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_14.imageset/effect_sticker_14.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_14.imageset/effect_sticker_14.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_14.imageset/effect_sticker_14@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_14.imageset/effect_sticker_14@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_14.imageset/effect_sticker_14@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_14.imageset/effect_sticker_14@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_15.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_15.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_15@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_15@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_15.imageset/effect_sticker_15.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_15.imageset/effect_sticker_15.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_15.imageset/effect_sticker_15@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_15.imageset/effect_sticker_15@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_15.imageset/effect_sticker_15@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_15.imageset/effect_sticker_15@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_16.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_16.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_16@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_16@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_16.imageset/effect_sticker_16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_16.imageset/effect_sticker_16.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_16.imageset/effect_sticker_16@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_16.imageset/effect_sticker_16@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_16.imageset/effect_sticker_16@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_16.imageset/effect_sticker_16@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_17.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_17.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_17@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_17@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_17.imageset/effect_sticker_17.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_17.imageset/effect_sticker_17.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_17.imageset/effect_sticker_17@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_17.imageset/effect_sticker_17@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_17.imageset/effect_sticker_17@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_17.imageset/effect_sticker_17@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_18.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "effect_sticker_18@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "filename" : "effect_sticker_18@3x.png", 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "author" : "xcode", 20 | "version" : 1 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_18.imageset/effect_sticker_18@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_18.imageset/effect_sticker_18@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_18.imageset/effect_sticker_18@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_18.imageset/effect_sticker_18@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_2.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_2.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_2@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_2@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_2.imageset/effect_sticker_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_2.imageset/effect_sticker_2.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_2.imageset/effect_sticker_2@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_2.imageset/effect_sticker_2@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_2.imageset/effect_sticker_2@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_2.imageset/effect_sticker_2@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_3.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_3.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_3@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_3@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_3.imageset/effect_sticker_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_3.imageset/effect_sticker_3.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_3.imageset/effect_sticker_3@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_3.imageset/effect_sticker_3@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_3.imageset/effect_sticker_3@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_3.imageset/effect_sticker_3@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_4.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_4.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_4@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_4@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_4.imageset/effect_sticker_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_4.imageset/effect_sticker_4.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_4.imageset/effect_sticker_4@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_4.imageset/effect_sticker_4@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_4.imageset/effect_sticker_4@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_4.imageset/effect_sticker_4@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_5.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_5.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_5@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_5@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_5.imageset/effect_sticker_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_5.imageset/effect_sticker_5.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_5.imageset/effect_sticker_5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_5.imageset/effect_sticker_5@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_5.imageset/effect_sticker_5@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_5.imageset/effect_sticker_5@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_6.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_6.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_6@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_6@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_6.imageset/effect_sticker_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_6.imageset/effect_sticker_6.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_6.imageset/effect_sticker_6@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_6.imageset/effect_sticker_6@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_6.imageset/effect_sticker_6@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_6.imageset/effect_sticker_6@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_7.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_7.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_7@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_7@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_7.imageset/effect_sticker_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_7.imageset/effect_sticker_7.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_7.imageset/effect_sticker_7@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_7.imageset/effect_sticker_7@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_7.imageset/effect_sticker_7@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_7.imageset/effect_sticker_7@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_8.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_8.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_8@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_8@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_8.imageset/effect_sticker_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_8.imageset/effect_sticker_8.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_8.imageset/effect_sticker_8@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_8.imageset/effect_sticker_8@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_8.imageset/effect_sticker_8@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_8.imageset/effect_sticker_8@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_9.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "effect_sticker_9.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "effect_sticker_9@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "effect_sticker_9@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_9.imageset/effect_sticker_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_9.imageset/effect_sticker_9.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_9.imageset/effect_sticker_9@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_9.imageset/effect_sticker_9@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/effect_sticker_9.imageset/effect_sticker_9@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/effect_sticker_9.imageset/effect_sticker_9@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_pengyouquan.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "export_share_pengyouquan.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "export_share_pengyouquan@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "export_share_pengyouquan@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_pengyouquan.imageset/export_share_pengyouquan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_pengyouquan.imageset/export_share_pengyouquan.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_pengyouquan.imageset/export_share_pengyouquan@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_pengyouquan.imageset/export_share_pengyouquan@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_pengyouquan.imageset/export_share_pengyouquan@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_pengyouquan.imageset/export_share_pengyouquan@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_qq.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "export_share_qq.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "export_share_qq@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "export_share_qq@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_qq.imageset/export_share_qq.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_qq.imageset/export_share_qq.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_qq.imageset/export_share_qq@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_qq.imageset/export_share_qq@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_qq.imageset/export_share_qq@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_qq.imageset/export_share_qq@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_qqzone.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "export_share_qqzone.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "export_share_qqzone@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "export_share_qqzone@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_qqzone.imageset/export_share_qqzone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_qqzone.imageset/export_share_qqzone.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_qqzone.imageset/export_share_qqzone@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_qqzone.imageset/export_share_qqzone@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_qqzone.imageset/export_share_qqzone@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_qqzone.imageset/export_share_qqzone@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_wechat.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "export_share_wechat.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "export_share_wechat@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "export_share_wechat@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_wechat.imageset/export_share_wechat.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_wechat.imageset/export_share_wechat.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_wechat.imageset/export_share_wechat@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_wechat.imageset/export_share_wechat@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_wechat.imageset/export_share_wechat@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_wechat.imageset/export_share_wechat@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_weibo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "export_share_weibo.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "export_share_weibo@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "export_share_weibo@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_weibo.imageset/export_share_weibo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_weibo.imageset/export_share_weibo.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_weibo.imageset/export_share_weibo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_weibo.imageset/export_share_weibo@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/export_share_weibo.imageset/export_share_weibo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/export_share_weibo.imageset/export_share_weibo@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_close_button.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "nav_close_button.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "nav_close_button@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "nav_close_button@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_close_button.imageset/nav_close_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_close_button.imageset/nav_close_button.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_close_button.imageset/nav_close_button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_close_button.imageset/nav_close_button@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_close_button.imageset/nav_close_button@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_close_button.imageset/nav_close_button@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_export_button.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "nav_export_button.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "nav_export_button@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "nav_export_button@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_export_button.imageset/nav_export_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_export_button.imageset/nav_export_button.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_export_button.imageset/nav_export_button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_export_button.imageset/nav_export_button@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_export_button.imageset/nav_export_button@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_export_button.imageset/nav_export_button@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_help_button.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "nav_help_button.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "nav_help_button@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "nav_help_button@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_help_button.imageset/nav_help_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_help_button.imageset/nav_help_button.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_help_button.imageset/nav_help_button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_help_button.imageset/nav_help_button@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_help_button.imageset/nav_help_button@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_help_button.imageset/nav_help_button@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_projectlist_button.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "nav_projectlist_button.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "nav_projectlist_button@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "nav_projectlist_button@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_projectlist_button.imageset/nav_projectlist_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_projectlist_button.imageset/nav_projectlist_button.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_projectlist_button.imageset/nav_projectlist_button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_projectlist_button.imageset/nav_projectlist_button@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_projectlist_button.imageset/nav_projectlist_button@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_projectlist_button.imageset/nav_projectlist_button@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_set_button.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "nav_set_button.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "nav_set_button@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "nav_set_button@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_set_button.imageset/nav_set_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_set_button.imageset/nav_set_button.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_set_button.imageset/nav_set_button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_set_button.imageset/nav_set_button@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/nav_set_button.imageset/nav_set_button@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/nav_set_button.imageset/nav_set_button@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/picker_album_selecticon.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "export_album_selecticon.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "export_album_selecticon@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "export_album_selecticon@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/picker_album_selecticon.imageset/export_album_selecticon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/picker_album_selecticon.imageset/export_album_selecticon.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/picker_album_selecticon.imageset/export_album_selecticon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/picker_album_selecticon.imageset/export_album_selecticon@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/picker_album_selecticon.imageset/export_album_selecticon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/picker_album_selecticon.imageset/export_album_selecticon@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/picker_nav_close.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "export_nav_close.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "export_nav_close@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "export_nav_close@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/picker_nav_close.imageset/export_nav_close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/picker_nav_close.imageset/export_nav_close.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/picker_nav_close.imageset/export_nav_close@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/picker_nav_close.imageset/export_nav_close@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/picker_nav_close.imageset/export_nav_close@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/picker_nav_close.imageset/export_nav_close@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/picker_nav_set.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "export_nav_set.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "export_nav_set@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "export_nav_set@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/picker_nav_set.imageset/export_nav_set.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/picker_nav_set.imageset/export_nav_set.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/picker_nav_set.imageset/export_nav_set@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/picker_nav_set.imageset/export_nav_set@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/picker_nav_set.imageset/export_nav_set@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/picker_nav_set.imageset/export_nav_set@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/playback_fullscreen_button.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "playback_fullscreen_button.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "playback_fullscreen_button@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "playback_fullscreen_button@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/playback_fullscreen_button.imageset/playback_fullscreen_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/playback_fullscreen_button.imageset/playback_fullscreen_button.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/playback_fullscreen_button.imageset/playback_fullscreen_button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/playback_fullscreen_button.imageset/playback_fullscreen_button@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/playback_fullscreen_button.imageset/playback_fullscreen_button@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/playback_fullscreen_button.imageset/playback_fullscreen_button@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/playback_pause_button.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "scale" : "1x" 6 | }, 7 | { 8 | "filename" : "playback_pause_button@2x.png", 9 | "idiom" : "universal", 10 | "scale" : "2x" 11 | }, 12 | { 13 | "filename" : "playback_pause_button@3x.png", 14 | "idiom" : "universal", 15 | "scale" : "3x" 16 | } 17 | ], 18 | "info" : { 19 | "author" : "xcode", 20 | "version" : 1 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/playback_pause_button.imageset/playback_pause_button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/playback_pause_button.imageset/playback_pause_button@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/playback_pause_button.imageset/playback_pause_button@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/playback_pause_button.imageset/playback_pause_button@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/playback_play_button.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "playback_play_button.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "playback_play_button@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "playback_play_button@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/playback_play_button.imageset/playback_play_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/playback_play_button.imageset/playback_play_button.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/playback_play_button.imageset/playback_play_button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/playback_play_button.imageset/playback_play_button@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/playback_play_button.imageset/playback_play_button@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/playback_play_button.imageset/playback_play_button@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_addresource_button.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "timeline_addresource_button.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "timeline_addresource_button@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "timeline_addresource_button@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_addresource_button.imageset/timeline_addresource_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_addresource_button.imageset/timeline_addresource_button.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_addresource_button.imageset/timeline_addresource_button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_addresource_button.imageset/timeline_addresource_button@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_addresource_button.imageset/timeline_addresource_button@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_addresource_button.imageset/timeline_addresource_button@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_clip_button.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "timeline_cat_button.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "timeline_cat_button@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "timeline_cat_button@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_clip_button.imageset/timeline_cat_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_clip_button.imageset/timeline_cat_button.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_clip_button.imageset/timeline_cat_button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_clip_button.imageset/timeline_cat_button@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_clip_button.imageset/timeline_cat_button@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_clip_button.imageset/timeline_cat_button@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_dragsort_delete.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "timeline_dragsort_delete.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "timeline_dragsort_delete@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "timeline_dragsort_delete@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_dragsort_delete.imageset/timeline_dragsort_delete.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_dragsort_delete.imageset/timeline_dragsort_delete.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_dragsort_delete.imageset/timeline_dragsort_delete@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_dragsort_delete.imageset/timeline_dragsort_delete@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_dragsort_delete.imageset/timeline_dragsort_delete@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_dragsort_delete.imageset/timeline_dragsort_delete@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_redo_button.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "timeline_redo_button.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "timeline_redo_button@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "timeline_redo_button@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_redo_button.imageset/timeline_redo_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_redo_button.imageset/timeline_redo_button.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_redo_button.imageset/timeline_redo_button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_redo_button.imageset/timeline_redo_button@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_redo_button.imageset/timeline_redo_button@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_redo_button.imageset/timeline_redo_button@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_undo_button.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "timeline_undo_button.png", 5 | "idiom" : "universal", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "filename" : "timeline_undo_button@2x.png", 10 | "idiom" : "universal", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "filename" : "timeline_undo_button@3x.png", 15 | "idiom" : "universal", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "author" : "xcode", 21 | "version" : 1 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_undo_button.imageset/timeline_undo_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_undo_button.imageset/timeline_undo_button.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_undo_button.imageset/timeline_undo_button@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_undo_button.imageset/timeline_undo_button@2x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Images.xcassets/timeline_undo_button.imageset/timeline_undo_button@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Images.xcassets/timeline_undo_button.imageset/timeline_undo_button@3x.png -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Video/video1.MOV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Video/video1.MOV -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Video/video2.MOV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Video/video2.MOV -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Video/video3.MOV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Video/video3.MOV -------------------------------------------------------------------------------- /Example/VideoLab/Resource/Video/video4.MOV: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/Video/video4.MOV -------------------------------------------------------------------------------- /Example/VideoLab/Resource/image1.JPG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/image1.JPG -------------------------------------------------------------------------------- /Example/VideoLab/Resource/image2.HEIC: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/image2.HEIC -------------------------------------------------------------------------------- /Example/VideoLab/Resource/image3.HEIC: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/Example/VideoLab/Resource/image3.HEIC -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Chocolate 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /VideoLab.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'VideoLab' 3 | s.version = '0.0.1' 4 | s.summary = 'High-performance and flexible video editing and effects framework, based on AVFoundation and Metal.' 5 | s.description = <<-DESC 6 | High-performance and flexible video editing and effects framework, based on AVFoundation and Metal. 7 | * High-performance real-time video editing and exporting. 8 | * Highly free to combination of video, picture, audio. 9 | * Support audio pitch setting and volume adjustment. 10 | * Support for CALayer vector animations. So support complex text animations. 11 | * Support keyframe animation. 12 | * Support for After Effect-like pre-compose. 13 | * Support transitions. 14 | * Support custom effects. Such as lut filter, zoom blur, etc. 15 | DESC 16 | 17 | s.homepage = 'https://github.com/ruanjx/VideoLab' 18 | s.license = { :type => 'MIT', :file => 'LICENSE' } 19 | s.author = { 'bear' => 'ruanjingxiong@gmail.com' } 20 | s.source = { :git => 'https://github.com/ruanjx/VideoLab.git', :tag => s.version.to_s } 21 | 22 | s.ios.deployment_target = '11.0' 23 | s.swift_version = "5" 24 | 25 | s.source_files = 'VideoLab/**/*.{swift,h,m,metal}' 26 | s.resources = 'VideoLab/VideoLab.bundle' 27 | 28 | end 29 | -------------------------------------------------------------------------------- /VideoLab/AudioConfiguration.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AudioConfiguration.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/9. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import AVFoundation 10 | 11 | public struct AudioConfiguration { 12 | public var pitchAlgorithm: AVAudioTimePitchAlgorithm = .varispeed 13 | public var volumeRamps: [VolumeRamp] = [] 14 | 15 | public init(pitchAlgorithm: AVAudioTimePitchAlgorithm = .varispeed, volumeRamps: [VolumeRamp] = []) { 16 | self.pitchAlgorithm = pitchAlgorithm 17 | self.volumeRamps = volumeRamps 18 | } 19 | } 20 | 21 | public struct VolumeRamp { 22 | public var startVolume: Float 23 | public var endVolume: Float 24 | public var timeRange: CMTimeRange 25 | public var timingFunction: TimingFunction = .linear 26 | 27 | public init(startVolume: Float, endVolume: Float, timeRange: CMTimeRange, timingFunction: TimingFunction = .linear) { 28 | self.startVolume = startVolume 29 | self.endVolume = endVolume 30 | self.timeRange = timeRange 31 | self.timingFunction = timingFunction 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /VideoLab/Render/Base/Color.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Color.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/20. 6 | // Copyright (c) 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Metal 11 | 12 | public struct Color { 13 | public let red:Float 14 | public let green:Float 15 | public let blue:Float 16 | public let alpha:Float 17 | 18 | public init(red:Float, green:Float, blue:Float, alpha:Float = 1.0) { 19 | self.red = red 20 | self.green = green 21 | self.blue = blue 22 | self.alpha = alpha 23 | } 24 | 25 | public static let black = Color(red:0.0, green:0.0, blue:0.0, alpha:1.0) 26 | public static let white = Color(red:1.0, green:1.0, blue:1.0, alpha:1.0) 27 | public static let red = Color(red:1.0, green:0.0, blue:0.0, alpha:1.0) 28 | public static let green = Color(red:0.0, green:1.0, blue:0.0, alpha:1.0) 29 | public static let blue = Color(red:0.0, green:0.0, blue:1.0, alpha:1.0) 30 | public static let transparent = Color(red:0.0, green:0.0, blue:0.0, alpha:0.0) 31 | 32 | public static var clearColor = Color.black 33 | public static var mtlClearColor: MTLClearColor { 34 | get { 35 | return MTLClearColorMake(Double(clearColor.red), Double(clearColor.green), Double(clearColor.blue), Double(clearColor.alpha)) 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /VideoLab/Render/Base/MetalRenderingDevice.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MetalRenderingDevice.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/7. 6 | // Copyright (c) 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Metal 11 | 12 | public let sharedMetalRenderingDevice = MetalRenderingDevice() 13 | 14 | public class MetalRenderingDevice { 15 | public let device: MTLDevice 16 | public let commandQueue: MTLCommandQueue 17 | public let shaderLibrary: MTLLibrary 18 | public lazy var textureCache: TextureCache = { 19 | TextureCache() 20 | }() 21 | 22 | init() { 23 | guard let device = MTLCreateSystemDefaultDevice() else { 24 | fatalError("Could not create Metal Device") 25 | } 26 | self.device = device 27 | 28 | guard let queue = self.device.makeCommandQueue() else { 29 | fatalError("Could not create command queue") 30 | } 31 | self.commandQueue = queue 32 | 33 | do { 34 | let frameworkBundle = Bundle(for: MetalRenderingDevice.self) 35 | let metalLibraryPath = frameworkBundle.path(forResource: "default", ofType: "metallib")! 36 | 37 | self.shaderLibrary = try device.makeLibrary(filepath:metalLibraryPath) 38 | } catch { 39 | fatalError("Could not load library") 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /VideoLab/Render/Base/Position.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Position.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/20. 6 | // Copyright (c) 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public struct Position { 12 | public let x:Float 13 | public let y:Float 14 | public let z:Float? 15 | 16 | public init (_ x:Float, _ y:Float, _ z:Float? = nil) { 17 | self.x = x 18 | self.y = y 19 | self.z = z 20 | } 21 | 22 | public static let center = Position(0.5, 0.5) 23 | public static let zero = Position(0.0, 0.0) 24 | } 25 | 26 | 27 | public struct Position2D { 28 | public let x:Float 29 | public let y:Float 30 | 31 | public init (_ x:Float, _ y:Float) { 32 | self.x = x 33 | self.y = y 34 | } 35 | 36 | public static let center = Position2D(0.5, 0.5) 37 | public static let zero = Position2D(0.0, 0.0) 38 | } 39 | -------------------------------------------------------------------------------- /VideoLab/Render/Base/Size.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Size.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/20. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public struct Size { 12 | public let width:Float 13 | public let height:Float 14 | 15 | public init(width:Float, height:Float) { 16 | self.width = width 17 | self.height = height 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /VideoLab/Render/Base/TextureCache.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextureCache.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/12. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import Metal 10 | 11 | public class TextureCache { 12 | var textureCache = [String:[Texture]]() 13 | 14 | public func requestTexture(pixelFormat: MTLPixelFormat = .bgra8Unorm, width: Int, height: Int) -> Texture? { 15 | let hash = hashForTexture(pixelFormat: pixelFormat, width: width, height: height) 16 | let texture: Texture? 17 | 18 | if let textureCount = textureCache[hash]?.count, textureCount > 0 { 19 | texture = textureCache[hash]!.removeLast() 20 | } else { 21 | texture = Texture.makeTexture(pixelFormat: pixelFormat, width: width, height: height) 22 | } 23 | 24 | return texture 25 | } 26 | 27 | public func purgeAllTextures() { 28 | textureCache.removeAll() 29 | } 30 | 31 | public func returnToCache(_ texture: Texture) { 32 | let hash = hashForTexture(pixelFormat: texture.texture.pixelFormat, width: texture.width, height: texture.height) 33 | if textureCache[hash] != nil { 34 | textureCache[hash]?.append(texture) 35 | } else { 36 | textureCache[hash] = [texture] 37 | } 38 | } 39 | 40 | private func hashForTexture(pixelFormat: MTLPixelFormat = .bgra8Unorm, width: Int, height: Int) -> String { 41 | return "\(width)x\(height)-\(pixelFormat)" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/BlendModeConstants.h: -------------------------------------------------------------------------------- 1 | // 2 | // BlendModeConstants.h 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/5. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | #ifndef BlendModeConstants_h 10 | #define BlendModeConstants_h 11 | 12 | typedef enum 13 | { 14 | BlendModeNormal = 0, 15 | BlendModeDarken, 16 | BlendModeMultiply, 17 | } BlendMode; 18 | 19 | #endif /* BlendModeConstants_h */ 20 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/BlendOperation.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BlendOperation.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/5. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import simd 11 | 12 | public class BlendOperation: BasicOperation { 13 | public var modelView: float4x4 = float4x4.identity() { 14 | didSet { 15 | uniformSettings["modelView"] = modelView 16 | } 17 | } 18 | 19 | public var projection: float4x4 = float4x4.identity() { 20 | didSet { 21 | uniformSettings["projection"] = projection 22 | } 23 | } 24 | 25 | public var blendMode: BlendMode = BlendModeNormal { 26 | didSet { 27 | uniformSettings["blendMode"] = blendMode 28 | } 29 | } 30 | 31 | public var blendOpacity: Float = 1.0 { 32 | didSet { 33 | uniformSettings["blendOpacity"] = blendOpacity 34 | } 35 | } 36 | 37 | public init() { 38 | super.init(vertexFunctionName: "blendOperationVertex", fragmentFunctionName: "blendOperationFragment", numberOfInputs: 1) 39 | 40 | ({ blendMode = BlendModeNormal })() 41 | ({ blendOpacity = 1.0 })() 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/BrightnessAdjustment.metal: -------------------------------------------------------------------------------- 1 | // 2 | // BrightnessAdjustment.metal 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/21. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | #include 10 | using namespace metal; 11 | #include "OperationShaderTypes.h" 12 | 13 | fragment half4 brightnessFragment(PassthroughVertexIO fragmentInput [[stage_in]], 14 | half4 sourceColor [[color(0)]], 15 | constant float& brightness [[ buffer(1) ]]) 16 | { 17 | return half4(sourceColor.rgb + brightness, sourceColor.a); 18 | } 19 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/BrightnessAdjustment.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BrightnessAdjustment.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/21. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | public class BrightnessAdjustment: BasicOperation { 10 | public var brightness:Float = 0.0 { 11 | didSet { 12 | uniformSettings["brightness"] = brightness 13 | } 14 | } 15 | 16 | public init() { 17 | super.init(fragmentFunctionName: "brightnessFragment", numberOfInputs: 0) 18 | 19 | ({ brightness = 0.0 })() 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/ChromaKeying.metal: -------------------------------------------------------------------------------- 1 | // 2 | // ChromaKeying.metal 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/13. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | #include 10 | using namespace metal; 11 | #include "OperationShaderTypes.h" 12 | 13 | fragment half4 ChromaKeyFragment(PassthroughVertexIO fragmentInput [[stage_in]], 14 | half4 sourceColor [[color(0)]], 15 | constant float& thresholdSensitivity [[ buffer(1) ]], 16 | constant float& smoothing [[ buffer(2) ]], 17 | constant float4& colorToReplace [[ buffer(3) ]]) 18 | { 19 | 20 | half maskY = 0.2989h * colorToReplace.r + 0.5866h * colorToReplace.g + 0.1145h * colorToReplace.b; 21 | half maskCr = 0.7132h * (colorToReplace.r - maskY); 22 | half maskCb = 0.5647h * (colorToReplace.b - maskY); 23 | 24 | half Y = 0.2989h * sourceColor.r + 0.5866h * sourceColor.g + 0.1145h * sourceColor.b; 25 | half Cr = 0.7132h * (sourceColor.r - Y); 26 | half Cb = 0.5647h * (sourceColor.b - Y); 27 | 28 | half blendValue = smoothstep(half(thresholdSensitivity), 29 | half(thresholdSensitivity + smoothing), 30 | distance(half2(Cr, Cb), half2(maskCr, maskCb))); 31 | 32 | return half4(sourceColor.rgb * blendValue, sourceColor.a * blendValue); 33 | } 34 | 35 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/ChromaKeying.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChromaKeying.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/13. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | public class ChromaKeying: BasicOperation { 10 | public var thresholdSensitivity: Float = 0.4 { 11 | didSet { 12 | uniformSettings["thresholdSensitivity"] = thresholdSensitivity 13 | } 14 | } 15 | 16 | public var smoothing: Float = 0.1 { 17 | didSet { 18 | uniformSettings["smoothing"] = smoothing 19 | } 20 | } 21 | 22 | public var colorToReplace: Color = Color.green { 23 | didSet { 24 | uniformSettings["colorToReplace"] = colorToReplace 25 | } 26 | } 27 | 28 | public init() { 29 | super.init(fragmentFunctionName: "ChromaKeyFragment", numberOfInputs: 0) 30 | 31 | ({ thresholdSensitivity = 0.4 })() 32 | ({ smoothing = 0.1 })() 33 | ({ colorToReplace = Color.green })() 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/LookupFilter.metal: -------------------------------------------------------------------------------- 1 | // 2 | // LookupFilter.metal 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/10. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | #include 10 | using namespace metal; 11 | #include "OperationShaderTypes.h" 12 | 13 | fragment half4 lookupFragment(SingleInputVertexIO fragmentInput [[stage_in]], 14 | texture2d inputTexture [[texture(0)]], 15 | half4 sourceColor [[color(0)]], 16 | constant float& intensity [[ buffer(1) ]]) 17 | { 18 | half4 base = sourceColor; 19 | 20 | half blueColor = base.b * 63.0h; 21 | 22 | half2 quad1; 23 | quad1.y = floor(floor(blueColor) / 8.0h); 24 | quad1.x = floor(blueColor) - (quad1.y * 8.0h); 25 | 26 | half2 quad2; 27 | quad2.y = floor(ceil(blueColor) / 8.0h); 28 | quad2.x = ceil(blueColor) - (quad2.y * 8.0h); 29 | 30 | float2 texPos1; 31 | texPos1.x = (quad1.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * base.r); 32 | texPos1.y = (quad1.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * base.g); 33 | 34 | float2 texPos2; 35 | texPos2.x = (quad2.x * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * base.r); 36 | texPos2.y = (quad2.y * 0.125) + 0.5/512.0 + ((0.125 - 1.0/512.0) * base.g); 37 | 38 | constexpr sampler quadSampler3; 39 | half4 newColor1 = inputTexture.sample(quadSampler3, texPos1); 40 | constexpr sampler quadSampler4; 41 | half4 newColor2 = inputTexture.sample(quadSampler4, texPos2); 42 | 43 | half4 newColor = mix(newColor1, newColor2, fract(blueColor)); 44 | return half4(mix(base, half4(newColor.rgb, base.w), half(intensity))); 45 | } 46 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/LookupFilter.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LookupFilter.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/10. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public class LookupFilter: BasicOperation { 12 | public var intensity: Float = 1.0 { 13 | didSet { 14 | uniformSettings["intensity"] = intensity 15 | } 16 | } 17 | 18 | public init() { 19 | super.init(fragmentFunctionName: "lookupFragment", numberOfInputs: 1) 20 | 21 | ({ intensity = 1.0 })() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/OperationConstants.h: -------------------------------------------------------------------------------- 1 | // 2 | // OperationConstants.h 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/5. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | #ifndef OperationConstants_h 10 | #define OperationConstants_h 11 | 12 | #import "BlendModeConstants.h" 13 | 14 | #endif /* OperationConstants_h */ 15 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/OperationShaderTypes.h: -------------------------------------------------------------------------------- 1 | // 2 | // OperationShaderTypes.h 3 | // Pods 4 | // 5 | // Created by Bear on 2020/8/21. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | #ifndef OperationShaderTypes_h 10 | #define OperationShaderTypes_h 11 | 12 | // It may be a bug in Xcode, maybe it will be fixed later 13 | // If you do not add this line, #include will have an error 14 | // https://github.com/CocoaPods/CocoaPods/issues/7073 15 | #if __METAL_MACOS__ || __METAL_IOS__ 16 | 17 | #include 18 | using namespace metal; 19 | 20 | struct PassthroughVertexIO 21 | { 22 | float4 position [[position]]; 23 | }; 24 | 25 | struct SingleInputVertexIO 26 | { 27 | float4 position [[position]]; 28 | float2 textureCoordinate [[user(texturecoord)]]; 29 | }; 30 | 31 | struct TwoInputVertexIO 32 | { 33 | float4 position [[position]]; 34 | float2 textureCoordinate [[user(texturecoord)]]; 35 | float2 textureCoordinate2 [[user(texturecoord2)]]; 36 | }; 37 | 38 | #endif /* __METAL_MACOS__ || __METAL_IOS__ */ 39 | 40 | #endif /* OperationShaderTypes_h */ 41 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/Passthrough.metal: -------------------------------------------------------------------------------- 1 | #include 2 | #include "OperationShaderTypes.h" 3 | 4 | using namespace metal; 5 | 6 | vertex PassthroughVertexIO passthroughVertex(const device packed_float2 *position [[buffer(0)]], 7 | uint vid [[vertex_id]]) 8 | { 9 | PassthroughVertexIO outputVertices; 10 | 11 | outputVertices.position = float4(position[vid], 0, 1.0); 12 | 13 | return outputVertices; 14 | } 15 | 16 | vertex SingleInputVertexIO oneInputVertex(const device packed_float2 *position [[buffer(0)]], 17 | const device packed_float2 *texturecoord [[buffer(1)]], 18 | uint vid [[vertex_id]]) 19 | { 20 | SingleInputVertexIO outputVertices; 21 | 22 | outputVertices.position = float4(position[vid], 0, 1.0); 23 | outputVertices.textureCoordinate = texturecoord[vid]; 24 | 25 | return outputVertices; 26 | } 27 | 28 | fragment half4 oneInputPassthroughFragment(SingleInputVertexIO fragmentInput [[stage_in]], 29 | texture2d inputTexture [[texture(0)]]) 30 | { 31 | constexpr sampler quadSampler; 32 | half4 color = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate); 33 | 34 | return color; 35 | } 36 | 37 | vertex TwoInputVertexIO twoInputVertex(const device packed_float2 *position [[buffer(0)]], 38 | const device packed_float2 *texturecoord [[buffer(1)]], 39 | const device packed_float2 *texturecoord2 [[buffer(2)]], 40 | uint vid [[vertex_id]]) 41 | { 42 | TwoInputVertexIO outputVertices; 43 | 44 | outputVertices.position = float4(position[vid], 0, 1.0); 45 | outputVertices.textureCoordinate = texturecoord[vid]; 46 | outputVertices.textureCoordinate2 = texturecoord2[vid]; 47 | 48 | return outputVertices; 49 | } 50 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/Passthrough.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Passthrough.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/12. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public class Passthrough: BasicOperation { 12 | public init () { 13 | super.init(fragmentFunctionName: "oneInputPassthroughFragment", numberOfInputs: 1) 14 | enableOutputTextureRead = false 15 | } 16 | } 17 | 18 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/YUVToRGBConversion.metal: -------------------------------------------------------------------------------- 1 | #include 2 | #include "OperationShaderTypes.h" 3 | using namespace metal; 4 | 5 | vertex TwoInputVertexIO yuvConversionVertex(const device packed_float2 *position [[buffer(0)]], 6 | const device packed_float2 *texturecoord [[buffer(1)]], 7 | const device packed_float2 *texturecoord2 [[buffer(2)]], 8 | constant float4x4& orientation [[ buffer(3) ]], 9 | uint vid [[vertex_id]]) 10 | { 11 | TwoInputVertexIO outputVertices; 12 | 13 | outputVertices.position = float4(position[vid], 0, 1.0); 14 | outputVertices.textureCoordinate = (orientation * float4(texturecoord[vid], 0, 1.0)).xy; 15 | outputVertices.textureCoordinate2 = (orientation * float4(texturecoord2[vid], 0, 1.0)).xy; 16 | 17 | return outputVertices; 18 | } 19 | 20 | fragment half4 yuvConversionFragment(TwoInputVertexIO fragmentInput [[stage_in]], 21 | texture2d inputTexture [[texture(0)]], 22 | texture2d inputTexture2 [[texture(1)]], 23 | constant float4x4& colorConversionMatrix [[ buffer(1) ]]) 24 | { 25 | constexpr sampler quadSampler; 26 | half y = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate).r; 27 | half2 uv = inputTexture2.sample(quadSampler, fragmentInput.textureCoordinate).rg; 28 | half4 ycc = half4(y, uv, 1.0); 29 | half4 color = half4((half4x4(colorConversionMatrix) * ycc).rgb, 1.0); 30 | 31 | return clamp(color, 0.0, 1.0); 32 | } 33 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/YUVToRGBConversion.swift: -------------------------------------------------------------------------------- 1 | // 2 | // YUVToRGBConversion.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/23. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import simd 10 | 11 | public class YUVToRGBConversion: BasicOperation { 12 | // BT.601, which is the standard for SDTV. 13 | public static let colorConversionMatrixVideoRange = float4x4( 14 | [1.164384, 1.164384, 1.164384, 0.000000], 15 | [0.000000, -0.213249, 2.111719, 0.000000], 16 | [1.792741, -0.532909, 0.000000, 0.000000], 17 | [-0.973015, 0.301512, -1.133142, 1.000000] 18 | ) 19 | 20 | public static let colorConversionMatrixFullRange = float4x4( 21 | [1.000000, 1.000000, 1.000000, 0.000000], 22 | [0.000000, -0.187324, 1.855000, 0.000000], 23 | [1.574800, -0.468124, 0.000000, 0.000000], 24 | [-0.790550, 0.329035, -0.931210, 1.000000] 25 | ) 26 | 27 | public var colorConversionMatrix: float4x4 = YUVToRGBConversion.colorConversionMatrixVideoRange { 28 | didSet { 29 | uniformSettings["colorConversionMatrix"] = colorConversionMatrix 30 | } 31 | } 32 | 33 | public var orientation: float4x4 = float4x4.identity() { 34 | didSet { 35 | uniformSettings["orientation"] = orientation 36 | } 37 | } 38 | 39 | public init () { 40 | super.init(vertexFunctionName: "yuvConversionVertex", fragmentFunctionName: "yuvConversionFragment", numberOfInputs: 2) 41 | enableOutputTextureRead = false 42 | 43 | ({ colorConversionMatrix = YUVToRGBConversion.colorConversionMatrixVideoRange })() 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/ZoomBlur.metal: -------------------------------------------------------------------------------- 1 | // 2 | // ZoomBlur.metal 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/31. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | #include 10 | using namespace metal; 11 | #include "OperationShaderTypes.h" 12 | 13 | fragment half4 zoomBlurFragment(SingleInputVertexIO fragmentInput [[stage_in]], 14 | texture2d inputTexture [[texture(0)]], 15 | constant float& size [[ buffer(1) ]], 16 | constant float2& center [[ buffer(2) ]]) 17 | { 18 | float2 samplingOffset = 1.0/100.0 * (center - fragmentInput.textureCoordinate) * size; 19 | 20 | constexpr sampler quadSampler; 21 | half4 color = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate) * 0.18; 22 | 23 | color += inputTexture.sample(quadSampler, fragmentInput.textureCoordinate + samplingOffset) * 0.15h; 24 | color += inputTexture.sample(quadSampler, fragmentInput.textureCoordinate + (2.0h * samplingOffset)) * 0.12h; 25 | color += inputTexture.sample(quadSampler, fragmentInput.textureCoordinate + (3.0h * samplingOffset)) * 0.09h; 26 | color += inputTexture.sample(quadSampler, fragmentInput.textureCoordinate + (4.0h * samplingOffset)) * 0.05h; 27 | color += inputTexture.sample(quadSampler, fragmentInput.textureCoordinate - samplingOffset) * 0.15h; 28 | color += inputTexture.sample(quadSampler, fragmentInput.textureCoordinate - (2.0h * samplingOffset)) * 0.12h; 29 | color += inputTexture.sample(quadSampler, fragmentInput.textureCoordinate - (3.0h * samplingOffset)) * 0.09h; 30 | color += inputTexture.sample(quadSampler, fragmentInput.textureCoordinate - (4.0h * samplingOffset)) * 0.05h; 31 | 32 | return color; 33 | } 34 | 35 | 36 | -------------------------------------------------------------------------------- /VideoLab/Render/Operations/ZoomBlur.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ZoomBlur.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/31. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import CoreMedia 10 | 11 | public class ZoomBlur: BasicOperation { 12 | public var blurSize: Float = 1.0 { 13 | didSet { 14 | uniformSettings["size"] = blurSize 15 | } 16 | } 17 | 18 | public var blurCenter: Position2D = Position2D.center { 19 | didSet { 20 | uniformSettings["center"] = blurCenter 21 | } 22 | } 23 | 24 | public init() { 25 | super.init(fragmentFunctionName: "zoomBlurFragment", numberOfInputs: 1) 26 | shouldInputSourceTexture = true 27 | 28 | ({ blurSize = 1.0 })() 29 | ({ blurCenter = Position2D.center })() 30 | } 31 | 32 | public override func updateAnimationValues(at time: CMTime) { 33 | if let blurSize = KeyframeAnimation.value(for: "blurSize", at: time, animations: animations) { 34 | self.blurSize = blurSize 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /VideoLab/RenderComposition.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RenderComposition.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/29. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import AVFoundation 10 | import UIKit 11 | 12 | public class RenderComposition { 13 | public var backgroundColor: Color = Color.black { 14 | didSet { 15 | Color.clearColor = backgroundColor 16 | } 17 | } 18 | 19 | public var frameDuration: CMTime = CMTime(value: 1, timescale: 30) 20 | public var renderSize: CGSize = CGSize(width: 720, height: 1280) 21 | 22 | public var layers: [RenderLayer] = [] 23 | public var animationLayer: CALayer? 24 | 25 | public init() {} 26 | } 27 | -------------------------------------------------------------------------------- /VideoLab/RenderLayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RenderLayer.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/29. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import AVFoundation 10 | 11 | public class RenderLayer: Animatable { 12 | public var timeRange: CMTimeRange 13 | 14 | public var layerLevel: Int = 0 15 | public var transform: Transform = Transform.identity 16 | public var blendMode: BlendMode = BlendModeNormal 17 | public var blendOpacity: Float = 1.0 18 | public var operations: [BasicOperation] = [] 19 | 20 | public var audioConfiguration: AudioConfiguration = AudioConfiguration() 21 | 22 | let source: Source? 23 | 24 | public init(timeRange: CMTimeRange, source: Source? = nil) { 25 | self.timeRange = timeRange 26 | self.source = source 27 | } 28 | 29 | // MARK: - Animatable 30 | public var animations: [KeyframeAnimation]? 31 | public func updateAnimationValues(at time: CMTime) { 32 | if let blendOpacity = KeyframeAnimation.value(for: "blendOpacity", at: time, animations: animations) { 33 | self.blendOpacity = blendOpacity 34 | } 35 | transform.updateAnimationValues(at: time) 36 | 37 | for operation in operations { 38 | let operationStartTime = operation.timeRange?.start ?? CMTime.zero 39 | let operationInternalTime = time - operationStartTime 40 | operation.updateAnimationValues(at: operationInternalTime) 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /VideoLab/RenderLayerGroup.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RenderLayerGroup.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/19. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import AVFoundation 10 | 11 | public class RenderLayerGroup: RenderLayer { 12 | public var layers: [RenderLayer] = [] 13 | } 14 | -------------------------------------------------------------------------------- /VideoLab/Source/ImageSource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageSource.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/1. 6 | // 7 | 8 | import AVFoundation 9 | import UIKit 10 | 11 | public class ImageSource: Source { 12 | private var cgImage: CGImage? 13 | var texture: Texture? 14 | 15 | public init(cgImage: CGImage?) { 16 | self.cgImage = cgImage 17 | duration = CMTime(seconds: 3, preferredTimescale: 600) // Default duration 18 | selectedTimeRange = CMTimeRangeMake(start: CMTime.zero, duration: duration) 19 | } 20 | 21 | public init() { 22 | duration = CMTime(seconds: 3, preferredTimescale: 600) // Default duration 23 | selectedTimeRange = CMTimeRangeMake(start: CMTime.zero, duration: duration) 24 | } 25 | 26 | public func copy() -> Source { 27 | let source = ImageSource.init() 28 | source.isLoaded = false 29 | source.cgImage = self.cgImage 30 | source.texture = self.texture 31 | source.duration = CMTime(seconds: 3, preferredTimescale: 600) // Default duration 32 | source.selectedTimeRange = CMTimeRangeMake(start: CMTime.zero, duration: duration) 33 | return source 34 | } 35 | 36 | // MARK: - Source 37 | public var selectedTimeRange: CMTimeRange 38 | 39 | public var duration: CMTime 40 | 41 | public var isLoaded: Bool = false 42 | 43 | public func load(completion: @escaping (NSError?) -> Void) { 44 | guard let cgImage = cgImage else { 45 | let error = NSError(domain: "com.source.load", 46 | code: 0, 47 | userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("Image is nil", comment: "")]) 48 | completion(error) 49 | isLoaded = true 50 | return 51 | } 52 | 53 | Texture.makeTexture(cgImage: cgImage) { [weak self] (texture) in 54 | guard let self = self else { return } 55 | 56 | self.texture = texture 57 | self.isLoaded = true 58 | completion(nil) 59 | } 60 | } 61 | 62 | public func tracks(for type: AVMediaType) -> [AVAssetTrack] { 63 | return [] 64 | } 65 | 66 | public func texture(at time: CMTime) -> Texture? { 67 | if isLoaded { 68 | return texture 69 | } 70 | 71 | defer { 72 | isLoaded = true 73 | } 74 | guard let cgImage = cgImage else { 75 | return nil 76 | } 77 | texture = Texture.makeTexture(cgImage: cgImage) 78 | return texture 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /VideoLab/Source/PHAssetImageSource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PHAssetImageSource.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/1. 6 | // 7 | 8 | import AVFoundation 9 | import Photos 10 | 11 | public class PHAssetImageSource: ImageSource { 12 | private var phAsset: PHAsset? 13 | 14 | public init(phAsset: PHAsset) { 15 | super.init() 16 | self.phAsset = phAsset 17 | } 18 | 19 | public override func copy() -> Source { 20 | let source = PHAssetImageSource.init(phAsset: self.phAsset!) 21 | source.isLoaded = false 22 | return source 23 | } 24 | 25 | // MARK: - Source 26 | override public func load(completion: @escaping (NSError?) -> Void) { 27 | guard let phAsset = phAsset else { 28 | let error = NSError(domain: "com.source.load", 29 | code: 0, 30 | userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("PHAsset is nil", comment: "")]) 31 | completion(error) 32 | return 33 | } 34 | 35 | let options = PHImageRequestOptions() 36 | options.version = .current 37 | options.deliveryMode = .highQualityFormat 38 | options.isNetworkAccessAllowed = true 39 | PHImageManager.default().requestImage(for: phAsset, targetSize: CGSize(width: phAsset.pixelWidth, height: phAsset.pixelHeight), contentMode: .aspectFill, options: options) { [weak self] (image, info) in 40 | guard let self = self else { return } 41 | if let error = info?[PHImageErrorKey] as? NSError { 42 | DispatchQueue.main.async { 43 | completion(error) 44 | } 45 | } 46 | 47 | if let cgImage = image?.cgImage { 48 | // defer { 49 | self.isLoaded = true 50 | // } 51 | self.texture = Texture.makeTexture(cgImage: cgImage) 52 | completion(nil); 53 | } else { 54 | let error = NSError(domain: "com.source.load", 55 | code: 0, 56 | userInfo: [NSLocalizedDescriptionKey: NSLocalizedString("PHAsset loaded, but can't find image", comment: "")]) 57 | completion(error) 58 | } 59 | } 60 | } 61 | 62 | override public func texture(at time: CMTime) -> Texture? { 63 | guard isLoaded else { 64 | fatalError("PHAssetImageSource must be loaded before use") 65 | } 66 | 67 | return super.texture(at: time) 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /VideoLab/Source/Source.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Source.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/29. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import AVFoundation 10 | 11 | public protocol Source { 12 | var selectedTimeRange: CMTimeRange { get set } 13 | var duration: CMTime { get set } 14 | var isLoaded: Bool { get set } 15 | 16 | func load(completion: @escaping (NSError?) -> Void) 17 | func tracks(for type: AVMediaType) -> [AVAssetTrack] 18 | func texture(at time: CMTime) -> Texture? 19 | 20 | func copy() -> Source 21 | } 22 | 23 | extension Source { 24 | public func texture(at time: CMTime) -> Texture? { 25 | return nil 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /VideoLab/Text/TextOpacityAnimationLayer.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TextOpacityAnimationLayer.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/11. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import AVFoundation 10 | 11 | public class TextOpacityAnimationLayer: TextAnimationLayer { 12 | override func addAnimations(to layers: [CATextLayer]) { 13 | var beginTime = AVCoreAnimationBeginTimeAtZero 14 | let beginTimeInterval = 0.125 15 | 16 | for layer in layers { 17 | let animationGroup = CAAnimationGroup() 18 | animationGroup.duration = 15.0 19 | animationGroup.beginTime = AVCoreAnimationBeginTimeAtZero 20 | animationGroup.fillMode = .both 21 | animationGroup.isRemovedOnCompletion = false 22 | 23 | let opacityAnimation = CABasicAnimation(keyPath: "opacity") 24 | opacityAnimation.fromValue = 0.0 25 | opacityAnimation.toValue = 1.0 26 | opacityAnimation.duration = 0.125 27 | opacityAnimation.beginTime = beginTime 28 | opacityAnimation.fillMode = .both 29 | 30 | let scaleAnimation = CABasicAnimation(keyPath: "transform.scale") 31 | scaleAnimation.fromValue = 0.0 32 | scaleAnimation.toValue = 1.0 33 | scaleAnimation.duration = 0.125 34 | scaleAnimation.beginTime = beginTime 35 | scaleAnimation.fillMode = .both 36 | 37 | animationGroup.animations = [opacityAnimation, scaleAnimation] 38 | layer.add(animationGroup, forKey: "animationGroup") 39 | 40 | beginTime += beginTimeInterval 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /VideoLab/Video/VideoCompositionInstruction.swift: -------------------------------------------------------------------------------- 1 | // 2 | // VideoCompositionInstruction.swift 3 | // VideoLab 4 | // 5 | // Created by Bear on 2020/8/29. 6 | // Copyright © 2020 Chocolate. All rights reserved. 7 | // 8 | 9 | import AVFoundation 10 | 11 | class VideoCompositionInstruction: NSObject, AVVideoCompositionInstructionProtocol { 12 | var timeRange: CMTimeRange 13 | var enablePostProcessing: Bool 14 | var containsTweening: Bool 15 | var requiredSourceTrackIDs: [NSValue]? 16 | var passthroughTrackID: CMPersistentTrackID 17 | 18 | var videoRenderLayers: [VideoRenderLayer] = [] 19 | 20 | init(videoRenderLayers: [VideoRenderLayer], timeRange: CMTimeRange) { 21 | self.timeRange = timeRange 22 | enablePostProcessing = true 23 | containsTweening = true 24 | passthroughTrackID = kCMPersistentTrackID_Invalid 25 | 26 | super.init() 27 | 28 | self.videoRenderLayers = videoRenderLayers 29 | 30 | var trackIDSet: Set = [] 31 | videoRenderLayers.forEach { videoRenderLayer in 32 | if let videoRenderLayerGroup = videoRenderLayer as? VideoRenderLayerGroup { 33 | let recursiveTrackIDs = videoRenderLayerGroup.recursiveTrackIDs() 34 | trackIDSet = trackIDSet.union(Set(recursiveTrackIDs)) 35 | } else { 36 | trackIDSet.insert(videoRenderLayer.trackID) 37 | } 38 | } 39 | requiredSourceTrackIDs = Array(trackIDSet) 40 | .filter { $0 != kCMPersistentTrackID_Invalid } 41 | .compactMap { $0 as NSValue } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /VideoLab/VideoLab.bundle/BlankVideo.mov: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ruanjx/VideoLab/d2651f4092a6eb343a799282def92c36c217958f/VideoLab/VideoLab.bundle/BlankVideo.mov --------------------------------------------------------------------------------