如何在 iOS 中将一个视频叠加到另一个视频上?

问题描述 投票:0回答:2

我正在尝试在 iOS 中将已拍摄的视频裁剪成一个圆圈。我该怎么做呢?我知道如何使用 AVCaptureSession 来做到这一点,但我不知道将已拍摄的视频作为 AVCaptureDevice 传递?有没有办法将视频裁剪成圆形。我想将其叠加在另一个视频之上,因此它也必须具有透明背景。谢谢。

ios avfoundation crop video-processing
2个回答
20
投票

我猜你想制作这样的东西:

您不需要

AVCaptureSession
,因为您没有捕捉视频。你想要一个
AVMutableComposition
。您需要阅读AV Foundation 编程指南“编辑”部分。以下是您需要执行的操作的摘要:

  1. 为您的视频创建

    AVAsset
    对象并等待它们加载轨道。

  2. 创建一个

    AVMutableComposition

  3. 为每个输入视频的合成添加单独的

    AVMutableCompositionTrack
    。确保为每个轨道分配明确的、不同的轨道 ID。如果您让系统选择,它将为每个轨道使用 ID 1,并且您稍后将无法在合成器中访问这两个轨道。

  4. 创建一个

    AVMutableVideoComposition

  5. 创建一个

    AVMutableVideoCompositionInstruction

  6. 对于每个输入视频,创建一个

    AVMutableVideoCompositionLayerInstruction
    并显式分配您在步骤 3 中使用的轨道 ID。

  7. AVMutableVideoCompositionInstruction
    layerInstructions
    设置为您在步骤 6 中创建的两层指令。

  8. AVMutableVideoComposition
    instructions
    设置为您在步骤 5 中创建的指令。

  9. 创建一个实现

    AVVideoCompositing
    协议的类。将视频合成(在步骤 4 中创建)的
    customVideoCompositorClass
    设置为此自定义类(例如
    videoComposition.customVideoCompositorClass = [CustomVideoCompositor class];
    )。

  10. 在您的自定义合成器中,从

    AVAsynchronousVideoCompositionRequest
    获取输入像素缓冲区,并使用它们来绘制复合帧(包含由前景视频帧的圆形块覆盖的背景视频帧)。您可以随心所欲地执行此操作。我使用 Core Graphics 完成此操作,因为这很简单,但您可能希望使用 OpenGL(或 Metal)来提高生产应用程序的效率。如果您使用 OpenGL,请务必指定
    kCVPixelBufferOpenGLESCompatibilityKey

  11. 使用步骤 1 中的构图创建

    AVAssetExportSession

  12. 设置会话的输出 URL 和文件类型。

  13. 将会话的

    videoComposition
    设置为步骤 4 中的视频合成。

  14. 告诉会议

    exportAsynchronouslyWithCompletionHandler:
    。可能会很慢!

您可以在这个 github 存储库中找到我的测试项目


0
投票

快速视频叠加

您有以下选择:

    使用
  1. AVMutableVideoComposition. animationTool
     添加额外的叠加(图像、动画)。实际上,这是一种后期处理,会在您的视频中添加额外的叠加层
向视频添加角点:

func applyCornersAsOverlayToComposition( composition: AVMutableVideoComposition, coverViewFrameSize: CGSize ) { //set up the parent layer let parentLayer = CALayer() //apply corners parentLayer.masksToBounds = true parentLayer.cornerRadius = CollagePresenter.containerViewCornerRadius let videoLayer = CALayer() parentLayer.frame = CGRectMake(0, 0, coverViewFrameSize.width, coverViewFrameSize.height) videoLayer.frame = CGRectMake(0, 0, coverViewFrameSize.width, coverViewFrameSize.height) //priority is important to make an overlay parentLayer.addSublayer(videoLayer) let animationTool = AVVideoCompositionCoreAnimationTool(postProcessingAsVideoLayer: videoLayer, in: parentLayer) composition.animationTool = animationTool }

    使用
  1. AVMutableVideoComposition.instructions
    AVMutableVideoCompositionLayerInstruction
     重叠多个视频。它允许您转换视频(旋转、平移、缩放...)并组合多个视频
private func foo( videoAsset1: AVURLAsset, videoAsset2: AVURLAsset ) { let composition = AVMutableComposition() let trackVideo1 = videoAsset1.tracks(withMediaType: .video)[0] let trackVideo2 = videoAsset2.tracks(withMediaType: .video)[0] let videoTrack1 = composition.addMutableTrack( withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid )! let videoTrack2 = composition.addMutableTrack( withMediaType: .video, preferredTrackID: kCMPersistentTrackID_Invalid )! try! videoTrack1.insertTimeRange( CMTimeRangeMake(start: CMTime.zero, duration: videoAsset1.duration), of: trackVideo1, at: CMTime.zero ) try! videoTrack2.insertTimeRange( CMTimeRangeMake(start: CMTime.zero, duration: videoAsset2.duration), of: trackVideo1, at: CMTime.zero ) let transform1 = CGAffineTransform(scaleX: 0.1, y: 0.1) .concatenating(CGAffineTransform(rotationAngle: 0)) .concatenating( CGAffineTransformMakeTranslation( 0, 0 ) ) let transform2 = CGAffineTransform(scaleX: 0.2, y: 0.2) .concatenating(CGAffineTransform(rotationAngle: 0)) .concatenating( CGAffineTransformMakeTranslation( 2, 2 ) ) let layerInstruction1 = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack1) layerInstruction1.setTransform( transform1, at: CMTime.zero ) let layerInstruction2 = AVMutableVideoCompositionLayerInstruction(assetTrack: videoTrack2) layerInstruction2.setTransform( transform2, at: CMTime.zero ) let mainInstruction = AVMutableVideoCompositionInstruction() mainInstruction.backgroundColor = UIColor.yellow.cgColor //Max duration mainInstruction.timeRange = CMTimeRangeMake( start: CMTime.zero, duration: max(videoAsset1.duration, videoAsset2.duration) ) mainInstruction.layerInstructions = [layerInstruction1, layerInstruction2] let videoComposition = AVMutableVideoComposition() videoComposition.renderSize = CGSize(width: 1920, height: 1080) videoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30) videoComposition.instructions = [mainInstruction] }

    使用
  1. AVMutableVideoComposition.customVideoCompositorClass 使用自定义指令重叠多个视频
let videoComposition = AVMutableVideoComposition() videoComposition.renderSize = CGSize(width: 1920, height: 1080) videoComposition.frameDuration = CMTimeMake(value: 1, timescale: 30) //every frame processing videoComposition.customVideoCompositorClass = CustomCompositor.self let customOverlayInstruction = CustomOverlayInstruction( timeRange: CMTimeRangeMake( start: CMTime.zero, duration: videoAsset.duration ), videoEntries: videoEntries ) videoComposition.instructions = [customOverlayInstruction]
    
© www.soinside.com 2019 - 2024. All rights reserved.