Запись обрезки видео с квадратным соотношением сторон AVCaptureSession

#ios #swift #avfoundation #avcapturesession #avcapturedevice

#iOS #swift #avfoundation #avcapturesession #avcapturedevice

Вопрос:

Как я могу записать квадратное видео с помощью AVCaptureSession? Если это невозможно при записи, то как я могу обрезать его впоследствии, в didFinishRecordingTo методе делегирования?

Заранее спасибо!

Ответ №1:

Вы можете записывать квадратное видео, используя этот демонстрационный код: https://github.com/DarshanRlogical/DKCustomCamera

или

Вы можете обрезать видео, используя следующий метод:

 func manageCroppingToSquare(filePath: URL , completion: @escaping (_ outputURL : URL?) -> ()) {
    
    // output file
    let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
    let outputPath = documentsURL?.appendingPathComponent("squareVideo.mov")
    if FileManager.default.fileExists(atPath: (outputPath?.path)!) {
        do {
           try FileManager.default.removeItem(atPath: (outputPath?.path)!)
        }
        catch {
            print ("Error deleting file")
        }
    }
    
    //input file
    let asset = AVAsset.init(url: filePath)
    print (asset)
    let composition = AVMutableComposition.init()
    composition.addMutableTrack(withMediaType: AVMediaTypeVideo, preferredTrackID: kCMPersistentTrackID_Invalid)
    
    //input clip
    let clipVideoTrack = asset.tracks(withMediaType: AVMediaTypeVideo)[0]
    
    //make it square
    let videoComposition = AVMutableVideoComposition()
    videoComposition.renderSize = CGSize(width: CGFloat(clipVideoTrack.naturalSize.height), height: CGFloat(clipVideoTrack.naturalSize.height))
    videoComposition.frameDuration = CMTimeMake(1, 30)
    let instruction = AVMutableVideoCompositionInstruction()
    instruction.timeRange = CMTimeRangeMake(kCMTimeZero, CMTimeMakeWithSeconds(60, 30))
    
    //rotate to potrait
    let transformer = AVMutableVideoCompositionLayerInstruction(assetTrack: clipVideoTrack)
    let t1 = CGAffineTransform(translationX: clipVideoTrack.naturalSize.height, y: -(clipVideoTrack.naturalSize.width - clipVideoTrack.naturalSize.height) / 2)
    let t2: CGAffineTransform = t1.rotated(by: .pi/2)
    let finalTransform: CGAffineTransform = t2
    transformer.setTransform(finalTransform, at: kCMTimeZero)
    instruction.layerInstructions = [transformer]
    videoComposition.instructions = [instruction]
    
    //exporter 
    let exporter = AVAssetExportSession.init(asset: asset, presetName: AVAssetExportPresetMediumQuality)
    exporter?.outputFileType = AVFileTypeQuickTimeMovie
    exporter?.outputURL = outputPath
    exporter?.videoComposition = videoComposition
    
    exporter?.exportAsynchronously() { handler -> Void in
        if exporter?.status == .completed {
            print("Export complete")
            DispatchQueue.main.async(execute: {
                completion(outputPath)
            })
            return
        } else if exporter?.status == .failed {
            print("Export failed - (String(describing: exporter?.error))")
        }
        completion(nil)
        return
    }
}
  

Я надеюсь, что этот код будет работать для вас.

Комментарии:

1. Спасибо за ответ! Я протестирую это и тоже вернусь с ответом.

2. Конечно, но, пожалуйста, сделайте то же самое с моим сообщением, потому что кто-то дал мне отрицательные оценки и не знаю почему.

3. эта библиотека открывает видео из ресурса и изменяет настройки рендеринга, это не библиотека для записи камеры

4. @famfamfam Я обновил URL, проверьте сейчас.