当应用程序重新打开时,在 FileManager 中保存视频不起作用
Saving a video in FileManager doesn't work when the app reopens
我正在我的应用程序中录制视频,我想保存该视频并随时播放。一切正常,但当我重新打开应用程序时,文件不再可用(文件中没有数据 URL)。
我是这样做的:
我录制视频并等待代表 fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?)
命中。在这个函数中,我从输出中获取数据URL,我先将它保存在用户的图库中,然后保存在 FileManager 本地目录中:
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
if error == nil {
try? PHPhotoLibrary.shared().performChangesAndWait {
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: outputFileURL)
}
SVProgressHUD.show()
do {
if let data = try? Data(contentsOf: outputFileURL) {
let localDirectoryURL = self.saveToLocalDirectory(nameWithExtension: "\(randomString(length: 10)).mp4", data: data)
viewModel.outputVideoURL = localDirectoryURL ?? outputFileURL
viewModel.createAndSaveLocalVideo(url: localDirectoryURL ?? outputFileURL)
} else {
SVProgressHUD.showError(withStatus: "Something wrong happened")
}
}
}
func saveToLocalDirectory(nameWithExtension: String, data: Data) -> URL? {
guard let documentDirectoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
return nil
}
let path = documentDirectoryPath.appendingPathComponent(nameWithExtension)
do {
try data.write(to: path)
return path
} catch {
print(error.localizedDescription)
return nil
}
}
我将文件 URL 保存在 UserDefaults 中并尝试播放它。如果我还没有关闭应用程序,一切都会按预期进行。但是当我关闭应用程序并重新启动它时,我得到:
Error Domain=NSCocoaErrorDomain Code=260 "The file “33eLKbc8kA.mp4” couldn’t be opened because there is no such file."
在任何时候都没有抛出任何错误,正如我提到的,当我尝试在同一个应用程序会话中通过 URL 重现它时,它工作得很好。
现在我正在录制 10-15 秒的视频,但我最多会录制 60 到 75 分钟。它不是 4K,当它是一个 60 分钟的视频时,它的重量约为 500mb。
我做错了什么?
根据设计,每次重新打开应用程序时,文档目录的路径都会发生变化。因此,与其保存完整的 URL,不如只保存 URL 的最后一部分(最有可能是文件名)。
所以只需保存您的 nameWithExtension
,然后通过
之类的东西重新创建完整路径
func urlForVideo(nameWithExtension: String) -> URL? {
return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent(nameWithExtension)
}
并在加载和保存文件时使用此代码。
我正在我的应用程序中录制视频,我想保存该视频并随时播放。一切正常,但当我重新打开应用程序时,文件不再可用(文件中没有数据 URL)。
我是这样做的:
我录制视频并等待代表 fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?)
命中。在这个函数中,我从输出中获取数据URL,我先将它保存在用户的图库中,然后保存在 FileManager 本地目录中:
func fileOutput(_ output: AVCaptureFileOutput, didFinishRecordingTo outputFileURL: URL, from connections: [AVCaptureConnection], error: Error?) {
if error == nil {
try? PHPhotoLibrary.shared().performChangesAndWait {
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: outputFileURL)
}
SVProgressHUD.show()
do {
if let data = try? Data(contentsOf: outputFileURL) {
let localDirectoryURL = self.saveToLocalDirectory(nameWithExtension: "\(randomString(length: 10)).mp4", data: data)
viewModel.outputVideoURL = localDirectoryURL ?? outputFileURL
viewModel.createAndSaveLocalVideo(url: localDirectoryURL ?? outputFileURL)
} else {
SVProgressHUD.showError(withStatus: "Something wrong happened")
}
}
}
func saveToLocalDirectory(nameWithExtension: String, data: Data) -> URL? {
guard let documentDirectoryPath = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first else {
return nil
}
let path = documentDirectoryPath.appendingPathComponent(nameWithExtension)
do {
try data.write(to: path)
return path
} catch {
print(error.localizedDescription)
return nil
}
}
我将文件 URL 保存在 UserDefaults 中并尝试播放它。如果我还没有关闭应用程序,一切都会按预期进行。但是当我关闭应用程序并重新启动它时,我得到:
Error Domain=NSCocoaErrorDomain Code=260 "The file “33eLKbc8kA.mp4” couldn’t be opened because there is no such file."
在任何时候都没有抛出任何错误,正如我提到的,当我尝试在同一个应用程序会话中通过 URL 重现它时,它工作得很好。
现在我正在录制 10-15 秒的视频,但我最多会录制 60 到 75 分钟。它不是 4K,当它是一个 60 分钟的视频时,它的重量约为 500mb。
我做错了什么?
根据设计,每次重新打开应用程序时,文档目录的路径都会发生变化。因此,与其保存完整的 URL,不如只保存 URL 的最后一部分(最有可能是文件名)。
所以只需保存您的 nameWithExtension
,然后通过
func urlForVideo(nameWithExtension: String) -> URL? {
return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent(nameWithExtension)
}
并在加载和保存文件时使用此代码。