错误域= NSCocoaErrorDomain代码= -1“(null)";将.mov移至相机胶卷时 [英] Error Domain=NSCocoaErrorDomain Code=-1 "(null)" when moving .mov to camera roll

查看:902
本文介绍了错误域= NSCocoaErrorDomain代码= -1“(null)";将.mov移至相机胶卷时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在将我的应用程序创建的.mov文件从documents文件夹移动到相机胶卷时,我遇到了一个怪异的问题.一点背景:

I'm having a weird problem moving a .mov file created by my app from the documents folder to the camera roll. A bit of background:

该应用可以制作定时短片.它特别适用于具有12兆像素4032x3024传感器的设备.它在应用程序的documents文件夹中创建了电影.影片可以另存为4k或HD.也可以将它们另存为整个传感器的4:3长宽比影片或传感器的16:9裁剪图像.如果用户希望将影片存储在设备的相机胶卷"中,则可以设置该选项. 当我尝试将完整尺寸的电影(4032x3024)从应用程序的文档文件夹移动到相机胶卷时,我遇到了问题.我收到此错误:

The app makes time lapse movies. It works specifically with the devices that have a 12 megapixel 4032x3024 sensor. It created the movies in the app's documents folder. The movies can be saved as either 4k or HD. They can also be saved as a 4:3 aspect ratio movie of the entire sensor, or a 16:9 crop of the sensor. If the user wants the movie to be stored in the Camera Roll of the device, they can set that option. My problem exists when trying to move a full size movie (4032x3024) from the app's documents folder to the Camera Roll. I get this error:

Error Domain = NSCocoaErrorDomain Code = -1(null)"

Error Domain=NSCocoaErrorDomain Code=-1 "(null)"

这部电影很好,它仍然坐在文档的文件夹中.只是无法将其复制到相机胶卷.如果我通过其他大小相同的代码通过相同的代码执行此操作,则不会有问题. 4:3 HD(1440x1080)可以正常工作,16:9 HD(1920x1080)可以正常工作,16:9 4k(3880x2160)可以正常工作.当我尝试将其移动时,只是4:3 4k(4032x3024)会产生此错误.

The movie is fine, it's still sitting in the document's folder. It just can't be copied to the Camera Roll. If I do this same operation through the same code with any of the other sizes, no problem. A 4:3 HD (1440x1080) works fine, a 16:9 HD (1920x1080) works fine, a 16:9 4k (3880x2160) works fine. It's just the 4:3 4k (4032x3024) that generates this error when I try to move it.

这是执行移动操作的代码:

This is the code that does the move:

PHPhotoLibrary.shared().performChanges({
            PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: cameraRollURL!)

该网址还可以,因为它可以与其他大小配合使用.

The URL is OK because it works with the other sizes just fine.

推荐答案

当我从拉动切换为推入方式时(从编写者的角度看),我确实解决了这个问题.

I did fix this when I switched from pull to push approach (as seen from writter side).

拉方法是当我有一个UIImage数组(从相机捕获)时,当我准备处理下一个图像时又提要feed. 推送方法是当我一个接一个UIImage(从相机捕获),并且准备好处理下一个图像时,供稿器.

Pull approach is when I have an array of UIImage (captured from camera), and feed writer when it is ready to process next image. Push approach is when I have single UIImage (captured from camera) one by one, and feed writer if it is ready to process next image.

不确定是什么原因.也许正在处理AVWritter调用之间的消息循环.

Not sure what's a cause. Maybe processing message loop between AVWritter calls.

优点:如果捕获更长的视频,则您不会在UIImage数组中随时分配GB内存.

Advantage: you do not allocate bunch of GB memory in UIImage array at any time if capturing longer video.

缺点:如果捕获速度太快,编写器可能没有准备好编写样本,因为可以实时处理,因此可以丢弃帧.

Disadvantage: writer may not be ready to write sample if capturing is happening too fast so frames can be dropped because it is processing in real time.

迅速4:

func initVideo(videoSettings: [String: Any]) -> (assetWriter: AVAssetWriter, writeInput: AVAssetWriterInput, bufferAdapter:AVAssetWriterInputPixelBufferAdaptor)? {

    if(FileManager.default.fileExists(atPath: ImagesToVideoUtils.tempPath)){
        guard (try? FileManager.default.removeItem(atPath: ImagesToVideoUtils.tempPath)) != nil else {
            print("remove path failed")
            return nil
        }
    }

    let assetWriter = try! AVAssetWriter(url: ImagesToVideoUtils.fileURL, fileType: AVFileType.mov)

    let writeInput = AVAssetWriterInput(mediaType: AVMediaType.video, outputSettings: videoSettings)
    assert(assetWriter.canAdd(writeInput), "add failed")

    assetWriter.add(writeInput)
    let bufferAttributes:[String: Any] = [kCVPixelBufferPixelFormatTypeKey as String: Int(kCVPixelFormatType_32ARGB)]
    let bufferAdapter = AVAssetWriterInputPixelBufferAdaptor(assetWriterInput: writeInput, sourcePixelBufferAttributes: bufferAttributes)

    return (assetWriter, writeInput, bufferAdapter)

}

func exportVideo_start(assetWriter: AVAssetWriter) -> (DispatchQueue) {

    assetWriter.startWriting()
    assetWriter.startSession(atSourceTime: CMTime.zero)

    let mediaInputQueue = DispatchQueue(label: "mediaInputQueue")

    return (mediaInputQueue)
}

func exportVideo_write(videoSettings: [String: Any], img: UIImage, assetWriter: AVAssetWriter, writeInput: AVAssetWriterInput, bufferAdapter:AVAssetWriterInputPixelBufferAdaptor, mediaInputQueue: DispatchQueue, timestamp: CMTime) {

    if (writeInput.isReadyForMoreMediaData){
        var sampleBuffer:CVPixelBuffer?
        autoreleasepool{
            sampleBuffer = self.newPixelBufferFrom(cgImage: img.cgImage!, videoSettings: videoSettings)
        }

        bufferAdapter.append(sampleBuffer!, withPresentationTime: timestamp)
        print("Adding frame at \(timestamp)")
    }
}

func exportVideo_end( assetWriter: AVAssetWriter, writeInput: AVAssetWriterInput) {

    writeInput.markAsFinished()
        assetWriter.finishWriting {
            DispatchQueue.main.sync {
                print("Finished writting")
                ImagesToVideoUtils.saveToCameraRoll(videoURL: ImagesToVideoUtils.fileURL)
            }
        }
}

这篇关于错误域= NSCocoaErrorDomain代码= -1“(null)";将.mov移至相机胶卷时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆