【问题标题】:How to crop a video recorded given by AVCaptureMovieFileOutput?如何裁剪由 AVCaptureMovieFileOutput 录制的视频?
【发布时间】:2020-08-10 11:27:52
【问题描述】:

我制作了 CustomCamera,它将视频录制到全屏(通过将 AVCaptureVideoPreviewLayer 的 videoGravity 设置为 resizeAspectFill)并使用 AVCaptureMovieFileOutput 保存录制。录制效果很好,但是当我将录制的视频保存到图库时,它没有全屏播放。它的顶部和底部都有黑条。因此,在录制时,由于 resizeAspectFill,它会以全屏显示,但在导出视频后,会在没有任何转换的情况下导出视频,因此它会按照录制的比例播放(我猜)。 我尝试使视频导出全屏的代码如下,但它不起作用。

func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
if let err = error as NSError?, err.code != -11810 { //-11810 = recording stopped when timelimit reached
    print("Error recording movie: \(err)")
} else {
    let videoAsset: AVAsset = AVAsset( url: outputFileURL )
    guard let clipVideoTrack = videoAsset.tracks( withMediaType: AVMediaType.video ).first as AVAssetTrack? else {
        
        return
    }
    
    let videoComposition = AVMutableVideoComposition(propertiesOf: videoAsset)

    let instruction = AVMutableVideoCompositionInstruction()
    instruction.timeRange = clipVideoTrack.timeRange
    
     let transformer = AVMutableVideoCompositionLayerInstruction( assetTrack: clipVideoTrack)
    transformer.setTransform(videoPreviewLayer.affineTransform(), at: .zero) // This is the transform value of AVCaptureVideoPreviewLayer
    print("clipVideoTrack size: \(clipVideoTrack.naturalSize)")
    
    instruction.layerInstructions = [transformer]
    videoComposition.instructions = [instruction]
    
    let outputPath = "\(NSTemporaryDirectory())\(UUID().uuidString).mov"
    let croppedOutputFileUrl = URL(fileURLWithPath: outputPath)
    
    let exporter = AVAssetExportSession(asset: videoAsset, presetName: AVAssetExportPresetHighestQuality)!
    exporter.videoComposition = videoComposition
    exporter.outputURL = croppedOutputFileUrl
    exporter.outputFileType = .mov
    exporter.shouldOptimizeForNetworkUse = true
    exporter.canPerformMultiplePassesOverSourceMediaData = true
    
    exporter.exportAsynchronously( completionHandler: { () -> Void in
        if let error = exporter.error {
            print("Error in exporting: \(error)")
        }
        if exporter.status == .completed {
            print("exported successfully")
        }
        DispatchQueue.main.async(execute: {
            if let url = exporter.outputURL {
                print("exported file url: \(url)")
            } else {
            }
            
        })
    })
}
}

【问题讨论】:

    标签: swift video-processing avassetexportsession avcapturemoviefileoutput


    【解决方案1】:

    录制的视频尺寸取决于您的会话sessionPreset

    captureSession.sessionPreset = AVCaptureSession.Preset.vga640x480 // and many others 
    

    它与选择播放视频的当前方面无关

    【讨论】:

    • 那么,我如何根据设备决定预设,以便录制的视频在该特定设备上全屏播放? (另外我想告诉你,我正在尝试开发类似视频录制的snapchat)感谢您的回复
    【解决方案2】:

    我发现使用 AVCaptureMovieFileOutput 很难更改录制视频的分辨率,并且裁剪带来了很多挑战。所以,最后我决定试一试 AVCaptureVideoDataOutput,它就像一个魅力。我能够全屏录制视频,以及当 AVCaptureVideoDataOutput 生成最终视频时,它在视频录制过程中看起来完全一样。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-07
      • 2011-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-09
      • 1970-01-01
      相关资源
      最近更新 更多