使用 AVFoundation 裁剪 AVAsset 视频不工作 iOS 8

Posted

技术标签:

【中文标题】使用 AVFoundation 裁剪 AVAsset 视频不工作 iOS 8【英文标题】:Cropping AVAsset video with AVFoundation not working iOS 8 【发布时间】:2015-03-19 22:19:19 【问题描述】:

这一直困扰着我最后一天,我曾经在 ObjC 中使用这种方法将视频裁剪成正方形,这似乎是我几年来发现的唯一有效但最近尝试裁剪后的方法在 Swift 和 ios 8 中使用它似乎根本没有裁剪视频,希望有人可以帮忙?

func captureOutput(captureOutput: AVCaptureFileOutput!, didFinishRecordingToOutputFileAtURL outputFileURL: NSURL!, fromConnections connections: [AnyObject]!, error: NSError!) 
    if error != nil 
        println("Error Outputting recording")
     else 
        self.writeVideoToAssetsLibrary(self.outputUrl!.copy() as NSURL)
    


func writeVideoToAssetsLibrary(videoUrl: NSURL) 
    var videoAsset: AVAsset = AVAsset.assetWithURL(videoUrl) as AVAsset

    var clipVideoTrack = videoAsset.tracksWithMediaType(AVMediaTypeVideo).first as AVAssetTrack

    var composition = AVMutableComposition()
    composition.addMutableTrackWithMediaType(AVMediaTypeVideo, preferredTrackID: CMPersistentTrackID())

    var videoComposition = AVMutableVideoComposition()

    videoComposition.renderSize = CGSizeMake(clipVideoTrack.naturalSize.height, clipVideoTrack.naturalSize.height)
    videoComposition.frameDuration = CMTimeMake(1, 30)


    var transformer = AVMutableVideoCompositionLayerInstruction(assetTrack: clipVideoTrack)

    var instruction = AVMutableVideoCompositionInstruction()
    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30))

    var transform1: CGAffineTransform = CGAffineTransformMakeTranslation(clipVideoTrack.naturalSize.height, (clipVideoTrack.naturalSize.width - clipVideoTrack.naturalSize.height) / 2)
    var transform2 = CGAffineTransformRotate(transform1, CGFloat(M_PI_2))
    var finalTransform = transform2


    transformer.setTransform(finalTransform, atTime: kCMTimeZero)

    instruction.layerInstructions = [transformer]
    videoComposition.instructions = [instruction]

    var exporter = AVAssetExportSession(asset: videoAsset, presetName: AVAssetExportPresetHighestQuality)
    exporter.videoComposition = videoComposition
    exporter.outputURL = videoUrl
    exporter.outputFileType = AVFileTypeQuickTimeMovie

    exporter.exportAsynchronouslyWithCompletionHandler( () -> Void in
        dispatch_async(dispatch_get_main_queue(), 
            self.handleExportCompletion(exporter)
        )
    )


func handleExportCompletion(session: AVAssetExportSession) 
    var library = ALAssetsLibrary()

    if library.videoAtPathIsCompatibleWithSavedPhotosAlbum(session.outputURL) 
        var completionBlock: ALAssetsLibraryWriteVideoCompletionBlock

        completionBlock =  assetUrl, error in
            if error != nil 
                println("error writing to disk")
             else 

            
        

        library.writeVideoAtPathToSavedPhotosAlbum(outputUrl, completionBlock: completionBlock)
    

【问题讨论】:

这里为什么需要composition 变量? 【参考方案1】:

事实证明,如果您尝试将导出器的 outputUrl 设置为与资产相同,那么您像我所做的那样编辑它并不会编辑它,太愚蠢了!所以为了将来引用,outputUrl 应该设置为一个新的唯一的

【讨论】:

能否请您详细说明解决方案和/或显示工作代码? 一旦资产被保存并且你已经获得了它的路径,你就不能覆盖它。因此,当我尝试使用这段代码进行保存时,我尝试将新编辑的视频保存在与原始视频相同的路径中,但失败了,因为默认情况下,Apple 不允许您覆盖它。所以我不得不将视频保存在一个新的独特路径上?有意义吗?如果您愿意,我可以提供一段代码,为资产生成唯一路径? 啊,有道理!如果你不介意的话,我会喜欢一段代码:)【参考方案2】:

我无法给你确切的答案,因为我使用 C# (Xamarin) 进行 iOS 编程。但我使用 setCropRectangle 来裁剪视频。 在 C# 中它看起来像这样:

layerInstruction.SetCrop (new CGRect (_cropMove, 0, _width / 2, height), transformTime);

查看文档:setCropRectangle

【讨论】:

以上是关于使用 AVFoundation 裁剪 AVAsset 视频不工作 iOS 8的主要内容,如果未能解决你的问题,请参考以下文章

使用 AV Foundation 时正确裁剪捕获的图像

带有 UIImagePickerController 和 AVFoundation 的自定义相机

使用 AVFoundation 的方形视频

缩放和裁剪 CMSampleBufferRef

Objective-C 如何将视频裁剪为捕获视图的大小?

裁剪 UIImage 使其在保存时逆时针旋转 90º