VPCamera3/tdvideo/tdvideo/CreateVideoByBuffer.swift
2024-03-05 11:44:34 +08:00

141 lines
4.2 KiB
Swift

//
// CreateVideoByBuffer.swift
// tdvideo
//
// Created by mac on 2024/2/22.
//
import UIKit
import AVFoundation
import Photos
class CreateVideoByBuffer: NSObject {
private var videoWriter: AVAssetWriter?
private var videoWriterInput: AVAssetWriterInput?
private var adaptor: AVAssetWriterInputPixelBufferAdaptor?
private var outputURL: URL?
private var isWriting: Bool = false
init(outputURL: URL) {
super.init()
self.outputURL = outputURL
setupWriter()
}
private func setupWriter() {
guard let outputURL = outputURL else {
print("Output URL is nil")
return
}
let width = 1920 // Example width
let height = 1080 // Example height
//
let outputSettings: [String: Any] = [
AVVideoCodecKey: AVVideoCodecType.h264,
AVVideoWidthKey: width,
AVVideoHeightKey: height
]
//
do {
videoWriter = try AVAssetWriter(outputURL: outputURL, fileType: .mov)
} catch {
print("Error creating AVAssetWriter: \(error)")
return
}
//
videoWriterInput = AVAssetWriterInput(mediaType: .video, outputSettings: outputSettings)
//
guard let videoWriterInput = videoWriterInput else {
print("Failed to create video writer input")
return
}
//
guard let videoWriter = videoWriter, videoWriter.canAdd(videoWriterInput) else {
print("Cannot add video writer input to video writer")
return
}
videoWriter.add(videoWriterInput)
//
adaptor = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: videoWriterInput, sourcePixelBufferAttributes: nil)
//
guard videoWriter.startWriting() else {
print("Failed to start writing")
return
}
videoWriter.startSession(atSourceTime: .zero)
}
func createVideo(from imageBuffer: CVImageBuffer, presentationTime: CMTime) {
guard isWriting else {
print("Video writer is not initialized or already writing")
return
}
//
let pixelBuffer = imageBuffer
guard let adaptor = adaptor else {
print("Failed to get pixel buffer adaptor")
return
}
guard let videoWriterInput = videoWriterInput else {
print("Failed to get video writer input")
return
}
guard adaptor.append(pixelBuffer, withPresentationTime: presentationTime) else {
print("Failed to append pixel buffer")
return
}
}
func videoCreationFinished(error: Error?) {
//
isWriting = false
//
guard let videoWriter = videoWriter, let videoWriterInput = videoWriterInput else {
print("Video writer or writer input is nil")
return
}
videoWriterInput.markAsFinished()
videoWriter.finishWriting { [weak self] in
guard let self = self else { return }
if let error = videoWriter.error {
print("Error finishing AVAssetWriter: \(error)")
} else {
print("Video creation finished at \(self.outputURL!)")
//
saveVideoToAlbum(url: outputURL!)
}
}
}
func saveVideoToAlbum(url: URL) {
PHPhotoLibrary.shared().performChanges {
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url)
} completionHandler: { success, error in
if success {
print("Video saved to album")
} else {
print("Failed to save video to album: \(error?.localizedDescription ?? "Unknown error")")
}
}
}
}