Fis*_*les 10 ios swift phphotolibrary
我有一个奇怪的问题,将.mov我的应用程序创建的文件从文档文件夹移动到相机胶卷.一点背景:
该应用程序制作时间推移电影.它专门用于具有1200万像素4032x3024传感器的设备.它在应用程序的文档文件夹中创建了电影.电影可以保存为4k或HD.它们也可以保存为整个传感器的4:3宽高比电影,或传感器的16:9裁剪.如果用户希望将电影存储在设备的相机胶卷中,则可以设置该选项.尝试将全尺寸电影(4032x3024)从应用程序的文档文件夹移动到相机胶卷时存在问题.我收到此错误:
错误域= NSCocoaErrorDomain代码= -1"(null)"
电影很好,它仍然坐在文档的文件夹中.它无法复制到相机胶卷.如果我通过相同的代码执行相同的操作与任何其他大小,没有问题.一个4:3高清(1440x1080)工作正常,16:9高清(1920x1080)工作正常,16:9 4k(3880x2160)工作正常.当我尝试移动它时,它只是4:3 4k(4032x3024)产生此错误.
这是移动的代码:
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: cameraRollURL!)
Run Code Online (Sandbox Code Playgroud)
该URL正常,因为它可以很好地与其他大小一起使用.
ved*_*ano -1
当我从拉式方法切换到推式方法时,我确实解决了这个问题(从作者的角度来看)。
拉方法是当我有一个 UIImage 数组(从相机捕获)时,并在准备好处理下一个图像时提供写入器。推送方法是当我一张一张地拥有单个 UIImage(从相机捕获)时,如果准备好处理下一张图像,则将其提供给编写器。
不确定是什么原因。也许处理 AVWritter 调用之间的消息循环。
优点:如果捕获较长的视频,则任何时候都无需在 UIImage 数组中分配大量 GB 内存。
缺点:如果捕获发生得太快,写入器可能尚未准备好写入样本,因此可能会丢失帧,因为它是实时处理的。
斯威夫特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)
}
}
}
Run Code Online (Sandbox Code Playgroud)