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后调用
videoWriter.writeSampleBuffer(sampleBuffer: sampleBuffer)
//停止采集调用
videoWriter.stopVideoWriting()