我要将AVAssetWriter
的输出保存到相机胶卷,我目前将其保存到documents目录。
我尝试使用UISaveVideoAtPathToSavedPhotosAlbum(_:_:_:_:)
。我当前正在使用AVAssetWriter
来写.documentsdirectotry
。但是,当我尝试写时,它会静默失败。要写作,我将打电话给startRecording()
,然后我打电话给stopRecording()
完成写作。
let captureSession = AVCaptureSession()
var videoOutput = AVCaptureVideoDataOutput()
var assetWriter: AVAssetWriter!
var assetWriterInput: AVAssetWriterInput!
var isCameraSetup = false
var hasStartedWritingCurrentVideo = false
var isWriting = false
let queue = DispatchQueue(label: "com.name.camera-queue")
// Camera preview setup code
//Setting up Asset Writer to save videos
public func setUpAssetWriter() {
do {
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first
let outputURL = URL(fileURLWithPath: documentsPath!).appendingPathComponent("test.m4v")
assetWriter = try! AVAssetWriter(outputURL: outputURL, fileType: .mp4)
assetWriterInput = AVAssetWriterInput(mediaType: .video, outputSettings: videoOutput.recommendedVideoSettingsForAssetWriter(writingTo: .mp4))
assetWriterInput.expectsMediaDataInRealTime = true
if assetWriter.canAdd(assetWriterInput) {
assetWriter.add(assetWriterInput)
} else {
print("no input added")
}
assetWriter.startWriting()
} catch let error {
debugPrint(error.localizedDescription)
}
}
public func tearDownAssetWriter() {
assetWriter = nil
assetWriterInput = nil
}
public func startWriting(){
if isWriting{ return }
setUpAssetWriter()
hasStartedWritingCurrentVideo = false
isWriting = true
}
public func finishWriting(_ completion: @escaping (URL) -> Void) {
if isWriting == false { return }
isWriting = false
assetWriterInput.markAsFinished()
let url = self.assetWriter.outputURL
assetWriter.finishWriting {
completion(url)
self.tearDownAssetWriter()
}
hasStartedWritingCurrentVideo = false
}
// MARK: Starts the capture session
public func start() {
if !captureSession.isRunning {
captureSession.startRunning()
}
}
public func stop() {
if captureSession.isRunning {
captureSession.stopRunning()
}
}
// MARK: Records after camera is set up
public func startRecording() {
startWriting()
isWriting = true
}
public func stopRecording() {
assetWriterInput.markAsFinished()
assetWriter.finishWriting {
[weak self] in return
}
}
}
extension VideoCapture: AVCaptureVideoDataOutputSampleBufferDelegate {
public func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
// Because lowering the capture device's FPS looks ugly in the preview,
// we capture at full speed but only call the delegate at its desired
// framerate.
let timestamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
let deltaTime = timestamp - lastTimestamp
if deltaTime >= CMTimeMake(value: 1, timescale: Int32(fps)) {
lastTimestamp = timestamp
let imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)
delegate?.videoCapture(self, didCaptureVideoFrame: imageBuffer, timestamp: timestamp)
}
// Asset Writer
guard let assetWriter = assetWriter, let assetWriterInput = assetWriterInput else { return }
if isWriting == false{ return }
if self.assetWriter.status == .failed {
setUpAssetWriter()
hasStartedWritingCurrentVideo = false
}
if hasStartedWritingCurrentVideo == false && output === videoOutput { return }
if hasStartedWritingCurrentVideo == false {
hasStartedWritingCurrentVideo = true
let sourceTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer)
assetWriter.startSession(atSourceTime: sourceTime)
}
if output === videoOutput && assetWriterInput.isReadyForMoreMediaData{
if isWriting == false{return}
assetWriterInput.append(sampleBuffer)
}
}
}
当前的实现设置了摄像头和预览,但是没有任何内容保存到输出中。
它应该保存到.documentDirectory,但是不保存。我想取而代之将其保存到相机胶卷中,但是我不确定应该在哪里准确调用UISaveVideoAtPathToSavedPhotosAlbum(_:_:_:_:)
。
问题可能出在我的扩展代表中。
预先感谢您的帮助。
答案 0 :(得分:0)
我对UISaveVideoAtPathToSavedPhotosAlbum不熟悉。但是浏览堆栈溢出和git时,很多人都使用PHPhotoLibrary,我也是如此。无论URL如何,下面的代码都会将视频添加到photoLibrary中。
1)信息列表 通过+按钮添加新的键值对。选择“ Privary-Photo Library使用说明”作为键。设置诸如“将照片保存在照片库中”之类的值
2)代码
fileWriter.finishWriting(completionHandler: {
let status = PHPhotoLibrary.authorizationStatus()
//no access granted yet
if status == .notDetermined || status == .denied{
PHPhotoLibrary.requestAuthorization({auth in
if auth == .authorized{
saveInPhotoLibrary(url)
}else{
print("user denied access to photo Library")
}
})
//access granted by user already
}else{
saveInPhotoLibrary(url)
}
})
private func saveInPhotoLibrary(_ url:URL){
PHPhotoLibrary.shared().performChanges({
//add video to PhotoLibrary here
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url)
}) { completed, error in
if completed {
print("save complete! path : " + url.absoluteString)
}else{
print("save failed")
}
}
}
希望这会有所帮助。 GW