├── .gitignore
├── Examples
├── SimpleFourSquareVideo
│ ├── SimpleFourSquareVideo.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ ├── xcshareddata
│ │ │ └── xcschemes
│ │ │ │ └── SimpleFourSquareVideo.xcscheme
│ │ └── xcuserdata
│ │ │ └── renzhumacro.xcuserdatad
│ │ │ └── xcschemes
│ │ │ └── xcschememanagement.plist
│ └── SimpleFourSquareVideo
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── SceneDelegate.swift
│ │ ├── ViewController.swift
│ │ ├── cute.mp4
│ │ ├── movie.mov
│ │ ├── movie2.mp4
│ │ ├── movie3.mp4
│ │ └── out.mp4
├── SimpleRealtimeFilterPlayback
│ ├── SimpleRealtimeFilterPlayback.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── SimpleRealtimeFilterPlayback.xcscheme
│ └── SimpleRealtimeFilterPlayback
│ │ ├── 853.mp4
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── PlaygroundVC.swift
│ │ ├── SceneDelegate.swift
│ │ ├── ViewController.swift
│ │ └── cute.mp4
├── SimpleVideoAnimation
│ ├── Podfile
│ ├── Podfile.lock
│ ├── Pods
│ │ ├── Manifest.lock
│ │ ├── Pods.xcodeproj
│ │ │ └── project.pbxproj
│ │ ├── PryntTrimmerView
│ │ │ ├── LICENSE
│ │ │ ├── PryntTrimmerView
│ │ │ │ └── Classes
│ │ │ │ │ ├── Cropper
│ │ │ │ │ ├── CropMaskView.swift
│ │ │ │ │ ├── VideoCropView.swift
│ │ │ │ │ └── VideoScrollView.swift
│ │ │ │ │ ├── Parents
│ │ │ │ │ ├── AVAssetTimeSelector.swift
│ │ │ │ │ └── AssetVideoScrollView.swift
│ │ │ │ │ ├── ThumbSelectorView.swift
│ │ │ │ │ └── Trimmer
│ │ │ │ │ ├── HandlerView.swift
│ │ │ │ │ └── PryntTrimmerView.swift
│ │ │ └── README.md
│ │ └── Target Support Files
│ │ │ ├── Pods-SimpleVideoAnimation
│ │ │ ├── Pods-SimpleVideoAnimation-Info.plist
│ │ │ ├── Pods-SimpleVideoAnimation-acknowledgements.markdown
│ │ │ ├── Pods-SimpleVideoAnimation-acknowledgements.plist
│ │ │ ├── Pods-SimpleVideoAnimation-dummy.m
│ │ │ ├── Pods-SimpleVideoAnimation-frameworks-Debug-input-files.xcfilelist
│ │ │ ├── Pods-SimpleVideoAnimation-frameworks-Debug-output-files.xcfilelist
│ │ │ ├── Pods-SimpleVideoAnimation-frameworks-Release-input-files.xcfilelist
│ │ │ ├── Pods-SimpleVideoAnimation-frameworks-Release-output-files.xcfilelist
│ │ │ ├── Pods-SimpleVideoAnimation-frameworks.sh
│ │ │ ├── Pods-SimpleVideoAnimation-umbrella.h
│ │ │ ├── Pods-SimpleVideoAnimation.debug.xcconfig
│ │ │ ├── Pods-SimpleVideoAnimation.modulemap
│ │ │ └── Pods-SimpleVideoAnimation.release.xcconfig
│ │ │ └── PryntTrimmerView
│ │ │ ├── PryntTrimmerView-Info.plist
│ │ │ ├── PryntTrimmerView-dummy.m
│ │ │ ├── PryntTrimmerView-prefix.pch
│ │ │ ├── PryntTrimmerView-umbrella.h
│ │ │ ├── PryntTrimmerView.modulemap
│ │ │ └── PryntTrimmerView.xcconfig
│ ├── SimpleVIdeoAnimation.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── SimpleVideoAnimation.xcscheme
│ ├── SimpleVIdeoAnimation
│ │ ├── 853.mp4
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ │ ├── AppIcon.appiconset
│ │ │ │ └── Contents.json
│ │ │ └── Contents.json
│ │ ├── Base.lproj
│ │ │ ├── LaunchScreen.storyboard
│ │ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── NavigateViewController.swift
│ │ ├── SceneDelegate.swift
│ │ ├── ViewController.swift
│ │ └── cute.mp4
│ └── SimpleVideoAnimation.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
├── SimpleVideoEditor
│ ├── SimpleVideoEditor.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ ├── xcshareddata
│ │ │ └── xcschemes
│ │ │ │ └── SimpleVideoEditor.xcscheme
│ │ └── xcuserdata
│ │ │ └── renzhumacro.xcuserdatad
│ │ │ └── xcschemes
│ │ │ └── xcschememanagement.plist
│ └── SimpleVideoEditor
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Images.xcassets
│ │ ├── Contents.json
│ │ ├── gallery_picker_camera.imageset
│ │ │ ├── Contents.json
│ │ │ ├── baseline_camera_alt_black_24pt_1x.png
│ │ │ ├── baseline_camera_alt_black_24pt_2x.png
│ │ │ └── baseline_camera_alt_black_24pt_3x.png
│ │ ├── gallery_picker_cloud.imageset
│ │ │ ├── Contents.json
│ │ │ ├── baseline_cloud_black_24pt_1x.png
│ │ │ ├── baseline_cloud_black_24pt_2x.png
│ │ │ └── baseline_cloud_black_24pt_3x.png
│ │ └── gallery_picker_library.imageset
│ │ │ ├── Contents.json
│ │ │ ├── baseline_photo_library_black_24pt_1x.png
│ │ │ ├── baseline_photo_library_black_24pt_2x.png
│ │ │ └── baseline_photo_library_black_24pt_3x.png
│ │ ├── Info.plist
│ │ ├── Model
│ │ └── ResourceItem.swift
│ │ ├── ResourceItemEditView.swift
│ │ ├── ResourceItemEditView.xib
│ │ ├── ResourceItemTableViewCell.swift
│ │ ├── SceneDelegate.swift
│ │ ├── SimpleVideoEditor-Bridging-Header.h
│ │ ├── Vender
│ │ ├── DynamicBlurView
│ │ │ ├── BlurLayer.swift
│ │ │ ├── CGContext+CGImage.swift
│ │ │ ├── CGImage+Accelerate.swift
│ │ │ ├── CaptureQuality.swift
│ │ │ ├── DynamicBlurView.h
│ │ │ ├── DynamicBlurView.swift
│ │ │ ├── TrackingMode.swift
│ │ │ └── UIImage+Blur.swift
│ │ ├── PopupDialog
│ │ │ ├── InteractiveTransition.swift
│ │ │ ├── PopupDialog+Keyboard.swift
│ │ │ ├── PopupDialog.swift
│ │ │ ├── PopupDialogButton.swift
│ │ │ ├── PopupDialogContainerView.swift
│ │ │ ├── PopupDialogDefaultButtons.swift
│ │ │ ├── PopupDialogDefaultView.swift
│ │ │ ├── PopupDialogDefaultViewController.swift
│ │ │ ├── PopupDialogOverlayView.swift
│ │ │ ├── PresentationController.swift
│ │ │ ├── PresentationManager.swift
│ │ │ ├── TransitionAnimations.swift
│ │ │ ├── TransitionAnimator.swift
│ │ │ ├── UIImageView+Calculations.swift
│ │ │ ├── UIView+Animations.swift
│ │ │ └── UIViewController+Visibility.swift
│ │ └── TableViewDragger
│ │ │ ├── ScrollRects.swift
│ │ │ ├── TableViewDragger.swift
│ │ │ ├── TableViewDraggerCell.swift
│ │ │ └── UIScrollViewExtension.swift
│ │ ├── ViewController+MetalVideoProcessPlayerDelegate.swift
│ │ ├── ViewController+UIGestureRecognizerDelegate.swift
│ │ ├── ViewController+UIImagePickerControllerDelegate.swift
│ │ ├── ViewController+UITableViewDelegate.swift
│ │ ├── ViewController.swift
│ │ ├── cute.mp4
│ │ └── movie.mov
├── SimpleVideoExport
│ ├── SimpleVideoExport.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ ├── xcshareddata
│ │ │ └── xcschemes
│ │ │ │ └── SimpleVideoExport.xcscheme
│ │ └── xcuserdata
│ │ │ └── renzhumacro.xcuserdatad
│ │ │ └── xcschemes
│ │ │ └── xcschememanagement.plist
│ └── SimpleVideoExport
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── SceneDelegate.swift
│ │ ├── SimpleVideoExport-Bridging-Header.h
│ │ ├── UI
│ │ ├── MBProgressHUD.h
│ │ ├── MBProgressHUD.m
│ │ ├── MBProgressHUDExtension.swift
│ │ ├── ProgressHUD.bundle
│ │ │ ├── progresshud-error@2x.png
│ │ │ └── progresshud-success@2x.png
│ │ ├── ProgressHUD.h
│ │ └── ProgressHUD.m
│ │ └── ViewController.swift
├── SimpleVideoTransition
│ ├── SimpleVideoTransition.xcodeproj
│ │ ├── project.pbxproj
│ │ ├── project.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ └── xcshareddata
│ │ │ └── xcschemes
│ │ │ └── SimpleVideoTransition.xcscheme
│ └── SimpleVideoTransition
│ │ ├── 853.mp4
│ │ ├── AppDelegate.swift
│ │ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ │ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ │ ├── Info.plist
│ │ ├── Model
│ │ └── ResourceItem.swift
│ │ ├── NaviViewController.swift
│ │ ├── ResourceItemEditView.swift
│ │ ├── ResourceItemEditView.xib
│ │ ├── ResourceItemTableViewCell.swift
│ │ ├── SceneDelegate.swift
│ │ ├── SimpleVideoEditor-Bridging-Header.h
│ │ ├── Vender
│ │ ├── DynamicBlurView
│ │ │ ├── BlurLayer.swift
│ │ │ ├── CGContext+CGImage.swift
│ │ │ ├── CGImage+Accelerate.swift
│ │ │ ├── CaptureQuality.swift
│ │ │ ├── DynamicBlurView.h
│ │ │ ├── DynamicBlurView.swift
│ │ │ ├── TrackingMode.swift
│ │ │ └── UIImage+Blur.swift
│ │ ├── PopupDialog
│ │ │ ├── InteractiveTransition.swift
│ │ │ ├── PopupDialog+Keyboard.swift
│ │ │ ├── PopupDialog.swift
│ │ │ ├── PopupDialogButton.swift
│ │ │ ├── PopupDialogContainerView.swift
│ │ │ ├── PopupDialogDefaultButtons.swift
│ │ │ ├── PopupDialogDefaultView.swift
│ │ │ ├── PopupDialogDefaultViewController.swift
│ │ │ ├── PopupDialogOverlayView.swift
│ │ │ ├── PresentationController.swift
│ │ │ ├── PresentationManager.swift
│ │ │ ├── TransitionAnimations.swift
│ │ │ ├── TransitionAnimator.swift
│ │ │ ├── UIImageView+Calculations.swift
│ │ │ ├── UIView+Animations.swift
│ │ │ └── UIViewController+Visibility.swift
│ │ └── TableViewDragger
│ │ │ ├── ScrollRects.swift
│ │ │ ├── TableViewDragger.swift
│ │ │ ├── TableViewDraggerCell.swift
│ │ │ └── UIScrollViewExtension.swift
│ │ ├── ViewController+MetalVideoProcessPlayerDelegate.swift
│ │ ├── ViewController+UIGestureRecognizerDelegate.swift
│ │ ├── ViewController+UIImagePickerControllerDelegate.swift
│ │ ├── ViewController+UITableViewDelegate.swift
│ │ ├── ViewController.swift
│ │ ├── cute.mp4
│ │ └── movie.mov
└── SimpleVideoTransitionSwitch
│ ├── SimpleVideoTransition
│ ├── 853.mp4
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── Contents.json
│ ├── Base.lproj
│ │ ├── LaunchScreen.storyboard
│ │ └── Main.storyboard
│ ├── Images.xcassets
│ │ ├── Contents.json
│ │ ├── gallery_picker_camera.imageset
│ │ │ ├── Contents.json
│ │ │ ├── baseline_camera_alt_black_24pt_1x.png
│ │ │ ├── baseline_camera_alt_black_24pt_2x.png
│ │ │ └── baseline_camera_alt_black_24pt_3x.png
│ │ ├── gallery_picker_cloud.imageset
│ │ │ ├── Contents.json
│ │ │ ├── baseline_cloud_black_24pt_1x.png
│ │ │ ├── baseline_cloud_black_24pt_2x.png
│ │ │ └── baseline_cloud_black_24pt_3x.png
│ │ └── gallery_picker_library.imageset
│ │ │ ├── Contents.json
│ │ │ ├── baseline_photo_library_black_24pt_1x.png
│ │ │ ├── baseline_photo_library_black_24pt_2x.png
│ │ │ └── baseline_photo_library_black_24pt_3x.png
│ ├── Info.plist
│ ├── Model
│ │ └── ResourceItem.swift
│ ├── ResourceItemEditView.swift
│ ├── ResourceItemEditView.xib
│ ├── ResourceItemTableViewCell.swift
│ ├── SceneDelegate.swift
│ ├── SimpleVideoEditor-Bridging-Header.h
│ ├── Vender
│ │ ├── DynamicBlurView
│ │ │ ├── BlurLayer.swift
│ │ │ ├── CGContext+CGImage.swift
│ │ │ ├── CGImage+Accelerate.swift
│ │ │ ├── CaptureQuality.swift
│ │ │ ├── DynamicBlurView.h
│ │ │ ├── DynamicBlurView.swift
│ │ │ ├── TrackingMode.swift
│ │ │ └── UIImage+Blur.swift
│ │ ├── PopupDialog
│ │ │ ├── InteractiveTransition.swift
│ │ │ ├── PopupDialog+Keyboard.swift
│ │ │ ├── PopupDialog.swift
│ │ │ ├── PopupDialogButton.swift
│ │ │ ├── PopupDialogContainerView.swift
│ │ │ ├── PopupDialogDefaultButtons.swift
│ │ │ ├── PopupDialogDefaultView.swift
│ │ │ ├── PopupDialogDefaultViewController.swift
│ │ │ ├── PopupDialogOverlayView.swift
│ │ │ ├── PresentationController.swift
│ │ │ ├── PresentationManager.swift
│ │ │ ├── TransitionAnimations.swift
│ │ │ ├── TransitionAnimator.swift
│ │ │ ├── UIImageView+Calculations.swift
│ │ │ ├── UIView+Animations.swift
│ │ │ └── UIViewController+Visibility.swift
│ │ └── TableViewDragger
│ │ │ ├── ScrollRects.swift
│ │ │ ├── TableViewDragger.swift
│ │ │ ├── TableViewDraggerCell.swift
│ │ │ └── UIScrollViewExtension.swift
│ ├── ViewController+MetalVideoProcessPlayerDelegate.swift
│ ├── ViewController+UIGestureRecognizerDelegate.swift
│ ├── ViewController+UIImagePickerControllerDelegate.swift
│ ├── ViewController+UITableViewDelegate.swift
│ ├── ViewController.swift
│ ├── ViewController_BACKUP_17810.swift
│ ├── ViewController_BASE_17810.swift
│ ├── ViewController_LOCAL_17810.swift
│ ├── ViewController_REMOTE_17810.swift
│ ├── cute.mp4
│ └── movie.mov
│ └── SimpleVideoTransitionSwitch.xcodeproj
│ ├── project.pbxproj
│ ├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ ├── renzhumacro.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ │ └── ruanshengqiang.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ └── xcshareddata
│ └── xcschemes
│ └── SimpleVideoTransition.xcscheme
├── LICENSE
├── MetalVideoProcess.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
└── xcshareddata
│ └── xcschemes
│ └── MetalVideoProcess.xcscheme
├── MetalVideoProcess
├── Info.plist
├── MetalVideoProcess.h
├── Vender
│ ├── Editor
│ │ ├── Core
│ │ │ ├── Audio
│ │ │ │ ├── AudioMixer.swift
│ │ │ │ ├── AudioProcessingChain.swift
│ │ │ │ └── AudioProcessingTapHolder.swift
│ │ │ ├── CompositionGenerator.swift
│ │ │ ├── Model
│ │ │ │ ├── AudioTransition.swift
│ │ │ │ ├── CompositionProvider.swift
│ │ │ │ ├── Timeline.swift
│ │ │ │ └── VideoTransition.swift
│ │ │ └── Video
│ │ │ │ ├── VideoCompositionInstruction.swift
│ │ │ │ └── VideoCompositor.swift
│ │ ├── Resource
│ │ │ └── black_empty.mp4
│ │ ├── Track
│ │ │ ├── Configuration
│ │ │ │ └── TrackConfiguration.swift
│ │ │ ├── ImageCompositionGroupProvider.swift
│ │ │ ├── ImageOverlayItem.swift
│ │ │ ├── Resource
│ │ │ │ ├── AVAssetReaderImageResource.swift
│ │ │ │ ├── AVAssetReverseImageResource.swift
│ │ │ │ ├── AVAssetTrackResource.swift
│ │ │ │ ├── ImageResource.swift
│ │ │ │ ├── PHAssetImageResource.swift
│ │ │ │ ├── PHAssetLivePhotoResource.swift
│ │ │ │ ├── PHAssetTrackResource.swift
│ │ │ │ └── Resource.swift
│ │ │ └── TrackItem.swift
│ │ └── Uitl
│ │ │ ├── CGMathFunctions.swift
│ │ │ ├── CMTimeExtensition.swift
│ │ │ ├── CoreImageExtension.swift
│ │ │ ├── ImageGeneratorExtension.swift
│ │ │ ├── Log.swift
│ │ │ ├── TimeRangeExtension.swift
│ │ │ └── TimingFunctionFactory.swift
│ └── Render
│ │ ├── Base
│ │ ├── Color.swift
│ │ ├── ImageOrientation.swift
│ │ ├── Matrix.swift
│ │ ├── MetalRendering.swift
│ │ ├── MetalRenderingDevice.swift
│ │ ├── OperationShaderTypes.h
│ │ ├── Pipeline.swift
│ │ ├── Position.swift
│ │ ├── ShaderUniformSettings.swift
│ │ ├── Size.swift
│ │ ├── Texture.swift
│ │ ├── Timestamp.swift
│ │ └── default.metal
│ │ ├── Inputs
│ │ ├── Camera.swift
│ │ ├── ImageGenerator.swift
│ │ ├── PictureInput.swift
│ │ ├── SolidColorGenerator.swift
│ │ ├── YUVToRGBConversion.metal
│ │ └── YUVToRGBConversion.swift
│ │ └── Outputs
│ │ ├── PictureOutput.swift
│ │ └── RenderView.swift
└── VideoProcess
│ ├── Base
│ ├── MetalVideoProcessCompositionRequestCache.swift
│ ├── MetalVideoProcessCompositor.swift
│ ├── MetalVideoProcessMotion.swift
│ ├── MetalVideoProcessOperation.swift
│ └── MetalVideoProcessTransition.swift
│ ├── Filters
│ ├── MetalVideoProcessBackground.swift
│ ├── MetalVideoProcessBeautyFilter.metal
│ ├── MetalVideoProcessBeautyFilter.swift
│ ├── MetalVideoProcessBlendFilter.metal
│ ├── MetalVideoProcessBlendFilter.swift
│ ├── MetalVideoProcessColorFilter.metal
│ ├── MetalVideoProcessColorFilter.swift
│ ├── MetalVideoProcessFilterGroup.swift
│ ├── MetalVideoProcessGaussianBlurFilter.swift
│ ├── MetalVideoProcessLuminance.metal
│ ├── MetalVideoProcessLuminance.swift
│ ├── MetalVideoProcessTransformFilter.metal
│ └── MetalVideoProcessTransformFilter.swift
│ ├── MetalVideoEditor.swift
│ ├── MetalVideoProcessMovieWriter.swift
│ ├── MetalVideoProcessPlayer+CompositorDelegate.swift
│ ├── MetalVideoProcessPlayer.swift
│ ├── MetalVideoProcessRenderView.swift
│ ├── Motions
│ ├── MetalVideoProcessFadeInMotion.swift
│ ├── MetalVideoProcessFadeMotion.metal
│ ├── MetalVideoProcessFadeOutMotion.swift
│ ├── MetalVideoProcessMirrorRotateMotion.metal
│ ├── MetalVideoProcessMirrorRotateMotion.swift
│ ├── MetalVideoProcessMoveDownMotion.metal
│ ├── MetalVideoProcessMoveDownMotion.swift
│ ├── MetalVideoProcessMoveLeftMotion.metal
│ ├── MetalVideoProcessMoveLeftMotion.swift
│ ├── MetalVideoProcessMoveRightMotion.metal
│ ├── MetalVideoProcessMoveRightMotion.swift
│ ├── MetalVideoProcessMoveUpMotion.metal
│ ├── MetalVideoProcessMoveUpMotion.swift
│ ├── MetalVideoProcessPendulumMotion.metal
│ ├── MetalVideoProcessPendulumMotion.swift
│ ├── MetalVideoProcessRightDropMotion.metal
│ ├── MetalVideoProcessRightDropMotion.swift
│ ├── MetalVideoProcessRotateInRightMotion.metal
│ ├── MetalVideoProcessRotateInRightMotion.swift
│ ├── MetalVideoProcessRotateMotion.metal
│ ├── MetalVideoProcessRotateMotion.swift
│ ├── MetalVideoProcessSlimZoomInMotion.metal
│ ├── MetalVideoProcessSlimZoomInMotion.swift
│ ├── MetalVideoProcessSwirlMotion.metal
│ ├── MetalVideoProcessSwirlMotion.swift
│ ├── MetalVideoProcessUpDropMotion.metal
│ ├── MetalVideoProcessUpDropMotion.swift
│ ├── MetalVideoProcessUpMoveInBlurIIMotion.metal
│ ├── MetalVideoProcessUpMoveInBlurIIMotion.swift
│ ├── MetalVideoProcessUpMoveInBlurMotion.metal
│ ├── MetalVideoProcessUpMoveInBlurMotion.swift
│ ├── MetalVideoProcessWiperMotion.metal
│ ├── MetalVideoProcessWiperMotion.swift
│ ├── MetalVideoProcessZoomInBlurMotion.metal
│ ├── MetalVideoProcessZoomInBlurMotion.swift
│ ├── MetalVideoProcessZoomInMotion.metal
│ ├── MetalVideoProcessZoomInMotion.swift
│ ├── MetalVideoProcessZoomOutBlurMotion.metal
│ ├── MetalVideoProcessZoomOutBlurMotion.swift
│ ├── MetalVideoProcessZoomOutMotion.metal
│ └── MetalVideoProcessZoomOutMotion.swift
│ └── Transitions
│ ├── MetalVideoProcessBurnTransition.metal
│ ├── MetalVideoProcessBurnTransition.swift
│ ├── MetalVideoProcessCircleEraseTransition.metal
│ ├── MetalVideoProcessCircleEraseTransition.swift
│ ├── MetalVideoProcessCubeTransition.metal
│ ├── MetalVideoProcessCubeTransition.swift
│ ├── MetalVideoProcessEraseDownTransition.metal
│ ├── MetalVideoProcessEraseDownTransition.swift
│ ├── MetalVideoProcessEraseLeftTransition.metal
│ ├── MetalVideoProcessEraseLeftTransition.swift
│ ├── MetalVideoProcessEraseRightTransition.metal
│ ├── MetalVideoProcessEraseRightTransition.swift
│ ├── MetalVideoProcessEraseUpTransition.metal
│ ├── MetalVideoProcessEraseUpTransition.swift
│ ├── MetalVideoProcessFadeTransition.metal
│ ├── MetalVideoProcessFadeTransition.swift
│ ├── MetalVideoProcessMirrorRotateTransition.metal
│ ├── MetalVideoProcessMirrorRotateTransition.swift
│ ├── MetalVideoProcessMorphTransition.metal
│ ├── MetalVideoProcessMorphTransition.swift
│ ├── MetalVideoProcessReflectTransition.metal
│ ├── MetalVideoProcessReflectTransition.swift
│ ├── MetalVideoProcessShanBaiTransition.metal
│ ├── MetalVideoProcessShanBaiTransition.swift
│ ├── MetalVideoProcessVerticalUpGlitchTransition.metal
│ └── MetalVideoProcessVerticalUpGlitchTransition.swift
├── README.md
└── Readme
├── Layer.png
└── videoTransitionDesign.png
/.gitignore:
--------------------------------------------------------------------------------
1 | MetalVideoProcess.xcodeproj/project.xcworkspace/xcshareddata
2 | MetalVideoProcess.xcodeproj/project.xcworkspace/xcuserdata
3 | MetalVideoProcess.xcodeproj/xcuserdata
4 | Examples/SimpleRealtimeFilterPlayback/SimpleRealtimeFilterPlayback.xcodeproj/project.xcworkspace/xcuserdata
5 | Examples/SimpleFourSquareVideo/SimpleFourSquareVideo.xcodeproj/project.xcworkspace/xcuserdata/renzhumacro.xcuserdatad
6 | Examples/SimpleVideoExport/SimpleVideoExport.xcodeproj/project.xcworkspace/xcuserdata
7 | Examples/SimpleRealtimeFilterPlayback/SimpleRealtimeFilterPlayback.xcodeproj/xcuserdata
8 | Examples/SimpleVideoTransition/SimpleVideoTransition.xcodeproj/project.xcworkspace/xcuserdata/renzhumacro.xcuserdatad
9 | Examples/SimpleVideoTransition/SimpleVideoTransition.xcodeproj/xcuserdata/renzhumacro.xcuserdatad
10 | Examples/SimpleVideoAnimation/Pods/Pods.xcodeproj/xcuserdata/renzhumacro.xcuserdatad
11 | Examples/SimpleVideoAnimation/SimpleVIdeoAnimation.xcodeproj/project.xcworkspace/xcuserdata
12 | Examples/SimpleVideoAnimation/SimpleVIdeoAnimation.xcodeproj/xcuserdata
13 | Examples/SimpleVideoAnimation/SimpleVideoAnimation.xcworkspace/xcuserdata
14 | Examples/SimpleVideoTransitionSwitch/SimpleVideoTransitionSwitch.xcodeproj/xcuserdata
15 | Examples/SimpleVideoEditor/SimpleVideoEditor.xcodeproj/project.xcworkspace/xcuserdata
16 |
--------------------------------------------------------------------------------
/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo.xcodeproj/xcuserdata/renzhumacro.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SimpleFourSquareVideo.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 6ADB07EB24AF120E0010A817
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SimpleFourSquareVideo
4 | //
5 | // Created by RenZhu Macro on 2020/7/3.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo/cute.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo/cute.mp4
--------------------------------------------------------------------------------
/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo/movie.mov:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo/movie.mov
--------------------------------------------------------------------------------
/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo/movie2.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo/movie2.mp4
--------------------------------------------------------------------------------
/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo/movie3.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo/movie3.mp4
--------------------------------------------------------------------------------
/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo/out.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleFourSquareVideo/SimpleFourSquareVideo/out.mp4
--------------------------------------------------------------------------------
/Examples/SimpleRealtimeFilterPlayback/SimpleRealtimeFilterPlayback.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Examples/SimpleRealtimeFilterPlayback/SimpleRealtimeFilterPlayback.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/SimpleRealtimeFilterPlayback/SimpleRealtimeFilterPlayback/853.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleRealtimeFilterPlayback/SimpleRealtimeFilterPlayback/853.mp4
--------------------------------------------------------------------------------
/Examples/SimpleRealtimeFilterPlayback/SimpleRealtimeFilterPlayback/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SimpleRealtimeFilterPlayback
4 | //
5 | // Created by RenZhu Macro on 2020/7/2.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application: didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/Examples/SimpleRealtimeFilterPlayback/SimpleRealtimeFilterPlayback/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Examples/SimpleRealtimeFilterPlayback/SimpleRealtimeFilterPlayback/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Examples/SimpleRealtimeFilterPlayback/SimpleRealtimeFilterPlayback/cute.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleRealtimeFilterPlayback/SimpleRealtimeFilterPlayback/cute.mp4
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Podfile:
--------------------------------------------------------------------------------
1 | # Uncomment the next line to define a global platform for your project
2 | # platform :ios, '9.0'
3 |
4 | target 'SimpleVideoAnimation' do
5 | # Comment the next line if you don't want to use dynamic frameworks
6 | use_frameworks!
7 |
8 | # Pods for SimpleVideoAnimation
9 | pod 'PryntTrimmerView'
10 |
11 | end
12 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - PryntTrimmerView (4.0.0)
3 |
4 | DEPENDENCIES:
5 | - PryntTrimmerView
6 |
7 | SPEC REPOS:
8 | trunk:
9 | - PryntTrimmerView
10 |
11 | SPEC CHECKSUMS:
12 | PryntTrimmerView: 67e67573ffd4c073f1308effa66aefd0cfa667a0
13 |
14 | PODFILE CHECKSUM: 4473f02a1528566660f9c5ed79ea1d9d7df2096d
15 |
16 | COCOAPODS: 1.8.4
17 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Manifest.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - PryntTrimmerView (4.0.0)
3 |
4 | DEPENDENCIES:
5 | - PryntTrimmerView
6 |
7 | SPEC REPOS:
8 | trunk:
9 | - PryntTrimmerView
10 |
11 | SPEC CHECKSUMS:
12 | PryntTrimmerView: 67e67573ffd4c073f1308effa66aefd0cfa667a0
13 |
14 | PODFILE CHECKSUM: 4473f02a1528566660f9c5ed79ea1d9d7df2096d
15 |
16 | COCOAPODS: 1.8.4
17 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/PryntTrimmerView/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Prynt
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/PryntTrimmerView/PryntTrimmerView/Classes/Trimmer/HandlerView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // HandlerView.swift
3 | // PryntTrimmerView
4 | //
5 | // Created by HHK on 27/03/2017.
6 | // Copyright © 2017 Prynt. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import UIKit
11 |
12 | class HandlerView: UIView {
13 |
14 | override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
15 | let hitFrame = bounds.insetBy(dx: -20, dy: -20)
16 | return hitFrame.contains(point) ? self : nil
17 | }
18 | override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
19 | let hitFrame = bounds.insetBy(dx: -20, dy: -20)
20 | return hitFrame.contains(point)
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/Pods-SimpleVideoAnimation/Pods-SimpleVideoAnimation-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 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/Pods-SimpleVideoAnimation/Pods-SimpleVideoAnimation-acknowledgements.markdown:
--------------------------------------------------------------------------------
1 | # Acknowledgements
2 | This application makes use of the following third party libraries:
3 |
4 | ## PryntTrimmerView
5 |
6 | MIT License
7 |
8 | Copyright (c) 2017 Prynt
9 |
10 | Permission is hereby granted, free of charge, to any person obtaining a copy
11 | of this software and associated documentation files (the "Software"), to deal
12 | in the Software without restriction, including without limitation the rights
13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14 | copies of the Software, and to permit persons to whom the Software is
15 | furnished to do so, subject to the following conditions:
16 |
17 | The above copyright notice and this permission notice shall be included in all
18 | copies or substantial portions of the Software.
19 |
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 | SOFTWARE.
27 |
28 | Generated by CocoaPods - https://cocoapods.org
29 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/Pods-SimpleVideoAnimation/Pods-SimpleVideoAnimation-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_Pods_SimpleVideoAnimation : NSObject
3 | @end
4 | @implementation PodsDummy_Pods_SimpleVideoAnimation
5 | @end
6 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/Pods-SimpleVideoAnimation/Pods-SimpleVideoAnimation-frameworks-Debug-input-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${PODS_ROOT}/Target Support Files/Pods-SimpleVideoAnimation/Pods-SimpleVideoAnimation-frameworks.sh
2 | ${BUILT_PRODUCTS_DIR}/PryntTrimmerView/PryntTrimmerView.framework
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/Pods-SimpleVideoAnimation/Pods-SimpleVideoAnimation-frameworks-Debug-output-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PryntTrimmerView.framework
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/Pods-SimpleVideoAnimation/Pods-SimpleVideoAnimation-frameworks-Release-input-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${PODS_ROOT}/Target Support Files/Pods-SimpleVideoAnimation/Pods-SimpleVideoAnimation-frameworks.sh
2 | ${BUILT_PRODUCTS_DIR}/PryntTrimmerView/PryntTrimmerView.framework
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/Pods-SimpleVideoAnimation/Pods-SimpleVideoAnimation-frameworks-Release-output-files.xcfilelist:
--------------------------------------------------------------------------------
1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/PryntTrimmerView.framework
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/Pods-SimpleVideoAnimation/Pods-SimpleVideoAnimation-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_SimpleVideoAnimationVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char Pods_SimpleVideoAnimationVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/Pods-SimpleVideoAnimation/Pods-SimpleVideoAnimation.debug.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PryntTrimmerView"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PryntTrimmerView/PryntTrimmerView.framework/Headers"
5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
6 | OTHER_LDFLAGS = $(inherited) -framework "PryntTrimmerView"
7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
8 | PODS_BUILD_DIR = ${BUILD_DIR}
9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
11 | PODS_ROOT = ${SRCROOT}/Pods
12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
13 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/Pods-SimpleVideoAnimation/Pods-SimpleVideoAnimation.modulemap:
--------------------------------------------------------------------------------
1 | framework module Pods_SimpleVideoAnimation {
2 | umbrella header "Pods-SimpleVideoAnimation-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/Pods-SimpleVideoAnimation/Pods-SimpleVideoAnimation.release.xcconfig:
--------------------------------------------------------------------------------
1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES
2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PryntTrimmerView"
3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1
4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/PryntTrimmerView/PryntTrimmerView.framework/Headers"
5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks'
6 | OTHER_LDFLAGS = $(inherited) -framework "PryntTrimmerView"
7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS
8 | PODS_BUILD_DIR = ${BUILD_DIR}
9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)
10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/.
11 | PODS_ROOT = ${SRCROOT}/Pods
12 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
13 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/PryntTrimmerView/PryntTrimmerView-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 | 4.0.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | ${CURRENT_PROJECT_VERSION}
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/PryntTrimmerView/PryntTrimmerView-dummy.m:
--------------------------------------------------------------------------------
1 | #import
2 | @interface PodsDummy_PryntTrimmerView : NSObject
3 | @end
4 | @implementation PodsDummy_PryntTrimmerView
5 | @end
6 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/PryntTrimmerView/PryntTrimmerView-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 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/PryntTrimmerView/PryntTrimmerView-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 PryntTrimmerViewVersionNumber;
15 | FOUNDATION_EXPORT const unsigned char PryntTrimmerViewVersionString[];
16 |
17 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/PryntTrimmerView/PryntTrimmerView.modulemap:
--------------------------------------------------------------------------------
1 | framework module PryntTrimmerView {
2 | umbrella header "PryntTrimmerView-umbrella.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/Pods/Target Support Files/PryntTrimmerView/PryntTrimmerView.xcconfig:
--------------------------------------------------------------------------------
1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/PryntTrimmerView
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}/PryntTrimmerView
8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier}
9 | SKIP_INSTALL = YES
10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
11 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/SimpleVIdeoAnimation.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/SimpleVIdeoAnimation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/SimpleVIdeoAnimation/853.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoAnimation/SimpleVIdeoAnimation/853.mp4
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/SimpleVIdeoAnimation/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SimpleVideoAnimation
4 | //
5 | // Created by RenZhu Macro on 2020/7/20.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/SimpleVIdeoAnimation/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/SimpleVIdeoAnimation/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/SimpleVIdeoAnimation/cute.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoAnimation/SimpleVIdeoAnimation/cute.mp4
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/SimpleVideoAnimation.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoAnimation/SimpleVideoAnimation.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor.xcodeproj/xcuserdata/renzhumacro.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SimpleVideoEditor.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 1
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 6ADB07BD24ADE0730010A817
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SimpleVideoEditor
4 | //
5 | // Created by RenZhu Macro on 2020/7/2.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_camera.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "baseline_camera_alt_black_24pt_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "baseline_camera_alt_black_24pt_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "baseline_camera_alt_black_24pt_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | },
23 | "properties" : {
24 | "template-rendering-intent" : "template"
25 | }
26 | }
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_camera.imageset/baseline_camera_alt_black_24pt_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_camera.imageset/baseline_camera_alt_black_24pt_1x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_camera.imageset/baseline_camera_alt_black_24pt_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_camera.imageset/baseline_camera_alt_black_24pt_2x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_camera.imageset/baseline_camera_alt_black_24pt_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_camera.imageset/baseline_camera_alt_black_24pt_3x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_cloud.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "baseline_cloud_black_24pt_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "baseline_cloud_black_24pt_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "baseline_cloud_black_24pt_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | },
23 | "properties" : {
24 | "template-rendering-intent" : "template"
25 | }
26 | }
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_cloud.imageset/baseline_cloud_black_24pt_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_cloud.imageset/baseline_cloud_black_24pt_1x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_cloud.imageset/baseline_cloud_black_24pt_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_cloud.imageset/baseline_cloud_black_24pt_2x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_cloud.imageset/baseline_cloud_black_24pt_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_cloud.imageset/baseline_cloud_black_24pt_3x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_library.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "baseline_photo_library_black_24pt_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "baseline_photo_library_black_24pt_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "baseline_photo_library_black_24pt_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | },
23 | "properties" : {
24 | "template-rendering-intent" : "template"
25 | }
26 | }
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_library.imageset/baseline_photo_library_black_24pt_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_library.imageset/baseline_photo_library_black_24pt_1x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_library.imageset/baseline_photo_library_black_24pt_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_library.imageset/baseline_photo_library_black_24pt_2x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_library.imageset/baseline_photo_library_black_24pt_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoEditor/SimpleVideoEditor/Images.xcassets/gallery_picker_library.imageset/baseline_photo_library_black_24pt_3x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Model/ResourceItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ResourceItem.swift
3 | // SimpleVideoEditor
4 | //
5 | // Created by RenZhu Macro on 2020/7/7.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import MetalVideoProcess
11 |
12 | class ResourceItem: MetalVideoEditorItem {
13 |
14 | public var rotate = 0.0
15 | public var scale = Position(1.0, 1.0)
16 | //translation 为归一化
17 | public var translation = Position(0.0, 0.0)
18 |
19 | var orientation : UIInterfaceOrientation = .portrait
20 | weak var transformFilter: MetalVideoProcessTransformFilter?
21 | weak var currentLayer: MetalVideoProcessBlendFilter?
22 | var roi: CGRect = CGRect.zero
23 | var fillType: MetalVideoProcessTransformFilter.StretchType = .aspectToFill
24 |
25 | var isSelected: Bool = false
26 |
27 | var startTimeText: NSString {
28 | get {
29 | return NSString(format: "%.2f", self.startTime.seconds)
30 | }
31 | }
32 |
33 | var durationText: NSString {
34 | get {
35 | return NSString(format: "%.2f", self.duration.seconds)
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/ResourceItemTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ResourceItemTableViewCell.swift
3 | // SimpleVideoEditor
4 | //
5 | // Created by RenZhu Macro on 2020/7/8.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ResourceItemTableViewCell: UITableViewCell {
12 | @IBOutlet weak var trackIdLabel: UILabel!
13 |
14 | override func awakeFromNib() {
15 | super.awakeFromNib()
16 | // Initialization code
17 | }
18 |
19 | override func setSelected(_ selected: Bool, animated: Bool) {
20 | super.setSelected(selected, animated: animated)
21 |
22 | // Configure the view for the selected state
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/SimpleVideoEditor-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Header.h
3 | // SimpleVideoExport
4 | //
5 | // Created by RenZhu Macro on 2020/7/7.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | #import "ProgressHUD.h"
10 | #import "MBProgressHUD.h"
11 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Vender/DynamicBlurView/CGContext+CGImage.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CGContext+CGImage.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/17.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | extension CGContext {
10 | static func imageContext(with quality: CaptureQuality, rect: CGRect, opaque: Bool) -> CGContext? {
11 | UIGraphicsBeginImageContextWithOptions(rect.size, opaque, quality.imageScale)
12 | guard let context = UIGraphicsGetCurrentContext() else {
13 | return nil
14 | }
15 |
16 | context.translateBy(x: -rect.origin.x, y: -rect.origin.y)
17 | context.interpolationQuality = quality.interpolationQuality
18 |
19 | return context
20 | }
21 |
22 | func makeImage(with blendColor: UIColor?, blendMode: CGBlendMode, size: CGSize) -> CGImage? {
23 | if let color = blendColor {
24 | setFillColor(color.cgColor)
25 | setBlendMode(blendMode)
26 | fill(CGRect(origin: .zero, size: size))
27 | }
28 |
29 | return makeImage()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Vender/DynamicBlurView/CaptureQuality.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CaptureQuality.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/17.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | public enum CaptureQuality {
10 | case `default`
11 | case low
12 | case medium
13 | case high
14 |
15 | var imageScale: CGFloat {
16 | switch self {
17 | case .default, .high:
18 | return 0
19 | case .low, .medium:
20 | return 1
21 | }
22 | }
23 |
24 | var interpolationQuality: CGInterpolationQuality {
25 | switch self {
26 | case .default, .low:
27 | return .none
28 | case .medium, .high:
29 | return .default
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Vender/DynamicBlurView/DynamicBlurView.h:
--------------------------------------------------------------------------------
1 | //
2 | // DynamicBlurView.h
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2015/04/08.
6 | // Copyright (c) 2015年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for DynamicBlurView.
12 | FOUNDATION_EXPORT double DynamicBlurViewVersionNumber;
13 |
14 | //! Project version string for DynamicBlurView.
15 | FOUNDATION_EXPORT const unsigned char DynamicBlurViewVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Vender/DynamicBlurView/TrackingMode.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TrackingMode.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/17.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | public enum TrackingMode: CustomStringConvertible {
10 | case tracking
11 | case common
12 | case none
13 |
14 | public var description: String {
15 | switch self {
16 | case .tracking:
17 | return RunLoop.Mode.tracking.rawValue
18 | case .common:
19 | return RunLoop.Mode.common.rawValue
20 | case .none:
21 | return ""
22 | }
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Vender/DynamicBlurView/UIImage+Blur.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+Blur.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/11.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | public extension UIImage {
10 | func blurred(radius: CGFloat, iterations: Int, ratio: CGFloat, blendColor color: UIColor?, blendMode mode: CGBlendMode) -> UIImage? {
11 | guard let cgImage = cgImage else {
12 | return nil
13 | }
14 |
15 | if cgImage.area <= 0 || radius <= 0 {
16 | return self
17 | }
18 |
19 | var boxSize = UInt32(radius * scale * ratio)
20 | if boxSize % 2 == 0 {
21 | boxSize += 1
22 | }
23 |
24 | return cgImage.blurred(with: boxSize, iterations: iterations, blendColor: color, blendMode: mode).map {
25 | UIImage(cgImage: $0, scale: scale, orientation: imageOrientation)
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Vender/TableViewDragger/ScrollRects.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScrollRects.swift
3 | // TableViewDragger
4 | //
5 | // Created by Kyohei Ito on 2017/12/08.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import CoreImage
11 |
12 | struct ScrollRects {
13 | private let maxDistance: CGFloat = 10
14 | private let size: CGSize
15 | private let scrollRange: CGFloat
16 |
17 | let topRect: CGRect
18 | let bottomRect: CGRect
19 |
20 | init(size: CGSize) {
21 | self.size = size
22 | scrollRange = size.height / 2.5
23 |
24 | let scrollSize = CGSize(width: size.width, height: scrollRange)
25 | topRect = CGRect(origin: .zero, size: scrollSize)
26 | bottomRect = CGRect(origin: CGPoint(x: 0, y: size.height - scrollRange), size: scrollSize)
27 | }
28 |
29 | func distance(at point: CGPoint) -> CGFloat {
30 | let ratio: CGFloat
31 | if topRect.contains(point) {
32 | ratio = -(scrollRange - point.y)
33 | } else if bottomRect.contains(point) {
34 | ratio = point.y - (size.height - scrollRange)
35 | } else {
36 | ratio = 0
37 | }
38 |
39 | return max(min(ratio / 30, maxDistance), -maxDistance)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/Vender/TableViewDragger/UIScrollViewExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIScrollViewExtension.swift
3 | // Pods
4 | //
5 | // Created by Kyohei Ito on 2015/09/29.
6 | //
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIScrollView {
12 | enum DraggingDirection {
13 | case up
14 | case down
15 | }
16 |
17 | func preferredContentOffset(at point: CGPoint, velocity: CGFloat) -> CGPoint {
18 | let distance = ScrollRects(size: bounds.size).distance(at: point) / velocity
19 | var offset = contentOffset
20 | offset.y += distance
21 |
22 | let topOffset = -contentInset.top
23 | let bottomOffset = contentInset.bottom
24 | let height = floor(contentSize.height) - bounds.size.height
25 |
26 | if offset.y > height + bottomOffset {
27 | offset.y = height + bottomOffset
28 | } else if offset.y < topOffset {
29 | offset.y = topOffset
30 | }
31 |
32 | return offset
33 | }
34 |
35 | func draggingDirection(at point: @autoclosure () -> CGPoint) -> DraggingDirection? {
36 | let contentHeight = floor(contentSize.height)
37 | if bounds.size.height >= contentHeight {
38 | return nil
39 | }
40 |
41 | let rects = ScrollRects(size: bounds.size)
42 | let point = point()
43 |
44 | if rects.topRect.contains(point) {
45 | let topOffset = -contentInset.top
46 | if contentOffset.y > topOffset {
47 | return .up
48 | }
49 | } else if rects.bottomRect.contains(point) {
50 | let bottomOffset = contentHeight + contentInset.bottom - bounds.size.height
51 | if contentOffset.y < bottomOffset {
52 | return .down
53 | }
54 | }
55 |
56 | return nil
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/cute.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoEditor/SimpleVideoEditor/cute.mp4
--------------------------------------------------------------------------------
/Examples/SimpleVideoEditor/SimpleVideoEditor/movie.mov:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoEditor/SimpleVideoEditor/movie.mov
--------------------------------------------------------------------------------
/Examples/SimpleVideoExport/SimpleVideoExport.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoExport/SimpleVideoExport.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoExport/SimpleVideoExport.xcodeproj/xcuserdata/renzhumacro.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | SimpleVideoExport.xcscheme_^#shared#^_
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 6A89623E24B30FAD0083B7AE
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoExport/SimpleVideoExport/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SimpleVideoExport
4 | //
5 | // Created by RenZhu Macro on 2020/7/6.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoExport/SimpleVideoExport/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoExport/SimpleVideoExport/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoExport/SimpleVideoExport/SimpleVideoExport-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Header.h
3 | // SimpleVideoExport
4 | //
5 | // Created by RenZhu Macro on 2020/7/7.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | #import "ProgressHUD.h"
10 | #import "MBProgressHUD.h"
11 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoExport/SimpleVideoExport/UI/ProgressHUD.bundle/progresshud-error@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoExport/SimpleVideoExport/UI/ProgressHUD.bundle/progresshud-error@2x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoExport/SimpleVideoExport/UI/ProgressHUD.bundle/progresshud-success@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoExport/SimpleVideoExport/UI/ProgressHUD.bundle/progresshud-success@2x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/853.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransition/SimpleVideoTransition/853.mp4
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SimpleVideoTransition
4 | //
5 | // Created by RenZhu Macro on 2020/7/2.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/Model/ResourceItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ResourceItem.swift
3 | // SimpleVideoEditor
4 | //
5 | // Created by RenZhu Macro on 2020/7/7.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import MetalVideoProcess
11 |
12 | class ResourceItem: MetalVideoEditorItem {
13 |
14 | public var rotate = 0.0
15 | public var scale = Position(1.0, 1.0)
16 | //translation 为归一化
17 | public var translation = Position(0.0, 0.0)
18 |
19 | var orientation : UIInterfaceOrientation = .portrait
20 | weak var transformFilter: MetalVideoProcessTransformFilter?
21 | weak var currentLayer: MetalVideoProcessBlendFilter?
22 | var roi: CGRect = CGRect.zero
23 | var fillType: MetalVideoProcessTransformFilter.StretchType = .aspectToFill
24 |
25 | var isSelected: Bool = false
26 |
27 | var startTimeText: NSString {
28 | get {
29 | return NSString(format: "%.2f", self.startTime.seconds)
30 | }
31 | }
32 |
33 | var durationText: NSString {
34 | get {
35 | return NSString(format: "%.2f", self.duration.seconds)
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/ResourceItemTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ResourceItemTableViewCell.swift
3 | // SimpleVideoEditor
4 | //
5 | // Created by RenZhu Macro on 2020/7/8.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ResourceItemTableViewCell: UITableViewCell {
12 | @IBOutlet weak var trackIdLabel: UILabel!
13 |
14 | override func awakeFromNib() {
15 | super.awakeFromNib()
16 | // Initialization code
17 | }
18 |
19 | override func setSelected(_ selected: Bool, animated: Bool) {
20 | super.setSelected(selected, animated: animated)
21 |
22 | // Configure the view for the selected state
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/SimpleVideoEditor-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Header.h
3 | // SimpleVideoExport
4 | //
5 | // Created by RenZhu Macro on 2020/7/7.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | #import "ProgressHUD.h"
10 | #import "MBProgressHUD.h"
11 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/Vender/DynamicBlurView/CGContext+CGImage.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CGContext+CGImage.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/17.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | extension CGContext {
10 | static func imageContext(with quality: CaptureQuality, rect: CGRect, opaque: Bool) -> CGContext? {
11 | UIGraphicsBeginImageContextWithOptions(rect.size, opaque, quality.imageScale)
12 | guard let context = UIGraphicsGetCurrentContext() else {
13 | return nil
14 | }
15 |
16 | context.translateBy(x: -rect.origin.x, y: -rect.origin.y)
17 | context.interpolationQuality = quality.interpolationQuality
18 |
19 | return context
20 | }
21 |
22 | func makeImage(with blendColor: UIColor?, blendMode: CGBlendMode, size: CGSize) -> CGImage? {
23 | if let color = blendColor {
24 | setFillColor(color.cgColor)
25 | setBlendMode(blendMode)
26 | fill(CGRect(origin: .zero, size: size))
27 | }
28 |
29 | return makeImage()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/Vender/DynamicBlurView/CaptureQuality.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CaptureQuality.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/17.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | public enum CaptureQuality {
10 | case `default`
11 | case low
12 | case medium
13 | case high
14 |
15 | var imageScale: CGFloat {
16 | switch self {
17 | case .default, .high:
18 | return 0
19 | case .low, .medium:
20 | return 1
21 | }
22 | }
23 |
24 | var interpolationQuality: CGInterpolationQuality {
25 | switch self {
26 | case .default, .low:
27 | return .none
28 | case .medium, .high:
29 | return .default
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/Vender/DynamicBlurView/DynamicBlurView.h:
--------------------------------------------------------------------------------
1 | //
2 | // DynamicBlurView.h
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2015/04/08.
6 | // Copyright (c) 2015年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for DynamicBlurView.
12 | FOUNDATION_EXPORT double DynamicBlurViewVersionNumber;
13 |
14 | //! Project version string for DynamicBlurView.
15 | FOUNDATION_EXPORT const unsigned char DynamicBlurViewVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/Vender/DynamicBlurView/TrackingMode.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TrackingMode.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/17.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | public enum TrackingMode: CustomStringConvertible {
10 | case tracking
11 | case common
12 | case none
13 |
14 | public var description: String {
15 | switch self {
16 | case .tracking:
17 | return RunLoop.Mode.tracking.rawValue
18 | case .common:
19 | return RunLoop.Mode.common.rawValue
20 | case .none:
21 | return ""
22 | }
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/Vender/DynamicBlurView/UIImage+Blur.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+Blur.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/11.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | public extension UIImage {
10 | func blurred(radius: CGFloat, iterations: Int, ratio: CGFloat, blendColor color: UIColor?, blendMode mode: CGBlendMode) -> UIImage? {
11 | guard let cgImage = cgImage else {
12 | return nil
13 | }
14 |
15 | if cgImage.area <= 0 || radius <= 0 {
16 | return self
17 | }
18 |
19 | var boxSize = UInt32(radius * scale * ratio)
20 | if boxSize % 2 == 0 {
21 | boxSize += 1
22 | }
23 |
24 | return cgImage.blurred(with: boxSize, iterations: iterations, blendColor: color, blendMode: mode).map {
25 | UIImage(cgImage: $0, scale: scale, orientation: imageOrientation)
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/Vender/TableViewDragger/ScrollRects.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScrollRects.swift
3 | // TableViewDragger
4 | //
5 | // Created by Kyohei Ito on 2017/12/08.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import CoreImage
11 |
12 | struct ScrollRects {
13 | private let maxDistance: CGFloat = 10
14 | private let size: CGSize
15 | private let scrollRange: CGFloat
16 |
17 | let topRect: CGRect
18 | let bottomRect: CGRect
19 |
20 | init(size: CGSize) {
21 | self.size = size
22 | scrollRange = size.height / 2.5
23 |
24 | let scrollSize = CGSize(width: size.width, height: scrollRange)
25 | topRect = CGRect(origin: .zero, size: scrollSize)
26 | bottomRect = CGRect(origin: CGPoint(x: 0, y: size.height - scrollRange), size: scrollSize)
27 | }
28 |
29 | func distance(at point: CGPoint) -> CGFloat {
30 | let ratio: CGFloat
31 | if topRect.contains(point) {
32 | ratio = -(scrollRange - point.y)
33 | } else if bottomRect.contains(point) {
34 | ratio = point.y - (size.height - scrollRange)
35 | } else {
36 | ratio = 0
37 | }
38 |
39 | return max(min(ratio / 30, maxDistance), -maxDistance)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/Vender/TableViewDragger/UIScrollViewExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIScrollViewExtension.swift
3 | // Pods
4 | //
5 | // Created by Kyohei Ito on 2015/09/29.
6 | //
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIScrollView {
12 | enum DraggingDirection {
13 | case up
14 | case down
15 | }
16 |
17 | func preferredContentOffset(at point: CGPoint, velocity: CGFloat) -> CGPoint {
18 | let distance = ScrollRects(size: bounds.size).distance(at: point) / velocity
19 | var offset = contentOffset
20 | offset.y += distance
21 |
22 | let topOffset = -contentInset.top
23 | let bottomOffset = contentInset.bottom
24 | let height = floor(contentSize.height) - bounds.size.height
25 |
26 | if offset.y > height + bottomOffset {
27 | offset.y = height + bottomOffset
28 | } else if offset.y < topOffset {
29 | offset.y = topOffset
30 | }
31 |
32 | return offset
33 | }
34 |
35 | func draggingDirection(at point: @autoclosure () -> CGPoint) -> DraggingDirection? {
36 | let contentHeight = floor(contentSize.height)
37 | if bounds.size.height >= contentHeight {
38 | return nil
39 | }
40 |
41 | let rects = ScrollRects(size: bounds.size)
42 | let point = point()
43 |
44 | if rects.topRect.contains(point) {
45 | let topOffset = -contentInset.top
46 | if contentOffset.y > topOffset {
47 | return .up
48 | }
49 | } else if rects.bottomRect.contains(point) {
50 | let bottomOffset = contentHeight + contentInset.bottom - bounds.size.height
51 | if contentOffset.y < bottomOffset {
52 | return .down
53 | }
54 | }
55 |
56 | return nil
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/cute.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransition/SimpleVideoTransition/cute.mp4
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransition/SimpleVideoTransition/movie.mov:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransition/SimpleVideoTransition/movie.mov
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/853.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/853.mp4
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // SimpleVideoTransition
4 | //
5 | // Created by RenZhu Macro on 2020/7/2.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 |
15 |
16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
17 | // Override point for customization after application launch.
18 | return true
19 | }
20 |
21 | // MARK: UISceneSession Lifecycle
22 |
23 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
24 | // Called when a new scene session is being created.
25 | // Use this method to select a configuration to create the new scene with.
26 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
27 | }
28 |
29 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
30 | // Called when the user discards a scene session.
31 | // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
32 | // Use this method to release any resources that were specific to the discarded scenes, as they will not return.
33 | }
34 |
35 |
36 | }
37 |
38 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_camera.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "baseline_camera_alt_black_24pt_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "baseline_camera_alt_black_24pt_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "baseline_camera_alt_black_24pt_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | },
23 | "properties" : {
24 | "template-rendering-intent" : "template"
25 | }
26 | }
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_camera.imageset/baseline_camera_alt_black_24pt_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_camera.imageset/baseline_camera_alt_black_24pt_1x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_camera.imageset/baseline_camera_alt_black_24pt_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_camera.imageset/baseline_camera_alt_black_24pt_2x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_camera.imageset/baseline_camera_alt_black_24pt_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_camera.imageset/baseline_camera_alt_black_24pt_3x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_cloud.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "baseline_cloud_black_24pt_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "baseline_cloud_black_24pt_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "baseline_cloud_black_24pt_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | },
23 | "properties" : {
24 | "template-rendering-intent" : "template"
25 | }
26 | }
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_cloud.imageset/baseline_cloud_black_24pt_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_cloud.imageset/baseline_cloud_black_24pt_1x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_cloud.imageset/baseline_cloud_black_24pt_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_cloud.imageset/baseline_cloud_black_24pt_2x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_cloud.imageset/baseline_cloud_black_24pt_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_cloud.imageset/baseline_cloud_black_24pt_3x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_library.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "baseline_photo_library_black_24pt_1x.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "baseline_photo_library_black_24pt_2x.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "baseline_photo_library_black_24pt_3x.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | },
23 | "properties" : {
24 | "template-rendering-intent" : "template"
25 | }
26 | }
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_library.imageset/baseline_photo_library_black_24pt_1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_library.imageset/baseline_photo_library_black_24pt_1x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_library.imageset/baseline_photo_library_black_24pt_2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_library.imageset/baseline_photo_library_black_24pt_2x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_library.imageset/baseline_photo_library_black_24pt_3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Images.xcassets/gallery_picker_library.imageset/baseline_photo_library_black_24pt_3x.png
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Model/ResourceItem.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ResourceItem.swift
3 | // SimpleVideoEditor
4 | //
5 | // Created by RenZhu Macro on 2020/7/7.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import MetalVideoProcess
11 |
12 | class ResourceItem: MetalVideoEditorItem {
13 |
14 | public var rotate = 0.0
15 | public var scale = Position(1.0, 1.0)
16 | //translation 为归一化
17 | public var translation = Position(0.0, 0.0)
18 |
19 | var orientation : UIInterfaceOrientation = .portrait
20 | weak var transformFilter: MetalVideoProcessTransformFilter?
21 | weak var currentLayer: MetalVideoProcessBlendFilter?
22 | var roi: CGRect = CGRect.zero
23 | var fillType: MetalVideoProcessTransformFilter.StretchType = .aspectToFill
24 |
25 | var isSelected: Bool = false
26 |
27 | var startTimeText: NSString {
28 | get {
29 | return NSString(format: "%.2f", self.startTime.seconds)
30 | }
31 | }
32 |
33 | var durationText: NSString {
34 | get {
35 | return NSString(format: "%.2f", self.duration.seconds)
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/ResourceItemTableViewCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ResourceItemTableViewCell.swift
3 | // SimpleVideoEditor
4 | //
5 | // Created by RenZhu Macro on 2020/7/8.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ResourceItemTableViewCell: UITableViewCell {
12 | @IBOutlet weak var trackIdLabel: UILabel!
13 |
14 | override func awakeFromNib() {
15 | super.awakeFromNib()
16 | // Initialization code
17 | }
18 |
19 | override func setSelected(_ selected: Bool, animated: Bool) {
20 | super.setSelected(selected, animated: animated)
21 |
22 | // Configure the view for the selected state
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/SimpleVideoEditor-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // Header.h
3 | // SimpleVideoExport
4 | //
5 | // Created by RenZhu Macro on 2020/7/7.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | #import "ProgressHUD.h"
10 | #import "MBProgressHUD.h"
11 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Vender/DynamicBlurView/CGContext+CGImage.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CGContext+CGImage.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/17.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | extension CGContext {
10 | static func imageContext(with quality: CaptureQuality, rect: CGRect, opaque: Bool) -> CGContext? {
11 | UIGraphicsBeginImageContextWithOptions(rect.size, opaque, quality.imageScale)
12 | guard let context = UIGraphicsGetCurrentContext() else {
13 | return nil
14 | }
15 |
16 | context.translateBy(x: -rect.origin.x, y: -rect.origin.y)
17 | context.interpolationQuality = quality.interpolationQuality
18 |
19 | return context
20 | }
21 |
22 | func makeImage(with blendColor: UIColor?, blendMode: CGBlendMode, size: CGSize) -> CGImage? {
23 | if let color = blendColor {
24 | setFillColor(color.cgColor)
25 | setBlendMode(blendMode)
26 | fill(CGRect(origin: .zero, size: size))
27 | }
28 |
29 | return makeImage()
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Vender/DynamicBlurView/CaptureQuality.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CaptureQuality.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/17.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | public enum CaptureQuality {
10 | case `default`
11 | case low
12 | case medium
13 | case high
14 |
15 | var imageScale: CGFloat {
16 | switch self {
17 | case .default, .high:
18 | return 0
19 | case .low, .medium:
20 | return 1
21 | }
22 | }
23 |
24 | var interpolationQuality: CGInterpolationQuality {
25 | switch self {
26 | case .default, .low:
27 | return .none
28 | case .medium, .high:
29 | return .default
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Vender/DynamicBlurView/DynamicBlurView.h:
--------------------------------------------------------------------------------
1 | //
2 | // DynamicBlurView.h
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2015/04/08.
6 | // Copyright (c) 2015年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for DynamicBlurView.
12 | FOUNDATION_EXPORT double DynamicBlurViewVersionNumber;
13 |
14 | //! Project version string for DynamicBlurView.
15 | FOUNDATION_EXPORT const unsigned char DynamicBlurViewVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Vender/DynamicBlurView/TrackingMode.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TrackingMode.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/17.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | public enum TrackingMode: CustomStringConvertible {
10 | case tracking
11 | case common
12 | case none
13 |
14 | public var description: String {
15 | switch self {
16 | case .tracking:
17 | return RunLoop.Mode.tracking.rawValue
18 | case .common:
19 | return RunLoop.Mode.common.rawValue
20 | case .none:
21 | return ""
22 | }
23 | }
24 | }
25 |
26 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Vender/DynamicBlurView/UIImage+Blur.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+Blur.swift
3 | // DynamicBlurView
4 | //
5 | // Created by Kyohei Ito on 2017/08/11.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | public extension UIImage {
10 | func blurred(radius: CGFloat, iterations: Int, ratio: CGFloat, blendColor color: UIColor?, blendMode mode: CGBlendMode) -> UIImage? {
11 | guard let cgImage = cgImage else {
12 | return nil
13 | }
14 |
15 | if cgImage.area <= 0 || radius <= 0 {
16 | return self
17 | }
18 |
19 | var boxSize = UInt32(radius * scale * ratio)
20 | if boxSize % 2 == 0 {
21 | boxSize += 1
22 | }
23 |
24 | return cgImage.blurred(with: boxSize, iterations: iterations, blendColor: color, blendMode: mode).map {
25 | UIImage(cgImage: $0, scale: scale, orientation: imageOrientation)
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Vender/TableViewDragger/ScrollRects.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ScrollRects.swift
3 | // TableViewDragger
4 | //
5 | // Created by Kyohei Ito on 2017/12/08.
6 | // Copyright © 2017年 kyohei_ito. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import CoreImage
11 |
12 | struct ScrollRects {
13 | private let maxDistance: CGFloat = 10
14 | private let size: CGSize
15 | private let scrollRange: CGFloat
16 |
17 | let topRect: CGRect
18 | let bottomRect: CGRect
19 |
20 | init(size: CGSize) {
21 | self.size = size
22 | scrollRange = size.height / 2.5
23 |
24 | let scrollSize = CGSize(width: size.width, height: scrollRange)
25 | topRect = CGRect(origin: .zero, size: scrollSize)
26 | bottomRect = CGRect(origin: CGPoint(x: 0, y: size.height - scrollRange), size: scrollSize)
27 | }
28 |
29 | func distance(at point: CGPoint) -> CGFloat {
30 | let ratio: CGFloat
31 | if topRect.contains(point) {
32 | ratio = -(scrollRange - point.y)
33 | } else if bottomRect.contains(point) {
34 | ratio = point.y - (size.height - scrollRange)
35 | } else {
36 | ratio = 0
37 | }
38 |
39 | return max(min(ratio / 30, maxDistance), -maxDistance)
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/Vender/TableViewDragger/UIScrollViewExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // UIScrollViewExtension.swift
3 | // Pods
4 | //
5 | // Created by Kyohei Ito on 2015/09/29.
6 | //
7 | //
8 |
9 | import UIKit
10 |
11 | extension UIScrollView {
12 | enum DraggingDirection {
13 | case up
14 | case down
15 | }
16 |
17 | func preferredContentOffset(at point: CGPoint, velocity: CGFloat) -> CGPoint {
18 | let distance = ScrollRects(size: bounds.size).distance(at: point) / velocity
19 | var offset = contentOffset
20 | offset.y += distance
21 |
22 | let topOffset = -contentInset.top
23 | let bottomOffset = contentInset.bottom
24 | let height = floor(contentSize.height) - bounds.size.height
25 |
26 | if offset.y > height + bottomOffset {
27 | offset.y = height + bottomOffset
28 | } else if offset.y < topOffset {
29 | offset.y = topOffset
30 | }
31 |
32 | return offset
33 | }
34 |
35 | func draggingDirection(at point: @autoclosure () -> CGPoint) -> DraggingDirection? {
36 | let contentHeight = floor(contentSize.height)
37 | if bounds.size.height >= contentHeight {
38 | return nil
39 | }
40 |
41 | let rects = ScrollRects(size: bounds.size)
42 | let point = point()
43 |
44 | if rects.topRect.contains(point) {
45 | let topOffset = -contentInset.top
46 | if contentOffset.y > topOffset {
47 | return .up
48 | }
49 | } else if rects.bottomRect.contains(point) {
50 | let bottomOffset = contentHeight + contentInset.bottom - bounds.size.height
51 | if contentOffset.y < bottomOffset {
52 | return .down
53 | }
54 | }
55 |
56 | return nil
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/ViewController_BASE_17810.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.swift
3 | // SimpleVideoTransition
4 | //
5 | // Created by RenZhu Macro on 2020/7/2.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | class ViewController: UIViewController {
12 |
13 | override func viewDidLoad() {
14 | super.viewDidLoad()
15 | // Do any additional setup after loading the view.
16 | }
17 |
18 |
19 | }
20 |
21 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/cute.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/cute.mp4
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/movie.mov:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransition/movie.mov
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransitionSwitch.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransitionSwitch.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransitionSwitch.xcodeproj/project.xcworkspace/xcuserdata/renzhumacro.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransitionSwitch.xcodeproj/project.xcworkspace/xcuserdata/renzhumacro.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransitionSwitch.xcodeproj/project.xcworkspace/xcuserdata/ruanshengqiang.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Examples/SimpleVideoTransitionSwitch/SimpleVideoTransitionSwitch.xcodeproj/project.xcworkspace/xcuserdata/ruanshengqiang.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Wangrenzhu
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/MetalVideoProcess.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/MetalVideoProcess/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE)
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/MetalVideoProcess/MetalVideoProcess.h:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcess.h
3 | // MetalVideoProcess
4 | //
5 | // Created by RenZhu Macro on 2020/7/2.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for MetalVideoProcess.
12 | FOUNDATION_EXPORT double MetalVideoProcessVersionNumber;
13 |
14 | //! Project version string for MetalVideoProcess.
15 | FOUNDATION_EXPORT const unsigned char MetalVideoProcessVersionString[];
16 |
17 | // In this header, you should import all the public headers of your framework using statements like #import
18 |
19 |
20 |
--------------------------------------------------------------------------------
/MetalVideoProcess/Vender/Editor/Core/Audio/AudioMixer.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AudioMixer.swift
3 | // Cabbage
4 | //
5 | // Created by Vito on 2018/6/30.
6 | // Copyright © 2018 Vito. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 | import Accelerate
11 |
12 | public class AudioMixer {
13 | public static func changeVolume(for bufferList: UnsafeMutablePointer, volume: Float) {
14 | let bufferList = UnsafeMutableAudioBufferListPointer(bufferList)
15 | for bufferIndex in 0...size)
20 | var volume = volume
21 | vDSP_vsmul(floatRawPointer, 1, &volume, floatRawPointer, 1, frameCount)
22 | }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/MetalVideoProcess/Vender/Editor/Core/Audio/AudioProcessingChain.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AudioProcessingChain.swift
3 | // Cabbage
4 | //
5 | // Created by Vito on 2018/6/30.
6 | // Copyright © 2018 Vito. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 |
11 | public protocol AudioProcessingNode: class {
12 | func process(timeRange: CMTimeRange, bufferListInOut: UnsafeMutablePointer)
13 | }
14 |
15 | public class AudioProcessingChain: NSObject, NSCopying {
16 | public var nodes: [AudioProcessingNode] = []
17 |
18 | public func process(timeRange: CMTimeRange, bufferListInOut: UnsafeMutablePointer) {
19 | nodes.forEach { (node) in
20 | node.process(timeRange: timeRange, bufferListInOut: bufferListInOut)
21 | }
22 | }
23 |
24 | // MARK: - NSCopying
25 | public required override init() {
26 | super.init()
27 | }
28 |
29 | public func copy(with zone: NSZone? = nil) -> Any {
30 | let chain = type(of: self).init()
31 | chain.nodes = nodes
32 | return chain
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/MetalVideoProcess/Vender/Editor/Core/Model/VideoTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // VideoTransition.swift
3 | // Cabbage
4 | //
5 | // Created by Vito on 01/03/2018.
6 | // Copyright © 2018 Vito. All rights reserved.
7 | //
8 |
9 | import CoreImage
10 | import CoreMedia
11 |
12 | public protocol VideoTransition: class {
13 | var identifier: String { get }
14 | var duration: CMTime { get }
15 | func renderImage(foregroundImage: CIImage,
16 | backgroundImage: CIImage,
17 | forTweenFactor tween: Float64,
18 | renderSize: CGSize) -> CIImage
19 | }
20 |
21 | open class TransitionDuration: VideoTransition {
22 | public var identifier: String {
23 | return String(describing: self)
24 | }
25 |
26 | open var duration: CMTime
27 |
28 | public init(duration: CMTime = CMTime.zero) {
29 | self.duration = duration
30 | }
31 |
32 | open func renderImage(foregroundImage: CIImage, backgroundImage: CIImage, forTweenFactor tween: Float64, renderSize: CGSize) -> CIImage {
33 | return foregroundImage.composited(over: backgroundImage)
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/MetalVideoProcess/Vender/Editor/Resource/black_empty.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/MetalVideoProcess/Vender/Editor/Resource/black_empty.mp4
--------------------------------------------------------------------------------
/MetalVideoProcess/Vender/Editor/Track/ImageCompositionGroupProvider.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ImageCompositionGroupProvider.swift
3 | // Cabbage
4 | //
5 | // Created by Vito on 2018/10/2.
6 | // Copyright © 2018 Vito. All rights reserved.
7 | //
8 |
9 | import CoreImage
10 | import CoreMedia
11 |
12 | public protocol ImageCompositionProvider: CompositionTimeRangeProvider, VideoCompositionProvider {}
13 |
14 | public class ImageCompositionGroupProvider: VideoCompositionProvider {
15 |
16 | public var passingThroughVideoCompositionProvider: VideoCompositionProvider?
17 | public var imageCompositionProviders: [ImageCompositionProvider] = []
18 |
19 | public func applyEffect(to sourceImage: CIImage, at time: CMTime, renderSize: CGSize) -> CIImage {
20 | var sourceImage = sourceImage
21 |
22 | imageCompositionProviders.forEach { (provider) in
23 | if provider.timeRange.containsTime(time) {
24 | sourceImage = provider.applyEffect(to: sourceImage, at: time, renderSize: renderSize)
25 | }
26 | }
27 |
28 | if let provider = passingThroughVideoCompositionProvider {
29 | sourceImage = provider.applyEffect(to: sourceImage, at: time, renderSize: renderSize)
30 | }
31 |
32 | return sourceImage
33 | }
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/MetalVideoProcess/Vender/Editor/Track/Resource/ImageResource.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ImageResource.swift
3 | // Cabbage
4 | //
5 | // Created by Vito on 2018/7/27.
6 | // Copyright © 2018 Vito. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 | import CoreImage
11 |
12 |
13 | /// Provide a Image as video frame
14 | open class ImageResource: Resource {
15 |
16 | public init(image: CIImage, duration: CMTime) {
17 | super.init()
18 | self.image = image
19 | self.status = .avaliable
20 | self.duration = duration
21 | self.selectedTimeRange = CMTimeRange(start: CMTime.zero, duration: duration)
22 | }
23 |
24 | public init(texture: MTLTexture, duration: CMTime) {
25 | super.init()
26 | self.texture = texture
27 | self.status = .avaliable
28 | self.duration = duration
29 | self.selectedTimeRange = CMTimeRange(start: CMTime.zero, duration: duration)
30 | }
31 |
32 | required public init() {
33 | super.init()
34 | }
35 |
36 | open var texture: MTLTexture? = nil
37 | open var image: CIImage? = nil
38 |
39 | open override func image(at time: CMTime, renderSize: CGSize) -> CIImage? {
40 | return image
41 | }
42 |
43 | open override func sourceTexture(at time: CMTime) -> MTLTexture? {
44 | return texture
45 | }
46 |
47 | // MARK: - NSCopying
48 | open override func copy(with zone: NSZone? = nil) -> Any {
49 | let resource = super.copy(with: zone) as! ImageResource
50 | resource.image = image
51 | return resource
52 | }
53 |
54 | }
55 |
--------------------------------------------------------------------------------
/MetalVideoProcess/Vender/Editor/Uitl/CoreImageExtension.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CoreImageExtension.swift
3 | // Cabbage
4 | //
5 | // Created by Vito on 2018/11/11.
6 | // Copyright © 2018 Vito. All rights reserved.
7 | //
8 |
9 | import Foundation
10 | import CoreImage
11 |
12 | extension CIImage {
13 |
14 | func apply(alpha: CGFloat) -> CIImage {
15 | let filter = CIFilter(name: "CIColorMatrix")
16 | filter?.setDefaults()
17 | filter?.setValue(self, forKey: kCIInputImageKey)
18 | let alphaVector = CIVector.init(x: 0, y: 0, z: 0, w: alpha)
19 | filter?.setValue(alphaVector, forKey: "inputAVector")
20 | if let outputImage = filter?.outputImage {
21 | return outputImage
22 | }
23 | return self
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/MetalVideoProcess/Vender/Render/Base/Color.swift:
--------------------------------------------------------------------------------
1 | public struct Color {
2 | public let redComponent: Float
3 | public let greenComponent: Float
4 | public let blueComponent: Float
5 | public let alphaComponent: Float
6 |
7 | public init(red: Float, green: Float, blue: Float, alpha: Float = 1.0) {
8 | self.redComponent = red
9 | self.greenComponent = green
10 | self.blueComponent = blue
11 | self.alphaComponent = alpha
12 | }
13 |
14 | public static let black = Color(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
15 | public static let white = Color(red: 1.0, green: 1.0, blue: 1.0, alpha: 1.0)
16 | public static let red = Color(red: 1.0, green: 0.0, blue: 0.0, alpha: 1.0)
17 | public static let green = Color(red: 0.0, green: 1.0, blue: 0.0, alpha: 1.0)
18 | public static let blue = Color(red: 0.0, green: 0.0, blue: 1.0, alpha: 1.0)
19 | public static let transparent = Color(red: 0.0, green: 0.0, blue: 0.0, alpha: 0.0)
20 | }
21 |
--------------------------------------------------------------------------------
/MetalVideoProcess/Vender/Render/Base/OperationShaderTypes.h:
--------------------------------------------------------------------------------
1 | //
2 | // OperationShaderTypes.h
3 | // MetalVideoProcess
4 | //
5 | // Created by RenZhu Macro on 2020/4/15.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 | #include
9 | using namespace metal;
10 |
11 | #ifndef OperationShaderTypes_h
12 | #define OperationShaderTypes_h
13 |
14 | // Luminance Constants
15 | constant half3 luminanceWeighting = half3(0.2125, 0.7154, 0.0721); // Values from "Graphics Shaders: Theory and Practice" by Bailey and Cunningham
16 |
17 | struct SingleInputVertexIO
18 | {
19 | float4 position [[position]];
20 | float2 textureCoordinate [[user(texturecoord)]];
21 | };
22 |
23 | struct TwoInputVertexIO
24 | {
25 | float4 position [[position]];
26 | float2 textureCoordinate [[user(texturecoord)]];
27 | float2 textureCoordinate2 [[user(texturecoord2)]];
28 | };
29 |
30 | #endif /* OperationShaderTypes_h */
31 |
--------------------------------------------------------------------------------
/MetalVideoProcess/Vender/Render/Base/Position.swift:
--------------------------------------------------------------------------------
1 | import Foundation
2 |
3 | #if os(iOS)
4 | import UIKit
5 | #endif
6 |
7 | public struct Position {
8 | public let x: Float
9 | public let y: Float
10 | public let z: Float?
11 |
12 | public init (_ x: Float, _ y: Float, _ z: Float? = nil) {
13 | self.x = x
14 | self.y = y
15 | self.z = z
16 | }
17 |
18 | public static let center = Position(0.5, 0.5)
19 | public static let zero = Position(0.0, 0.0)
20 | }
21 |
22 |
23 | public struct Position2D {
24 | public let x: Float
25 | public let y: Float
26 |
27 | public init (_ x: Float, _ y: Float) {
28 | self.x = x
29 | self.y = y
30 | }
31 |
32 | public static let center = Position(0.5, 0.5)
33 | public static let zero = Position(0.0, 0.0)
34 | }
35 |
--------------------------------------------------------------------------------
/MetalVideoProcess/Vender/Render/Base/Size.swift:
--------------------------------------------------------------------------------
1 | public struct Size {
2 | public let width: Float
3 | public let height: Float
4 |
5 | public init(width: Float, height: Float) {
6 | self.width = width
7 | self.height = height
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/MetalVideoProcess/Vender/Render/Inputs/ImageGenerator.swift:
--------------------------------------------------------------------------------
1 | public class ImageGenerator: ImageSource {
2 | public var trackID: Int32
3 |
4 | public func transmitPreviousImage(to target: ImageConsumer, atIndex: UInt, trackID: Int32) {
5 | target.newTextureAvailable(internalTexture,
6 | fromSourceIndex: atIndex,
7 | trackID: trackID)
8 | }
9 |
10 | public var size: Size
11 |
12 | public let targets = TargetContainer()
13 | var internalTexture: Texture!
14 |
15 | public init(size: Size,
16 | trackID: Int32) {
17 | self.size = size
18 | internalTexture = Texture(device: sharedMetalRenderingDevice.device, orientation: .portrait, width: Int(size.width), height: Int(size.height), timingStyle: .stillImage)
19 | self.trackID = trackID
20 | }
21 |
22 | func notifyTargets() {
23 | updateTargetsWithTexture(internalTexture, trackID: self.trackID)
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/MetalVideoProcess/Vender/Render/Inputs/SolidColorGenerator.swift:
--------------------------------------------------------------------------------
1 | public class SolidColorGenerator: ImageGenerator {
2 |
3 | public func renderColor(_ color: Color) {
4 | guard let commandBuffer = sharedMetalRenderingDevice.commandQueue.makeCommandBuffer() else {return}
5 |
6 | commandBuffer.clear(with: color, outputTexture: internalTexture)
7 |
8 | notifyTargets()
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Base/MetalVideoProcessMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by RenZhu Macro on 2020/7/20.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 |
11 | public class MetalVideoProcessMotion: MetalVideoProcessOperation {
12 |
13 | public var factor: Float = 1.0 {
14 | didSet { uniformSettings["factor"] = factor } }
15 |
16 | public var roi: CGRect = CGRect(x: 0.0, y: 0.0, width: 1.0, height: 1.0) {
17 | didSet {
18 | uniformSettings["roi"] = Color(red: Float(roi.origin.x), green: Float(roi.origin.y), blue: Float(roi.width), alpha: Float(roi.height))
19 | }
20 | }
21 |
22 | public var timingType: TimingFunctionType = .linearInterpolation
23 |
24 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
25 |
26 | if self.timelineRange.containsTime(texture.timingStyle.timestamp?.asCMTime ?? CMTime.invalid) {
27 | let distance = CMTime(seconds: texture.frameTime, preferredTimescale: 1000) - self.timelineRange.start
28 | let progress = Float(distance.seconds / self.timelineRange.duration.seconds)
29 | self.factor = self.timingType.timingValue(p: progress)
30 | }
31 |
32 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Base/MetalVideoProcessTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessTransition.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by RenZhu Macro on 2020/7/14.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import Metal
10 | import AVFoundation
11 |
12 | public class MetalVideoProcessTransition: MetalVideoProcessOperation {
13 | //Transition factor
14 | public var tweenFactor: Float = 1.0 { didSet { uniformSettings["tweenFactor"] = tweenFactor } }
15 |
16 | public var timingType: TimingFunctionType = .linearInterpolation
17 |
18 | open var mainTrackIDs: [Int32] = []
19 |
20 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
21 | guard let sourceIndex = mainTrackIDs.firstIndex(of: trackID) else {
22 | updateTargetsWithTexture(texture, trackID: trackID)
23 | return
24 | }
25 |
26 | if self.timelineRange.containsTime(texture.timingStyle.timestamp?.asCMTime ?? CMTime.invalid) {
27 | let distance = CMTime(seconds: texture.frameTime, preferredTimescale: 1000) - self.timelineRange.start
28 | let progress = Float(distance.seconds / self.timelineRange.duration.seconds)
29 | self.tweenFactor = self.timingType.timingValue(p: progress)
30 | super.newTextureAvailable(texture, fromSourceIndex: UInt(sourceIndex), trackID: trackID)
31 | } else {
32 | updateTargetsWithTexture(texture, trackID: trackID)
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Filters/MetalVideoProcessBlendFilter.metal:
--------------------------------------------------------------------------------
1 | #include
2 | using namespace metal;
3 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
4 |
5 | typedef struct
6 | {
7 | float mixturePercent;
8 | float blendMode;
9 | } AlphaBlendUniform;
10 |
11 | fragment half4 alphaBlend(TwoInputVertexIO fragmentInput [[stage_in]],
12 | texture2d inputTexture [[texture(0)]],
13 | texture2d inputTexture2 [[texture(1)]],
14 | constant AlphaBlendUniform& uniform [[ buffer(1) ]])
15 | {
16 |
17 | constexpr sampler quadSampler(mag_filter:: linear,
18 | min_filter:: linear,
19 | address:: clamp_to_zero);
20 |
21 | half4 textureColor = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
22 | constexpr sampler quadSampler2(mag_filter:: linear,
23 | min_filter:: linear,
24 | address:: clamp_to_zero);
25 |
26 | half4 textureColor2 = inputTexture2.sample(quadSampler, fragmentInput.textureCoordinate2);
27 | half4 outputCol = half4(0.0);
28 | switch(int(uniform.blendMode)) {
29 | case 0:
30 | outputCol = textureColor * (1. - textureColor2.a) + textureColor2;//mix(textureColor, textureColor2, textureColor2.a);
31 | break;
32 | case 1:
33 | outputCol = half4(textureColor.rgb * textureColor2.a, textureColor.a * textureColor2.a);
34 | break;
35 | default:
36 | outputCol = mix(textureColor, textureColor2, textureColor2.a);
37 | break;
38 | }
39 | return outputCol;
40 | }
41 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Filters/MetalVideoProcessBlendFilter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessAlphaBlend.swift
3 | // MetalVideoProcessAlphaBlend
4 | // Created by RenZhu Macro on 2020/5/15.
5 | // Copyright © 2020 wangrenzhu Macro. All rights reserved.
6 | //
7 |
8 | import AVFoundation
9 |
10 | public class MetalVideoProcessBlendFilter: MetalVideoProcessOperation {
11 | public var mix: Float = 1.0 { didSet { uniformSettings["mixturePercent"] = mix } }
12 | public var blendMode: Blendmode = .Alpha { didSet {
13 | uniformSettings["blendMode"] = blendMode.rawValue } }
14 |
15 | public enum Blendmode: Float {
16 | case Alpha = 0.0
17 | case Mask = 1.0
18 | }
19 | public var renderSize: CGSize? = nil
20 | public init() {
21 | super.init(fragmentFunctionName: "alphaBlend", numberOfInputs: 2, device: sharedMetalRenderingDevice)
22 | ({mix = 1.0})()
23 | ({blendMode = .Alpha})()
24 | }
25 |
26 | public override func newTextureAvailable(_ inputTexture: Texture, fromSourceIndex: UInt, trackID: Int32) {
27 | self.renderSize = CGSize(width: CGFloat(inputTexture.texture.width), height: CGFloat(inputTexture.texture.height))
28 |
29 | super.newTextureWithSize(inputTexture, fromSourceIndex: fromSourceIndex, renderSize: renderSize!, trackID: trackID)
30 |
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Filters/MetalVideoProcessColorFilter.metal:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessColorFilter.metal
3 | // MetalVideoProcessColorFilter
4 | //
5 | // Created by wangrenzhu Macro on 2020/5/15.
6 | // Copyright © 2020 wangrenzhu Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | #define vec4 float4
14 | #define vec3 float3
15 | #define vec2 float2
16 | #define mat2 float2x2
17 | #define mat3 float3x3
18 |
19 | using namespace metal;
20 |
21 | typedef struct
22 | {
23 | float strength;
24 | float4 color;
25 | } Uniform;
26 |
27 | fragment half4 colorFragment(SingleInputVertexIO fragmentInput [[stage_in]],
28 | texture2d inputTexture [[texture(0)]],
29 | constant Uniform &uniform [[ buffer(1) ]])
30 | {
31 | constexpr sampler textureSampler(mag_filter:: linear,
32 | min_filter:: linear,
33 | address:: clamp_to_zero);
34 | half4 bgCol = inputTexture.sample(textureSampler, fragmentInput.textureCoordinate);
35 |
36 | return mix(bgCol, half4(uniform.color), half(uniform.strength));
37 | }
38 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Filters/MetalVideoProcessColorFilter.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessColorFilter.swift
3 | // MetalVideoProcessColorFilter
4 | //
5 | // Created by wangrenzhu Macro on 2020/5/15.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 |
11 | public class MetalVideoProcessColorFilter: MetalVideoProcessOperation {
12 | public var renderSize: CGSize? = nil
13 |
14 | public var color: Color
15 | {
16 | get {
17 | return uniformSettings["color"]
18 | }
19 | set {
20 | uniformSettings["color"] = newValue
21 | }
22 | }
23 |
24 | public var strength: Float
25 | {
26 | get {
27 | return uniformSettings["strength"]
28 | }
29 | set {
30 | uniformSettings["strength"] = newValue
31 | }
32 | }
33 |
34 | public init() {
35 | super.init(fragmentFunctionName: "colorFragment",
36 | numberOfInputs: 1, device: sharedMetalRenderingDevice)
37 | strength = 1.0
38 | renderSize = MetalVideoProcessBackground.canvasSize
39 | }
40 |
41 | public override func newTextureAvailable(_ inputTexture: Texture, fromSourceIndex: UInt, trackID: Int32) {
42 | renderSize = MetalVideoProcessBackground.canvasSize
43 | super.newTextureWithSize(inputTexture, fromSourceIndex: fromSourceIndex, renderSize: renderSize!, trackID: trackID)
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Filters/MetalVideoProcessLuminance.metal:
--------------------------------------------------------------------------------
1 |
2 | #include
3 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
4 | using namespace metal;
5 |
6 | fragment half4 luminanceFragment(SingleInputVertexIO fragmentInput [[stage_in]],
7 | texture2d inputTexture [[texture(0)]])
8 | {
9 | constexpr sampler quadSampler;
10 | half4 color = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
11 | half luminance = dot(color.rgb, luminanceWeighting);
12 |
13 | return half4(half3(luminance), color.a);
14 | }
15 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Filters/MetalVideoProcessLuminance.swift:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // OrpheusMetalRenderLuminance.swift
4 | // OrpheusMetalRenderLuminance
5 | //
6 | // Created by Ruanshengqiang Macro on 2020/5/15.
7 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
8 | //
9 | import Foundation
10 |
11 | public class MetalVideoProcessLuminance: MetalVideoProcessOperation {
12 | public init() {
13 | super.init(fragmentFunctionName: "luminanceFragment", numberOfInputs: 1, device: sharedMetalRenderingDevice)
14 | }
15 |
16 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
17 |
18 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
19 | }
20 |
21 | }
22 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/MetalVideoProcessPlayer+CompositorDelegate.swift:
--------------------------------------------------------------------------------
1 | // MetalVideoProcessPlayer+CompositorDelegate.swift
2 | // MetalVideoProcessPlayer
3 | //
4 | // Created by RenZhu Macro on 2020/6/11.
5 | // Copyright © 2020 RenZhu Macro. All rights reserved.
6 | //
7 |
8 | import Foundation
9 | import AVFoundation
10 |
11 | extension MetalVideoProcessPlayer: MetalVideoProcessCompositorDelegate {
12 |
13 | public func renderRequest(request: AVAsynchronousVideoCompositionRequest) {
14 | if self.isPlaying {
15 | self.requestCache.addRequest(time: request.compositionTime, request: request)
16 | } else {
17 | self.currentRequest = request
18 | }
19 | }
20 |
21 | public func exportRequest(request: AVAsynchronousVideoCompositionRequest) {
22 | let _ = self.audioEncodingTarget?.renderVideoFramesemaphore.wait(timeout: .distantFuture)
23 | self.videoFrameProcessingQueue.async { [weak self] in
24 | autoreleasepool {
25 | guard let `self` = self else { return }
26 |
27 | //这里开始通过request去纹理并process
28 | debugPrint("export:", request.compositionTime.seconds)
29 | self.process(request: request, newTime: request.compositionTime)
30 |
31 | }
32 | }
33 |
34 |
35 | }
36 |
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessFadeInMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessFadeInMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by RenZhu Macro on 2020/7/21.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessFadeInMotion: MetalVideoProcessMotion {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "fadeInMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .quadraticEaseOut
16 | self.factor = 0.0
17 | }
18 |
19 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
20 | if let time = texture.timingStyle.timestamp?.asCMTime {
21 | if time < timelineRange.start {
22 | factor = 0.0
23 | }
24 | debugPrint("fadein:", factor, " frameTime:", texture.frameTime)
25 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
26 | }
27 | }
28 |
29 |
30 | /// before fade in, we need the texture alpha keep to zero
31 | /// - Parameter texture: texture
32 | /// - Returns: result
33 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
34 | return true
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessFadeOutMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessFadeOutMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by RenZhu Macro on 2020/7/21.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessFadeOutMotion: MetalVideoProcessMotion {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "fadeOutMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .quadraticEaseOut
16 | }
17 | //
18 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
19 | // if let time = texture.timingStyle.timestamp?.asCMTime {
20 | // if time > timelineRange.end {
21 | // factor = 1.0
22 | // }
23 | //
24 | //
25 | // debugPrint("fadeout:", factor, " frameTime:", texture.frameTime)
26 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
27 | // }
28 | }
29 |
30 | /// after fade out, we need the texture alpha keep to zero
31 | /// - Parameter texture: texture
32 | /// - Returns: result
33 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
34 | return true
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessMirrorRotateMotion.metal:
--------------------------------------------------------------------------------
1 | //
2 | // mirrorRotateMotion.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace mirrorRotateMotion {
14 | typedef struct
15 | {
16 | float factor;
17 | float4 roi;
18 | } MotionUniform;
19 |
20 | fragment half4 mirrorRotateMotion(TwoInputVertexIO fragmentInput [[stage_in]],
21 | texture2d inputTexture [[texture(0)]],
22 | texture2d inputTexture2 [[texture(1)]],
23 | constant MotionUniform& uniform [[ buffer(1) ]])
24 | {
25 | constexpr sampler quadSampler(mip_filter::linear, min_filter::linear, mag_filter::linear, address::clamp_to_zero);
26 |
27 | half4 bgCol = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
28 | float2 center = float2(uniform.roi.r + uniform.roi.b * 0.5, uniform.roi.g + uniform.roi.a * 0.5);
29 | float2 uv = fragmentInput.textureCoordinate2;
30 |
31 | float2 tempUv = uv;
32 | float curve = uniform.factor;
33 | half4 outCol = half4(0.0);
34 | if (curve < 0.5) {
35 | tempUv = float2((tempUv.x - center.x) * -(1. + curve * 200.0) + center.x, uv.y);
36 | outCol = inputTexture2.sample(quadSampler, tempUv.xy);
37 | } else {
38 | tempUv = float2((tempUv.x - center.x) * (1. + (1.0 - curve) * 200.0) + center.x, uv.y);
39 | outCol = inputTexture2.sample(quadSampler, tempUv.xy);
40 | }
41 |
42 | return half4(bgCol.rgb * (1. - outCol.a) + outCol.rgb, outCol.a);
43 | }
44 | }
45 |
46 |
47 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessMirrorRotateMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessMirrorRotateMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessMirrorRotateMotion: MetalVideoProcessMotion {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "mirrorRotateMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .linearInterpolation
16 | self.factor = 0.0
17 | }
18 |
19 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
20 | if let time = texture.timingStyle.timestamp?.asCMTime {
21 | if time < timelineRange.start {
22 | factor = 0.0
23 | }
24 |
25 | debugPrint("mirrorRotateMotion:", factor, " frameTime:", texture.frameTime)
26 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
27 | }
28 | }
29 |
30 | /// before fade in, we need the texture alpha keep to zero
31 | /// - Parameter texture: texture
32 | /// - Returns: result
33 |
34 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
35 | return true
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessMoveDownMotion.metal:
--------------------------------------------------------------------------------
1 | //
2 | // moveDownMotion.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace moveDownMotion {
14 | typedef struct
15 | {
16 | float factor;
17 | float4 roi;
18 | } MotionUniform;
19 |
20 | fragment half4 moveDownMotion(TwoInputVertexIO fragmentInput [[stage_in]],
21 | texture2d inputTexture [[texture(0)]],
22 | texture2d inputTexture2 [[texture(1)]],
23 | constant MotionUniform& uniform [[ buffer(1) ]])
24 | {
25 |
26 | constexpr sampler quadSampler(mip_filter::linear, min_filter::linear, mag_filter::linear, address::clamp_to_zero);
27 |
28 | half4 bgCol = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
29 |
30 | float2 uv = fragmentInput.textureCoordinate2;
31 |
32 | half4 fgCol = inputTexture2.sample(quadSampler, uv + float2(0.0, uniform.roi.a) - float2(0.0, uniform.roi.a * uniform.factor));
33 |
34 | return half4(bgCol.rgb * (1. - fgCol.a) + fgCol.rgb, fgCol.a);
35 | }
36 | }
37 |
38 |
39 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessMoveDownMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessMoveDownMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessMoveDownMotion: MetalVideoProcessMotion {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "moveDownMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .quadraticEaseIn
16 | self.factor = 0.0
17 | }
18 |
19 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
20 | if let time = texture.timingStyle.timestamp?.asCMTime {
21 | if time < timelineRange.start {
22 | factor = 0.0
23 | }
24 |
25 | debugPrint("moveUpMotion:", factor, " frameTime:", texture.frameTime)
26 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
27 | }
28 | }
29 |
30 | /// before fade in, we need the texture alpha keep to zero
31 | /// - Parameter texture: texture
32 | /// - Returns: result
33 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
34 | return true
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessMoveLeftMotion.metal:
--------------------------------------------------------------------------------
1 | //
2 | // rotateMotion.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace moveLeftMotion {
14 | typedef struct
15 | {
16 | float factor;
17 | float4 roi;
18 | } MotionUniform;
19 |
20 | fragment half4 moveLeftMotion(TwoInputVertexIO fragmentInput [[stage_in]],
21 | texture2d inputTexture [[texture(0)]],
22 | texture2d inputTexture2 [[texture(1)]],
23 | constant MotionUniform& uniform [[ buffer(1) ]])
24 | {
25 |
26 | constexpr sampler quadSampler(mip_filter::linear, min_filter::linear, mag_filter::linear, address::clamp_to_zero);
27 |
28 | half4 bgCol = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
29 |
30 | float2 uv = fragmentInput.textureCoordinate2;
31 |
32 | half4 fgCol = inputTexture2.sample(quadSampler, uv - float2(uniform.roi.b, 0.0) + float2(uniform.roi.b * uniform.factor, 0.0));
33 |
34 | return half4(bgCol.rgb * (1. - fgCol.a) + fgCol.rgb, fgCol.a);
35 | }
36 | }
37 |
38 |
39 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessMoveLeftMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessMoveLeftMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessMoveLeftMotion: MetalVideoProcessMotion {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "moveLeftMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .linearInterpolation
16 | self.factor = 0.0
17 | }
18 |
19 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
20 | if let time = texture.timingStyle.timestamp?.asCMTime {
21 | if time < timelineRange.start {
22 | factor = 0.0
23 | }
24 |
25 | debugPrint("moveLeftMotion:", factor, " frameTime:", texture.frameTime)
26 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
27 | }
28 | }
29 |
30 | /// before fade in, we need the texture alpha keep to zero
31 | /// - Parameter texture: texture
32 | /// - Returns: result
33 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
34 | return true
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessMoveRightMotion.metal:
--------------------------------------------------------------------------------
1 | //
2 | // moveRightMotion.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace moveRightMotion {
14 | typedef struct
15 | {
16 | float factor;
17 | float4 roi;
18 | } MotionUniform;
19 |
20 | fragment half4 moveRightMotion(TwoInputVertexIO fragmentInput [[stage_in]],
21 | texture2d inputTexture [[texture(0)]],
22 | texture2d inputTexture2 [[texture(1)]],
23 | constant MotionUniform& uniform [[ buffer(1) ]])
24 | {
25 |
26 | constexpr sampler quadSampler(mip_filter::linear, min_filter::linear, mag_filter::linear, address::clamp_to_zero);
27 |
28 | half4 bgCol = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
29 |
30 | float2 uv = fragmentInput.textureCoordinate2;
31 |
32 | half4 fgCol = inputTexture2.sample(quadSampler, uv + float2(uniform.roi.b, 0.0) - float2(uniform.roi.b * uniform.factor, 0.0));
33 |
34 | return half4(bgCol.rgb * (1. - fgCol.a) + fgCol.rgb, fgCol.a);
35 | }
36 | }
37 |
38 |
39 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessMoveRightMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessMoveRightMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessMoveRightMotion: MetalVideoProcessMotion {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "moveRightMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .linearInterpolation
16 | self.factor = 0.0
17 | }
18 |
19 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
20 | if let time = texture.timingStyle.timestamp?.asCMTime {
21 | if time < timelineRange.start {
22 | factor = 0.0
23 | }
24 |
25 | debugPrint("moveLeftMotion:", factor, " frameTime:", texture.frameTime)
26 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
27 | }
28 | }
29 |
30 | /// before fade in, we need the texture alpha keep to zero
31 | /// - Parameter texture: texture
32 | /// - Returns: result
33 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
34 | return true
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessMoveUpMotion.metal:
--------------------------------------------------------------------------------
1 | //
2 | // rotateMotion.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace moveUpMotion {
14 | typedef struct
15 | {
16 | float factor;
17 | float4 roi;
18 | } MotionUniform;
19 |
20 | fragment half4 moveUpMotion(TwoInputVertexIO fragmentInput [[stage_in]],
21 | texture2d inputTexture [[texture(0)]],
22 | texture2d inputTexture2 [[texture(1)]],
23 | constant MotionUniform& uniform [[ buffer(1) ]])
24 | {
25 |
26 | constexpr sampler quadSampler(mip_filter::linear, min_filter::linear, mag_filter::linear, address::clamp_to_zero);
27 |
28 | half4 bgCol = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
29 |
30 | float2 uv = fragmentInput.textureCoordinate2;
31 |
32 | half4 fgCol = inputTexture2.sample(quadSampler, uv - float2(0.0, uniform.roi.a) + float2(0.0, uniform.roi.a * uniform.factor));
33 |
34 | return half4(bgCol.rgb * (1. - fgCol.a) + fgCol.rgb, fgCol.a);
35 | }
36 | }
37 |
38 |
39 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessMoveUpMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessMoveUpMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessMoveUpMotion: MetalVideoProcessMotion {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "moveUpMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .quadraticEaseIn
16 | self.factor = 0.0
17 | }
18 |
19 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
20 | if let time = texture.timingStyle.timestamp?.asCMTime {
21 | if time < timelineRange.start {
22 | factor = 0.0
23 | }
24 |
25 | debugPrint("moveUpMotion:", factor, " frameTime:", texture.frameTime)
26 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
27 | }
28 | }
29 |
30 | /// before fade in, we need the texture alpha keep to zero
31 | /// - Parameter texture: texture
32 | /// - Returns: result
33 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
34 | return true
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessPendulumMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessPendulumMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessPendulumMotion: MetalVideoProcessMotion {
12 |
13 | var iResolution: Position {
14 | set {
15 | uniformSettings["iResolution"] = newValue
16 | }
17 | get {
18 | return uniformSettings["iResolution"]
19 | }
20 | }
21 |
22 | public init() {
23 | super.init(fragmentFunctionName: "pendulumMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
24 | self.timingType = .linearInterpolation
25 | self.factor = 0.0
26 | }
27 |
28 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
29 | if let time = texture.timingStyle.timestamp?.asCMTime {
30 | if time < timelineRange.start {
31 | factor = 0.0
32 | }
33 |
34 | self.iResolution = Position(Float(texture.texture.width), Float(texture.texture.height))
35 | debugPrint("pendulumMotion:", factor, " frameTime:", texture.frameTime)
36 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
37 | }
38 | }
39 |
40 | /// before fade in, we need the texture alpha keep to zero
41 | /// - Parameter texture: texture
42 | /// - Returns: result
43 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
44 | return true
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessRightDropMotion.metal:
--------------------------------------------------------------------------------
1 | //
2 | // pendulumMotion.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 | #define PI 3.1415926
13 | namespace rightDropMotion {
14 | typedef struct
15 | {
16 | float factor;
17 | float4 roi;
18 | float2 iResolution;
19 | } MotionUniform;
20 |
21 | fragment half4 rightDropMotion(TwoInputVertexIO fragmentInput [[stage_in]],
22 | texture2d inputTexture [[texture(0)]],
23 | texture2d inputTexture2 [[texture(1)]],
24 | constant MotionUniform& uniform [[ buffer(1) ]])
25 | {
26 |
27 | constexpr sampler quadSampler(mip_filter::linear, min_filter::linear, mag_filter::linear, address::clamp_to_zero);
28 |
29 | half4 bgCol = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
30 |
31 | float2 center = float2(uniform.roi.r + uniform.roi.b * 0.5, uniform.roi.g);
32 | float time = cos(uniform.factor * PI * 2.5) * exp(-uniform.factor);
33 | float2 uv = fragmentInput.textureCoordinate2 + float2(0.5, 0.0) * time;
34 |
35 | float2 dir = float2(0.1, 0.0) * time;
36 |
37 | half4 fgCol = half4(0.0);
38 | for(float i = 0.0; i < 1.0; i = i + 0.1) {
39 | fgCol += inputTexture2.sample(quadSampler, uv + dir * i);
40 | }
41 |
42 | fgCol /= 10.0;
43 | return half4(bgCol.rgb * (1. - fgCol.a) + fgCol.rgb, fgCol.a);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessRightDropMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessRightDropMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessRightDropMotion: MetalVideoProcessMotion {
12 |
13 | var iResolution: Position {
14 | set {
15 | uniformSettings["iResolution"] = newValue
16 | }
17 | get {
18 | return uniformSettings["iResolution"]
19 | }
20 | }
21 |
22 | public init() {
23 | super.init(fragmentFunctionName: "rightDropMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
24 | self.timingType = .linearInterpolation
25 | self.factor = 0.0
26 | }
27 |
28 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
29 | if let time = texture.timingStyle.timestamp?.asCMTime {
30 | if time < timelineRange.start {
31 | factor = 0.0
32 | }
33 |
34 | self.iResolution = Position(Float(texture.texture.width), Float(texture.texture.height))
35 | debugPrint("rightDropMotion:", factor, " frameTime:", texture.frameTime)
36 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
37 | }
38 | }
39 |
40 | /// before fade in, we need the texture alpha keep to zero
41 | /// - Parameter texture: texture
42 | /// - Returns: result
43 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
44 | return true
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessRotateInRightMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessRotateMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessRotateInRightMotion: MetalVideoProcessMotion {
12 |
13 | var iResolution: Position {
14 | set {
15 | uniformSettings["iResolution"] = newValue
16 | }
17 | get {
18 | return uniformSettings["iResolution"]
19 | }
20 | }
21 |
22 | public init() {
23 | super.init(fragmentFunctionName: "rotateInRightMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
24 | self.timingType = .quadraticEaseOut
25 | self.factor = 0.0
26 | }
27 |
28 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
29 | if let time = texture.timingStyle.timestamp?.asCMTime {
30 | if time < timelineRange.start {
31 | factor = 0.0
32 | }
33 |
34 | self.iResolution = Position(Float(texture.texture.width), Float(texture.texture.height))
35 | debugPrint("rotateMotion:", factor, " frameTime:", texture.frameTime)
36 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
37 | }
38 | }
39 |
40 | /// before fade in, we need the texture alpha keep to zero
41 | /// - Parameter texture: texture
42 | /// - Returns: result
43 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
44 | return true
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessRotateMotion.metal:
--------------------------------------------------------------------------------
1 | //
2 | // rotateMotion.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace rotateMotion {
14 | typedef struct
15 | {
16 | float factor;
17 | float4 roi;
18 | float2 iResolution;
19 |
20 | } MotionUniform;
21 |
22 | fragment half4 rotateMotion(TwoInputVertexIO fragmentInput [[stage_in]],
23 | texture2d inputTexture [[texture(0)]],
24 | texture2d inputTexture2 [[texture(1)]],
25 | constant MotionUniform& uniform [[ buffer(1) ]])
26 | {
27 |
28 | constexpr sampler quadSampler(mip_filter::linear, min_filter::linear, mag_filter::linear, address::clamp_to_zero);
29 | float2 center = float2(uniform.roi.r + uniform.roi.b * 0.5, uniform.roi.g + uniform.roi.a * 0.5);
30 |
31 | half4 bgCol = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
32 |
33 | float2 uv = fragmentInput.textureCoordinate2;
34 |
35 | float rotCorner = uniform.factor * 25.1327408;
36 | float2 rot = float2(cos(rotCorner), sin(rotCorner));
37 |
38 | uv = (uv - center) * uniform.iResolution;
39 | uv = float2(rot.x * uv.x + rot.y * uv.y, -rot.y * uv.x + rot.x * uv.y);
40 | uv = uv / uniform.iResolution + center;
41 |
42 | half4 fgCol = inputTexture2.sample(quadSampler, uv);
43 |
44 | return half4(bgCol.rgb * (1. - fgCol.a) + fgCol.rgb, fgCol.a);
45 | }
46 | }
47 |
48 |
49 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessRotateMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessRotateMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessRotateMotion: MetalVideoProcessMotion {
12 |
13 | var iResolution: Position {
14 | set {
15 | uniformSettings["iResolution"] = newValue
16 | }
17 | get {
18 | return uniformSettings["iResolution"]
19 | }
20 | }
21 |
22 | public init() {
23 | super.init(fragmentFunctionName: "rotateMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
24 | self.timingType = .quadraticEaseOut
25 | self.factor = 0.0
26 | }
27 |
28 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
29 | if let time = texture.timingStyle.timestamp?.asCMTime {
30 | if time < timelineRange.start {
31 | factor = 0.0
32 | }
33 |
34 | self.iResolution = Position(Float(texture.texture.width), Float(texture.texture.height))
35 | debugPrint("rotateMotion:", factor, " frameTime:", texture.frameTime)
36 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
37 | }
38 | }
39 |
40 | /// before fade in, we need the texture alpha keep to zero
41 | /// - Parameter texture: texture
42 | /// - Returns: result
43 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
44 | return true
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessSlimZoomInMotion.metal:
--------------------------------------------------------------------------------
1 | //
2 | // slimZoomInMotion.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace slimZoomInMotion {
14 | typedef struct
15 | {
16 | float factor;
17 | float4 roi;
18 | } MotionUniform;
19 |
20 | fragment half4 slimZoomInMotion(TwoInputVertexIO fragmentInput [[stage_in]],
21 | texture2d inputTexture [[texture(0)]],
22 | texture2d inputTexture2 [[texture(1)]],
23 | constant MotionUniform& uniform [[ buffer(1) ]])
24 | {
25 | constexpr sampler quadSampler(mip_filter::linear, min_filter::linear, mag_filter::linear, address::clamp_to_zero);
26 |
27 | half4 bgCol = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
28 | float2 center = float2(uniform.roi.r + uniform.roi.b * 0.5, uniform.roi.g + uniform.roi.a * 0.5);
29 | float2 uv = fragmentInput.textureCoordinate2;
30 |
31 | half4 fgCol = inputTexture2.sample(quadSampler, (uv - center) * (1.2 - uniform.factor * 0.2) + center);
32 | return half4(bgCol.rgb * (1. - fgCol.a) + fgCol.rgb, fgCol.a);
33 | }
34 | }
35 |
36 |
37 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessSlimZoomInMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessSlimZoomInMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessSlimZoomInMotion: MetalVideoProcessMotion {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "slimZoomInMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .quadraticEaseIn
16 | self.factor = 0.0
17 | }
18 |
19 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
20 | if let time = texture.timingStyle.timestamp?.asCMTime {
21 | if time < timelineRange.start {
22 | factor = 0.0
23 | }
24 |
25 | debugPrint("slimZoomInMotion:", factor, " frameTime:", texture.frameTime)
26 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
27 | }
28 | }
29 |
30 | /// before fade in, we need the texture alpha keep to zero
31 | /// - Parameter texture: texture
32 | /// - Returns: result
33 |
34 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
35 | return true
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessSwirlMotion.metal:
--------------------------------------------------------------------------------
1 | //
2 | // swirlMotion.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace swirlMotion {
14 | typedef struct
15 | {
16 | float factor;
17 | float4 roi;
18 | float2 iResolution;
19 |
20 | } MotionUniform;
21 |
22 | fragment half4 swirlMotion(TwoInputVertexIO fragmentInput [[stage_in]],
23 | texture2d inputTexture [[texture(0)]],
24 | texture2d inputTexture2 [[texture(1)]],
25 | constant MotionUniform& uniform [[ buffer(1) ]])
26 | {
27 |
28 | constexpr sampler quadSampler(mip_filter::linear, min_filter::linear, mag_filter::linear, address::clamp_to_zero);
29 | float2 center = float2(uniform.roi.r + uniform.roi.b * 0.5, uniform.roi.g + uniform.roi.a * 0.5);
30 |
31 | half4 bgCol = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
32 |
33 | float2 uv = fragmentInput.textureCoordinate2;
34 |
35 | float2 tempUv = uv - center;
36 | float theta = atan2(tempUv.y, tempUv.x);
37 | float r = length(tempUv);
38 | theta = theta + r * 20.0 * (1. - uniform.factor);
39 | uv = float2(r * cos(theta), r * sin(theta)) + center;
40 |
41 | half4 fgCol = inputTexture2.sample(quadSampler, uv);
42 |
43 | return half4(bgCol.rgb * (1. - fgCol.a) + fgCol.rgb, fgCol.a);
44 | }
45 | }
46 |
47 |
48 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessSwirlMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessSwirlMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessSwirlMotion: MetalVideoProcessMotion {
12 |
13 | var iResolution: Position {
14 | set {
15 | uniformSettings["iResolution"] = newValue
16 | }
17 | get {
18 | return uniformSettings["iResolution"]
19 | }
20 | }
21 |
22 | public init() {
23 | super.init(fragmentFunctionName: "swirlMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
24 | self.timingType = .quadraticEaseOut
25 | self.factor = 0.0
26 | }
27 |
28 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
29 | if let time = texture.timingStyle.timestamp?.asCMTime {
30 | if time < timelineRange.start {
31 | factor = 0.0
32 | }
33 |
34 | self.iResolution = Position(Float(texture.texture.width), Float(texture.texture.height))
35 | debugPrint("rotateMotion:", factor, " frameTime:", texture.frameTime)
36 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
37 | }
38 | }
39 |
40 | /// before fade in, we need the texture alpha keep to zero
41 | /// - Parameter texture: texture
42 | /// - Returns: result
43 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
44 | return true
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessUpDropMotion.metal:
--------------------------------------------------------------------------------
1 | //
2 | // pendulumMotion.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 | #define PI 3.1415926
13 | namespace upDropMotion {
14 | typedef struct
15 | {
16 | float factor;
17 | float4 roi;
18 | float2 iResolution;
19 | } MotionUniform;
20 |
21 | fragment half4 upDropMotion(TwoInputVertexIO fragmentInput [[stage_in]],
22 | texture2d inputTexture [[texture(0)]],
23 | texture2d inputTexture2 [[texture(1)]],
24 | constant MotionUniform& uniform [[ buffer(1) ]])
25 | {
26 |
27 | constexpr sampler quadSampler(mip_filter::linear, min_filter::linear, mag_filter::linear, address::clamp_to_zero);
28 |
29 | half4 bgCol = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
30 |
31 | float2 center = float2(uniform.roi.r + uniform.roi.b * 0.5, uniform.roi.g);
32 | float time = cos(uniform.factor * PI * 2.5) * exp(-uniform.factor);
33 | float2 uv = fragmentInput.textureCoordinate2 + float2(0.0, 0.5) * time;
34 |
35 | float2 dir = float2(0.0, 0.1) * time;
36 |
37 | half4 fgCol = half4(0.0);
38 | for(float i = 0.0; i < 1.0; i = i + 0.1) {
39 | fgCol += inputTexture2.sample(quadSampler, uv + dir * i);
40 | }
41 |
42 | fgCol /= 10.0;
43 | return half4(bgCol.rgb * (1. - fgCol.a) + fgCol.rgb, fgCol.a);
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessUpDropMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessUpDropMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessUpDropMotion: MetalVideoProcessMotion {
12 |
13 | var iResolution: Position {
14 | set {
15 | uniformSettings["iResolution"] = newValue
16 | }
17 | get {
18 | return uniformSettings["iResolution"]
19 | }
20 | }
21 |
22 | public init() {
23 | super.init(fragmentFunctionName: "upDropMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
24 | self.timingType = .linearInterpolation
25 | self.factor = 0.0
26 | }
27 |
28 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
29 | if let time = texture.timingStyle.timestamp?.asCMTime {
30 | if time < timelineRange.start {
31 | factor = 0.0
32 | }
33 |
34 | self.iResolution = Position(Float(texture.texture.width), Float(texture.texture.height))
35 | debugPrint("upDropMotion:", factor, " frameTime:", texture.frameTime)
36 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
37 | }
38 | }
39 |
40 | /// before fade in, we need the texture alpha keep to zero
41 | /// - Parameter texture: texture
42 | /// - Returns: result
43 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
44 | return true
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessUpMoveInBlurIIMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessUpMoveInBlurIIMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessUpMoveInBlurIIMotion: MetalVideoProcessMotion {
12 |
13 | var iResolution: Position {
14 | set {
15 | uniformSettings["iResolution"] = newValue
16 | }
17 | get {
18 | return uniformSettings["iResolution"]
19 | }
20 | }
21 |
22 | public init() {
23 | super.init(fragmentFunctionName: "upMoveInBlurIIMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
24 | self.timingType = .quadraticEaseOut
25 | self.factor = 0.0
26 | }
27 |
28 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
29 | if let time = texture.timingStyle.timestamp?.asCMTime {
30 | if time < timelineRange.start {
31 | factor = 0.0
32 | }
33 |
34 | self.iResolution = Position(Float(texture.texture.width), Float(texture.texture.height))
35 | debugPrint("upMoveInBlurMotion:", factor, " frameTime:", texture.frameTime)
36 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
37 | }
38 | }
39 |
40 | /// before fade in, we need the texture alpha keep to zero
41 | /// - Parameter texture: texture
42 | /// - Returns: result
43 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
44 | return true
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessUpMoveInBlurMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessUpMoveInBlurMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessUpMoveInBlurMotion: MetalVideoProcessMotion {
12 |
13 | var iResolution: Position {
14 | set {
15 | uniformSettings["iResolution"] = newValue
16 | }
17 | get {
18 | return uniformSettings["iResolution"]
19 | }
20 | }
21 |
22 | public init() {
23 | super.init(fragmentFunctionName: "upMoveInBlurMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
24 | self.timingType = .quadraticEaseOut
25 | self.factor = 0.0
26 | }
27 |
28 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
29 | if let time = texture.timingStyle.timestamp?.asCMTime {
30 | if time < timelineRange.start {
31 | factor = 0.0
32 | }
33 |
34 | self.iResolution = Position(Float(texture.texture.width), Float(texture.texture.height))
35 | debugPrint("upMoveInBlurMotion:", factor, " frameTime:", texture.frameTime)
36 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
37 | }
38 | }
39 |
40 | /// before fade in, we need the texture alpha keep to zero
41 | /// - Parameter texture: texture
42 | /// - Returns: result
43 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
44 | return true
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessWiperMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessUpMoveInBlurIIMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessWiperMotion: MetalVideoProcessMotion {
12 |
13 | var iResolution: Position {
14 | set {
15 | uniformSettings["iResolution"] = newValue
16 | }
17 | get {
18 | return uniformSettings["iResolution"]
19 | }
20 | }
21 |
22 | public init() {
23 | super.init(fragmentFunctionName: "wiperMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
24 | self.timingType = .linearInterpolation
25 | self.factor = 0.0
26 | }
27 |
28 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
29 | if let time = texture.timingStyle.timestamp?.asCMTime {
30 | if time < timelineRange.start {
31 | factor = 0.0
32 | }
33 |
34 | self.iResolution = Position(Float(texture.texture.width), Float(texture.texture.height))
35 | debugPrint("wiperMotion:", factor, " frameTime:", texture.frameTime)
36 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
37 | }
38 | }
39 |
40 | /// before fade in, we need the texture alpha keep to zero
41 | /// - Parameter texture: texture
42 | /// - Returns: result
43 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
44 | return true
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessZoomInBlurMotion.metal:
--------------------------------------------------------------------------------
1 | //
2 | // zoomOutBluMotion.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace zoomInBlurMotion {
14 | typedef struct
15 | {
16 | float factor;
17 | float4 roi;
18 | float2 iResolution;
19 | } MotionUniform;
20 |
21 | fragment half4 zoomInBlurMotion(TwoInputVertexIO fragmentInput [[stage_in]],
22 | texture2d inputTexture [[texture(0)]],
23 | texture2d inputTexture2 [[texture(1)]],
24 | constant MotionUniform& uniform [[ buffer(1) ]])
25 | {
26 |
27 | constexpr sampler quadSampler(mip_filter::linear, min_filter::linear, mag_filter::linear, address::clamp_to_zero);
28 |
29 | half4 bgCol = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
30 |
31 | float2 center = float2(uniform.roi.r + uniform.roi.b * 0.5, uniform.roi.g + uniform.roi.a * 0.5);
32 | float time = clamp(uniform.factor * 2.0, 0.0, 1.0);
33 | float2 uv = fragmentInput.textureCoordinate2;
34 |
35 | uv = (uv - center);
36 | uv = uv * (3.0 - 2.0 * uniform.factor) + center;
37 |
38 | float2 dir = float2(uv - center) * 0.5 * (1. - time);
39 |
40 | half4 fgCol = half4(0.0);
41 | for(float i = 0.0; i < 1.0; i = i + 0.1) {
42 | fgCol += inputTexture2.sample(quadSampler, uv + dir * i);
43 | }
44 |
45 | fgCol /= 10.0;
46 | return half4(bgCol.rgb * (1. - fgCol.a) + fgCol.rgb, fgCol.a);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessZoomInBlurMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessZoomOutBlurMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessZoomInBlurMotion: MetalVideoProcessMotion {
12 |
13 | var iResolution: Position {
14 | set {
15 | uniformSettings["iResolution"] = newValue
16 | }
17 | get {
18 | return uniformSettings["iResolution"]
19 | }
20 | }
21 |
22 | public init() {
23 | super.init(fragmentFunctionName: "zoomInBlurMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
24 | self.timingType = .quadraticEaseOut
25 | self.factor = 0.0
26 | }
27 |
28 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
29 | if let time = texture.timingStyle.timestamp?.asCMTime {
30 | if time < timelineRange.start {
31 | factor = 0.0
32 | }
33 |
34 | self.iResolution = Position(Float(texture.texture.width), Float(texture.texture.height))
35 | debugPrint("zoomInBlurMotion:", factor, " frameTime:", texture.frameTime)
36 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
37 | }
38 | }
39 |
40 | /// before fade in, we need the texture alpha keep to zero
41 | /// - Parameter texture: texture
42 | /// - Returns: result
43 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
44 | return true
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessZoomInMotion.metal:
--------------------------------------------------------------------------------
1 | //
2 | // rotateMotion.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace zoomInMotion {
14 | typedef struct
15 | {
16 | float factor;
17 | float4 roi;
18 | //float2 iResolution;
19 | } MotionUniform;
20 |
21 | fragment half4 zoomInMotion(TwoInputVertexIO fragmentInput [[stage_in]],
22 | texture2d inputTexture [[texture(0)]],
23 | texture2d inputTexture2 [[texture(1)]],
24 | constant MotionUniform& uniform [[ buffer(1) ]])
25 | {
26 |
27 | constexpr sampler quadSampler(mip_filter::linear, min_filter::linear, mag_filter::linear, address::clamp_to_zero);
28 |
29 | half4 bgCol = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
30 | float2 center = float2(uniform.roi.r + uniform.roi.b * 0.5, uniform.roi.g + uniform.roi.a * 0.5);
31 | float2 uv = fragmentInput.textureCoordinate2;
32 |
33 | half4 fgCol = inputTexture2.sample(quadSampler, (uv - center) * (2. - uniform.factor) + center);
34 |
35 | return half4(bgCol.rgb * (1. - fgCol.a) + fgCol.rgb, fgCol.a);
36 | }
37 | }
38 |
39 |
40 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessZoomInMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessMoveInMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessZoomInMotion: MetalVideoProcessMotion {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "zoomInMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .quadraticEaseIn
16 | self.factor = 0.0
17 | }
18 |
19 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
20 | if let time = texture.timingStyle.timestamp?.asCMTime {
21 | if time < timelineRange.start {
22 | factor = 0.0
23 | }
24 |
25 | debugPrint("moveInMotion:", factor, " frameTime:", texture.frameTime)
26 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
27 | }
28 | }
29 |
30 | /// before fade in, we need the texture alpha keep to zero
31 | /// - Parameter texture: texture
32 | /// - Returns: result
33 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
34 | return true
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessZoomOutBlurMotion.metal:
--------------------------------------------------------------------------------
1 | //
2 | // zoomOutBluMotion.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace zoomOutBlurMotion {
14 | typedef struct
15 | {
16 | float factor;
17 | float4 roi;
18 | float2 iResolution;
19 | } MotionUniform;
20 |
21 | fragment half4 zoomOutBlurMotion(TwoInputVertexIO fragmentInput [[stage_in]],
22 | texture2d inputTexture [[texture(0)]],
23 | texture2d inputTexture2 [[texture(1)]],
24 | constant MotionUniform& uniform [[ buffer(1) ]])
25 | {
26 |
27 | constexpr sampler quadSampler(mip_filter::linear, min_filter::linear, mag_filter::linear, address::clamp_to_zero);
28 |
29 | half4 bgCol = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
30 |
31 | float2 center = float2(uniform.roi.r + uniform.roi.b * 0.5, uniform.roi.g + uniform.roi.a * 0.5);
32 | float time = clamp(uniform.factor * 2.0, 0.0, 1.0);
33 | float2 uv = fragmentInput.textureCoordinate2;
34 |
35 | uv = (uv - center);
36 | uv = uv * (0.4 + 0.6 * uniform.factor) + center;
37 |
38 | float2 dir = float2(uv - center) * 0.5 * (1. - time);
39 |
40 | half4 fgCol = half4(0.0);
41 | for(float i = 0.0; i < 1.0; i = i + 0.1) {
42 | fgCol += inputTexture2.sample(quadSampler, uv + dir * i);
43 | }
44 |
45 | fgCol /= 10.0;
46 | return half4(bgCol.rgb * (1. - fgCol.a) + fgCol.rgb, fgCol.a);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessZoomOutBlurMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessZoomOutBlurMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessZoomOutBlurMotion: MetalVideoProcessMotion {
12 |
13 | var iResolution: Position {
14 | set {
15 | uniformSettings["iResolution"] = newValue
16 | }
17 | get {
18 | return uniformSettings["iResolution"]
19 | }
20 | }
21 |
22 | public init() {
23 | super.init(fragmentFunctionName: "zoomOutBlurMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
24 | self.timingType = .quadraticEaseOut
25 | self.factor = 0.0
26 | }
27 |
28 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
29 | if let time = texture.timingStyle.timestamp?.asCMTime {
30 | if time < timelineRange.start {
31 | factor = 0.0
32 | }
33 |
34 | self.iResolution = Position(Float(texture.texture.width), Float(texture.texture.height))
35 | debugPrint("zoomOutBlurMotion:", factor, " frameTime:", texture.frameTime)
36 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
37 | }
38 | }
39 |
40 | /// before fade in, we need the texture alpha keep to zero
41 | /// - Parameter texture: texture
42 | /// - Returns: result
43 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
44 | return true
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessZoomOutMotion.metal:
--------------------------------------------------------------------------------
1 | //
2 | // zoomOutMotion.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace zoomOutMotion {
14 | typedef struct
15 | {
16 | float factor;
17 | float4 roi;
18 | //float2 iResolution;
19 | } MotionUniform;
20 |
21 | fragment half4 zoomOutMotion(TwoInputVertexIO fragmentInput [[stage_in]],
22 | texture2d inputTexture [[texture(0)]],
23 | texture2d inputTexture2 [[texture(1)]],
24 | constant MotionUniform& uniform [[ buffer(1) ]])
25 | {
26 |
27 | constexpr sampler quadSampler(mip_filter::linear, min_filter::linear, mag_filter::linear, address::clamp_to_zero);
28 |
29 | half4 bgCol = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
30 | float2 center = float2(uniform.roi.r + uniform.roi.b * 0.5, uniform.roi.g + uniform.roi.a * 0.5);
31 | float2 uv = fragmentInput.textureCoordinate2;
32 |
33 | half4 fgCol = inputTexture2.sample(quadSampler, (uv - center) * (1. + uniform.factor) + center);
34 |
35 | return half4(bgCol.rgb * (1. - fgCol.a) + fgCol.rgb, fgCol.a);
36 | }
37 | }
38 |
39 |
40 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Motions/MetalVideoProcessZoomOutMotion.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessZoomOutMotion.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/21.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | public class MetalVideoProcessZoomOutMotion: MetalVideoProcessMotion {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "zoomOutMotion", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .quadraticEaseIn
16 | self.factor = 0.0
17 | }
18 |
19 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
20 | if let time = texture.timingStyle.timestamp?.asCMTime {
21 | if time < timelineRange.start {
22 | factor = 0.0
23 | }
24 |
25 | debugPrint("moveInMotion:", factor, " frameTime:", texture.frameTime)
26 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
27 | }
28 | }
29 |
30 | /// before fade in, we need the texture alpha keep to zero
31 | /// - Parameter texture: texture
32 | /// - Returns: result
33 | public override func checkTimelineRange(with texture: Texture) -> (Bool) {
34 | return true
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessBurnTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessBurnTransition.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 |
11 | public class MetalVideoProcessBurnTransition: MetalVideoProcessTransition {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "burnTransition", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .linearInterpolation
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessCircleEraseTransition.metal:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessCircleEraseTransition.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace morph {
14 | #define vec2 float2
15 | #define vec3 float3
16 | #define vec4 float4
17 |
18 | typedef struct
19 | {
20 | float tweenFactor;
21 | float2 iResolution;
22 | } FadeTransitionUniform;
23 |
24 | fragment half4 circleErase(TwoInputVertexIO fragmentInput [[stage_in]],
25 | texture2d inputTexture [[texture(0)]],
26 | texture2d inputTexture2 [[texture(1)]],
27 | constant FadeTransitionUniform& uniform [[ buffer(1) ]])
28 | {
29 |
30 | constexpr sampler quadSampler(mag_filter:: linear,
31 | min_filter:: linear,
32 | address:: clamp_to_zero);
33 | float progress = uniform.tweenFactor;
34 | float2 uv = fragmentInput.textureCoordinate;
35 |
36 | float mProgress = 1.0 - progress;
37 | vec2 resolution = uniform.iResolution;
38 | if(distance(uv * resolution, vec2(0.5,0.5) * resolution) < mProgress * length(resolution) * 0.5)
39 | return inputTexture.sample(quadSampler, uv);
40 | else
41 | return inputTexture2.sample(quadSampler, uv);
42 |
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessCircleEraseTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessCircleEraseTransition.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 |
11 | public class MetalVideoProcessCircleEraseTransition: MetalVideoProcessTransition {
12 | public var iResolution: Size = Size(width: 1, height: 1) { didSet { uniformSettings["iResolution"] = iResolution } }
13 |
14 | public init() {
15 | super.init(fragmentFunctionName: "circleErase", numberOfInputs: 2, device: sharedMetalRenderingDevice)
16 | self.timingType = .linearInterpolation
17 | iResolution = Size(width: 1, height: 1)
18 | }
19 |
20 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
21 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
22 | self.iResolution = Size(width: Float(texture.texture.width), height: Float(texture.texture.height))
23 |
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessCubeTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessCubeTransition.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 |
11 | public class MetalVideoProcessCubeTransition: MetalVideoProcessTransition {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "cubeTransition", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .linearInterpolation
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessEraseDownTransition.metal:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessEraseDownTransition.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | typedef struct
14 | {
15 | float tweenFactor;
16 | } FadeTransitionUniform;
17 |
18 | fragment half4 eraseDownTransition(TwoInputVertexIO fragmentInput [[stage_in]],
19 | texture2d inputTexture [[texture(0)]],
20 | texture2d inputTexture2 [[texture(1)]],
21 | constant FadeTransitionUniform& uniform [[ buffer(1) ]])
22 | {
23 |
24 | constexpr sampler quadSampler(mag_filter:: linear,
25 | min_filter:: linear,
26 | address:: clamp_to_zero);
27 | float2 uv = fragmentInput.textureCoordinate;
28 | half4 input0 = inputTexture.sample(quadSampler, uv);
29 | half4 input1 = inputTexture2.sample(quadSampler, uv);
30 | float process = uniform.tweenFactor;
31 |
32 | float curve0 = process * process;
33 | float curve1 = 3. * curve0 - 2. * curve0 * process;
34 | return mix(input0, input1, step(uv.y, process));
35 | }
36 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessEraseDownTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessEraseDownTransition.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 | ///向下擦除转场
11 | public class MetalVideoProcessEraseDownTransition: MetalVideoProcessTransition {
12 |
13 | required public init() {
14 | super.init(fragmentFunctionName: "eraseDownTransition", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .quadraticEaseOut
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessEraseLeftTransition.metal:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessEraseLeftTransition.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace eraseLeft {
14 | typedef struct
15 | {
16 | float tweenFactor;
17 | } FadeTransitionUniform;
18 |
19 | fragment half4 eraseLeft(TwoInputVertexIO fragmentInput [[stage_in]],
20 | texture2d inputTexture [[texture(0)]],
21 | texture2d inputTexture2 [[texture(1)]],
22 | constant FadeTransitionUniform& uniform [[ buffer(1) ]])
23 | {
24 |
25 | constexpr sampler quadSampler(mag_filter:: linear,
26 | min_filter:: linear,
27 | address:: clamp_to_zero);
28 | float2 uv = fragmentInput.textureCoordinate;
29 | half4 input0 = inputTexture.sample(quadSampler, uv);
30 | half4 input1 = inputTexture2.sample(quadSampler, uv);
31 | float process = uniform.tweenFactor;
32 |
33 | float curve0 = process * process;
34 | float curve1 = 3. * curve0 - 2. * curve0 * process;
35 | return mix(input0, input1, step(1. - uv.x, process));
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessEraseLeftTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessEraseLeftTransition.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 |
11 | public class MetalVideoProcessEraseLeftTransition: MetalVideoProcessTransition {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "eraseLeft", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .linearInterpolation
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessEraseRightTransition.metal:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessEraseRightTransition.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace eraseLeft {
14 | typedef struct
15 | {
16 | float tweenFactor;
17 | } FadeTransitionUniform;
18 |
19 | fragment half4 eraseRight(TwoInputVertexIO fragmentInput [[stage_in]],
20 | texture2d inputTexture [[texture(0)]],
21 | texture2d inputTexture2 [[texture(1)]],
22 | constant FadeTransitionUniform& uniform [[ buffer(1) ]])
23 | {
24 |
25 | constexpr sampler quadSampler(mag_filter:: linear,
26 | min_filter:: linear,
27 | address:: clamp_to_zero);
28 | float2 uv = fragmentInput.textureCoordinate;
29 | half4 input0 = inputTexture.sample(quadSampler, uv);
30 | half4 input1 = inputTexture2.sample(quadSampler, uv);
31 | float process = uniform.tweenFactor;
32 |
33 | float curve0 = process * process;
34 | float curve1 = 3. * curve0 - 2. * curve0 * process;
35 | return mix(input0, input1, step(uv.x, process));
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessEraseRightTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessEraseRightTransition.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 |
11 | public class MetalVideoProcessEraseRightTransition: MetalVideoProcessTransition {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "eraseRight", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .linearInterpolation
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessEraseUpTransition.metal:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessEraseUpTransition.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace eraseUp {
14 | typedef struct
15 | {
16 | float tweenFactor;
17 | } FadeTransitionUniform;
18 |
19 | fragment half4 eraseUpTransition(TwoInputVertexIO fragmentInput [[stage_in]],
20 | texture2d inputTexture [[texture(0)]],
21 | texture2d inputTexture2 [[texture(1)]],
22 | constant FadeTransitionUniform& uniform [[ buffer(1) ]])
23 | {
24 |
25 | constexpr sampler quadSampler(mag_filter:: linear,
26 | min_filter:: linear,
27 | address:: clamp_to_zero);
28 | float2 uv = fragmentInput.textureCoordinate;
29 | half4 input0 = inputTexture.sample(quadSampler, uv);
30 | half4 input1 = inputTexture2.sample(quadSampler, uv);
31 | float process = uniform.tweenFactor;
32 |
33 | float curve0 = process * process;
34 | float curve1 = 3. * curve0 - 2. * curve0 * process;
35 | return mix(input0, input1, step(1. - uv.y, process));
36 | }
37 |
38 | }
39 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessEraseUpTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessEraseUpTransition.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 |
11 | public class MetalVideoProcessEraseUpTransition: MetalVideoProcessTransition {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "eraseUpTransition", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .linearInterpolation
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessFadeTransition.metal:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessFadeTransition.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | typedef struct
14 | {
15 | float tweenFactor;
16 | } FadeTransitionUniform;
17 |
18 | fragment half4 fadeTransition(TwoInputVertexIO fragmentInput [[stage_in]],
19 | texture2d inputTexture [[texture(0)]],
20 | texture2d inputTexture2 [[texture(1)]],
21 | constant FadeTransitionUniform& uniform [[ buffer(1) ]])
22 | {
23 |
24 | constexpr sampler quadSampler;
25 | half4 textureColor = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
26 | constexpr sampler quadSampler2;
27 | half4 textureColor2 = inputTexture2.sample(quadSampler, fragmentInput.textureCoordinate2);
28 |
29 | return half4(mix(textureColor.rgb, textureColor2.rgb, textureColor2.a * half(uniform.tweenFactor)), textureColor.a);
30 | }
31 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessFadeTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessFadeTransition.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 RenZhu Macro. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 |
11 | public class MetalVideoProcessFadeTransition: MetalVideoProcessTransition {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "fadeTransition", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .quadraticEaseOut
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessMirrorRotateTransition.metal:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessMirrorRotateTransition.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | typedef struct
14 | {
15 | float tweenFactor;
16 | } FadeTransitionUniform;
17 |
18 | fragment half4 mirrorRotateTransition(TwoInputVertexIO fragmentInput [[stage_in]],
19 | texture2d inputTexture [[texture(0)]],
20 | texture2d inputTexture2 [[texture(1)]],
21 | constant FadeTransitionUniform& uniform [[ buffer(1) ]])
22 | {
23 |
24 | constexpr sampler quadSampler(mag_filter:: linear,
25 | min_filter:: linear,
26 | address:: clamp_to_zero);
27 | float2 uv = fragmentInput.textureCoordinate;
28 |
29 | float process = uniform.tweenFactor;
30 |
31 | float curve0 = process * process;
32 | float curve1 = 3. * curve0 - 2. * curve0 * process;
33 | float2 tempUv = uv;
34 |
35 | half4 outCol = half4(0.0);
36 | if (curve1 < 0.5) {
37 | tempUv = float2((tempUv.x - 0.5) * (1. + curve1 * 100.0) + 0.5, uv.y);
38 | outCol = inputTexture.sample(quadSampler, tempUv.xy);
39 | } else {
40 | tempUv = float2((tempUv.x - 0.5) * (1. + (1.0 - curve1) * 100.0) + 0.5, uv.y);
41 | outCol = inputTexture2.sample(quadSampler, tempUv.xy);
42 | }
43 |
44 | return outCol;
45 | }
46 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessMirrorRotateTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessMirrorRotateTransition.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 | ///镜像翻转转场
11 | public class MetalVideoProcessMirrorRotateTransition: MetalVideoProcessTransition {
12 |
13 | required public init() {
14 | super.init(fragmentFunctionName: "mirrorRotateTransition", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 |
16 | self.timingType = .linearInterpolation
17 |
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessMorphTransition.metal:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessEraseRightTransition.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace morph {
14 | #define vec2 float2
15 | #define vec3 float3
16 | #define vec4 float4
17 |
18 | typedef struct
19 | {
20 | float tweenFactor;
21 | } FadeTransitionUniform;
22 |
23 | constant float strength=0.1;
24 |
25 | fragment half4 morph(TwoInputVertexIO fragmentInput [[stage_in]],
26 | texture2d inputTexture [[texture(0)]],
27 | texture2d inputTexture2 [[texture(1)]],
28 | constant FadeTransitionUniform& uniform [[ buffer(1) ]])
29 | {
30 |
31 | constexpr sampler quadSampler(mag_filter:: linear,
32 | min_filter:: linear,
33 | address:: clamp_to_zero);
34 | float progress = uniform.tweenFactor;
35 | float2 uv = fragmentInput.textureCoordinate;
36 | vec2 p = uv;
37 |
38 | vec4 ca = vec4(inputTexture.sample(quadSampler, p));
39 | vec4 cb = vec4(inputTexture2.sample(quadSampler, p));
40 |
41 | vec2 oa = (((ca.rg + ca.b) * 0.5) * 2.0 - 1.0);
42 | vec2 ob = (((cb.rg + cb.b) * 0.5) * 2.0 - 1.0);
43 | vec2 oc = mix(oa,ob,0.5) * strength;
44 | // float progress = clamp(timer, 0.0, 1.0);
45 | float w0 = progress;
46 | float w1 = 1.0 - w0;
47 |
48 | return mix(inputTexture.sample(quadSampler, p + oc * w0), inputTexture2.sample(quadSampler, p - oc * w1), progress);
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessMorphTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessEraseRightTransition.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 |
11 | public class MetalVideoProcessMorphTransition: MetalVideoProcessTransition {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "morph", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .linearInterpolation
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessReflectTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessReflectTransition.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 | ///向下擦除转场
11 | public class MetalVideoProcessReflectTransition: MetalVideoProcessTransition {
12 |
13 | public init() {
14 | super.init(fragmentFunctionName: "reflectTransition", numberOfInputs: 2, device: sharedMetalRenderingDevice)
15 | self.timingType = .linearInterpolation
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessShanBaiTransition.metal:
--------------------------------------------------------------------------------
1 | #include
2 | using namespace metal;
3 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
4 |
5 | typedef struct
6 | {
7 | float tweenFactor;
8 | } FadeTransitionUniform;
9 |
10 | fragment half4 shanBai(TwoInputVertexIO fragmentInput [[stage_in]],
11 | texture2d inputTexture [[texture(0)]],
12 | texture2d inputTexture2 [[texture(1)]],
13 | constant FadeTransitionUniform& uniform [[ buffer(1) ]])
14 | {
15 |
16 | constexpr sampler quadSampler(mag_filter:: linear,
17 | min_filter:: linear,
18 | address:: clamp_to_zero);
19 |
20 | half4 moveInText = inputTexture.sample(quadSampler, fragmentInput.textureCoordinate);
21 |
22 | half4 moveOutTex = inputTexture2.sample(quadSampler, fragmentInput.textureCoordinate2);
23 | float curve = 0.0;
24 | half4 outputTex = moveInText;
25 |
26 | float process = uniform.tweenFactor * 2.0;
27 | if (process < 1.0) {
28 | curve = process;
29 | outputTex = half4(moveInText.rgb + curve, moveInText.a);
30 | } else {
31 | curve = 2.0 - process;
32 | outputTex = half4(moveOutTex.rgb + curve, moveOutTex.a);
33 | }
34 | return outputTex;
35 | }
36 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessShanBaiTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessShanBai.swift
3 | // MetalVideoProcessShanBai
4 | // Created by Ruanshengqiang Macro on 2020/5/15.
5 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
6 | //
7 | import AVFoundation
8 | /// 闪白转场
9 | public class MetalVideoProcessShanBaiTransition: MetalVideoProcessTransition {
10 | public var renderSize: CGSize? = nil
11 | public init() {
12 | super.init(fragmentFunctionName: "shanBai", numberOfInputs: 2, device: sharedMetalRenderingDevice)
13 | }
14 |
15 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
16 | if self.timelineRange.containsTime(texture.timingStyle.timestamp?.asCMTime ?? CMTime.invalid) {
17 | let distance = CMTime(seconds: texture.frameTime, preferredTimescale: 1000) - self.timelineRange.start
18 | let progress = distance.seconds / self.timelineRange.duration.seconds
19 | self.tweenFactor = TimingFunctionFactory.quadraticEaseOut(p: Float(progress))
20 | }
21 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessVerticalUpGlitchTransition.metal:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessVerticalGlitchTransition.metal
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | #include
10 | using namespace metal;
11 | #include "../../Vender/Render/Base/OperationShaderTypes.h"
12 |
13 | namespace morph {
14 | #define vec2 float2
15 | #define vec3 float3
16 | #define vec4 float4
17 |
18 | typedef struct
19 | {
20 | float tweenFactor;
21 | float2 iResolution;
22 | } FadeTransitionUniform;
23 |
24 | float easeInOutQuint(float t)
25 | {
26 | return t < 0.5 ? 16.0 * t * t * t * t * t : 1.0 + 16.0 * (--t) * t * t * t * t;
27 | }
28 |
29 | void main() {
30 |
31 | }
32 |
33 |
34 | fragment half4 verticalupGlitch(TwoInputVertexIO fragmentInput [[stage_in]],
35 | texture2d inputTexture [[texture(0)]],
36 | texture2d inputTexture2 [[texture(1)]],
37 | constant FadeTransitionUniform& uniform [[ buffer(1) ]])
38 | {
39 |
40 | constexpr sampler quadSampler(mag_filter:: linear,
41 | min_filter:: linear,
42 | address:: clamp_to_zero);
43 | float progress = uniform.tweenFactor;
44 | float2 uv = fragmentInput.textureCoordinate;
45 | vec2 resolution = uniform.iResolution;
46 |
47 | float mProgress = 1.0 - easeInOutQuint(progress);
48 | if(uv.y < mProgress)
49 | return inputTexture.sample(quadSampler, uv + vec2(0.0, 1.0 - mProgress));
50 | else
51 | return inputTexture2.sample(quadSampler, uv - vec2(0.0, mProgress));
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/MetalVideoProcess/VideoProcess/Transitions/MetalVideoProcessVerticalUpGlitchTransition.swift:
--------------------------------------------------------------------------------
1 | //
2 | // MetalVideoProcessVerticalGlitchTransition.swift
3 | // MetalVideoProcess
4 | //
5 | // Created by Ruanshengqiang Macro on 2020/7/16.
6 | // Copyright © 2020 Ruanshengqiang Macro. All rights reserved.
7 | //
8 |
9 | import AVFoundation
10 |
11 | public class MetalVideoProcessVerticalUpGlitchTransition: MetalVideoProcessTransition {
12 | public var iResolution: Size = Size(width: 1, height: 1) { didSet { uniformSettings["iResolution"] = iResolution } }
13 |
14 | public init() {
15 | super.init(fragmentFunctionName: "verticalupGlitch", numberOfInputs: 2, device: sharedMetalRenderingDevice)
16 | self.timingType = .linearInterpolation
17 | iResolution = Size(width: 1, height: 1)
18 | }
19 |
20 | public override func newTextureAvailable(_ texture: Texture, fromSourceIndex: UInt, trackID: Int32) {
21 | super.newTextureAvailable(texture, fromSourceIndex: fromSourceIndex, trackID: trackID)
22 | self.iResolution = Size(width: Float(texture.texture.width), height: Float(texture.texture.height))
23 |
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Readme/Layer.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Readme/Layer.png
--------------------------------------------------------------------------------
/Readme/videoTransitionDesign.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GhostZephyr/MetalVideoProcess/3e298925f6edc2fcf8c91cd90fa34729afaaabea/Readme/videoTransitionDesign.png
--------------------------------------------------------------------------------