Swift-AVAssetWriter保存視頻

import UIKit
import AVFoundation

class ZGVideoWriter: NSObject {
    
    private var videoWriter: AVAssetWriter?
    private var videoWriterInput: AVAssetWriterInput?
    private var videoOutput: AVCaptureVideoDataOutput?
    private var isWritingStarted = false

    private var videoWidth: Double = 1080
    private var videoHeight: Double = 1920
    private var fps: Double = 30
    
    func setFpsAndResolution(width: Double, height: Double, fps: Double){
        videoWidth = width
        videoHeight = height
        self.fps = fps
    }
    
    func setParameter(outputPath: String, orientation: UIDeviceOrientation){
        let outputURL = URL(fileURLWithPath: filePath)
        do {
            videoWriter = try AVAssetWriter(url: outputURL, fileType: .mp4)
        } catch {
            fatalError("Failed to create AVAssetWriter: \(error)")
        }
        
        var rotation = CGFloat.zero
        let w = videoWidth
        let h = videoHeight
        switch orientation {
        case .portrait, .portraitUpsideDown:
            videoWidth = min(w, h)
            videoHeight = max(w, h)
        case .landscapeLeft, .landscapeRight:
            videoWidth = max(w, h)
            videoHeight = min(w, h)
            rotation = -(Double.pi)
        default: break
        }
        
        let pixelsCount = videoWidth * videoHeight
        let bitsPerPixel = 6.0
        let bitsPerSecond = pixelsCount * bitsPerPixel
        let videoSettings: [String: Any] = [
            AVVideoCodecKey: AVVideoCodecType.h264,
            AVVideoWidthKey: videoWidth,
            AVVideoHeightKey: videoHeight,
            AVVideoCompressionPropertiesKey: [
                AVVideoAverageBitRateKey: bitsPerSecond,
                AVVideoExpectedSourceFrameRateKey: fps,
                AVVideoMaxKeyFrameIntervalKey: fps,
                AVVideoProfileLevelKey: AVVideoProfileLevelH264BaselineAutoLevel
            ]
        ]
        videoWriterInput = AVAssetWriterInput(mediaType: .video, outputSettings: videoSettings)
        videoWriterInput?.transform = CGAffineTransform(rotationAngle: rotation)
        if videoWriter!.canAdd(videoWriterInput!) {
            videoWriter?.add(videoWriterInput!)
        } else {
            fatalError("Failed to add videoWriterInput to AVAssetWriter")
        }
    }
    
    func writeSampleBuffer(sampleBuffer: CMSampleBuffer){
        if !isWritingStarted {
            videoWriter?.startWriting()
            videoWriter?.startSession(atSourceTime: CMSampleBufferGetPresentationTimeStamp(sampleBuffer))
            isWritingStarted = true
        }
        
        if videoWriterInput!.isReadyForMoreMediaData {
            if videoWriterInput!.append(sampleBuffer) {
            } else {
                print("Failed to append sample buffer")
            }
        }
    }
    
    func stopVideoWriting() {
        videoWriterInput?.markAsFinished()
        videoWriter?.finishWriting {[weak self] in
            if self?.videoWriter?.status == .completed {
                print("Video saved successfully")
                
            } else {
                print("Failed to save video: \(self?.videoWriter?.error?.localizedDescription ?? "")")
            }
            self?.isWritingStarted = false
        }
    }
}

使用

let videoWriter = ZGVideoWriter()
videoWriter.setVideoOutputPath(outputPath: "/\(your path).mov")
//采集到CMSampleBuffer后調(diào)用
videoWriter.writeSampleBuffer(sampleBuffer: sampleBuffer)
//停止采集調(diào)用
videoWriter.stopVideoWriting()
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容