我正在 swift 上编写一个 iOS 应用程序,它从 URL 下载视频并将其写入磁盘。我正在获取数据,但迄今为止未能成功写入磁盘。下面是代码:
let yourURL = NSURL(string: "http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_10mb.mp4")
//Create a URL request
let urlRequest = NSURLRequest(URL: yourURL!)
//get the data
var theData = NSData();
do{
theData = try NSURLConnection.sendSynchronousRequest(urlRequest, returningResponse: nil)
}
catch let err as NSError
{
}
try! PHPhotoLibrary.sharedPhotoLibrary().performChangesAndWait({ ()-> Void in
if #available(iOS 9.0, *) {
PHAssetCreationRequest.creationRequestForAsset().addResourceWithType(PHAssetResourceType.Video, data: theData, options: nil)
print("SUCESS");
} else {
};
});
我收到以下错误,感谢任何见解:
fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=-1 "(null)": file /Library/Caches/com.apple.xbs/Sources/swiftlang/swiftlang-703.0.18.1/src/swift/stdlib/public/core/ErrorType.swift, line 54
一个问题是您试图将视频(可能非常大)加载到 NSData
的内存中。如果您可以流式传输到持久存储中的文件,或者从这些文件流式传输,那就更好了。您可以通过使用 NSURLSession
下载任务而不是使用已弃用的 NSURLConnection
方法 sendSynchronousRequest
来完成此操作。
通过使用 NSURLSession
下载任务,您可以避免一次尝试在内存中保存一个大视频,而是将视频直接流式传输到持久存储。 (注意,不要使用 NSURLSession
数据任务,因为这将与 NSURLConnection
的已弃用方法 sendSynchronousRequest
具有相同的内存占用问题。)
NSURLSession
下载任务将下载直接流式传输到持久存储后,您可以将文件移动到临时文件,然后使用 addResourceWithType
,再次提供文件 URL 而不是 NSData
。
当我这样做时(并添加了一些其他有用的错误检查),它似乎工作正常:
// make sure it's authorized
PHPhotoLibrary.requestAuthorization { authorizationStatus in
guard authorizationStatus == .Authorized else {
print("cannot proceed without permission")
return
}
self.downloadVideo()
}
地点:
func downloadVideo() {
let fileManager = NSFileManager.defaultManager()
// create request
let url = NSURL(string: "http://www.sample-videos.com/video/mp4/720/big_buck_bunny_720p_10mb.mp4")!
let task = NSURLSession.sharedSession().downloadTaskWithURL(url) { location, response, error in
// make sure there weren't any fundamental networking errors
guard location != nil && error == nil else {
print(error)
return
}
// make sure there weren't and web server errors
guard let httpResponse = response as? NSHTTPURLResponse where httpResponse.statusCode == 200 else {
print(response)
return
}
// move the file to temporary folder
let fileURL = NSURL(fileURLWithPath: NSTemporaryDirectory())
.URLByAppendingPathComponent(url.lastPathComponent!)
do {
try fileManager.moveItemAtURL(location!, toURL: fileURL)
} catch {
print(error)
return
}
// now save it in our photo library
PHPhotoLibrary.sharedPhotoLibrary().performChanges({
PHAssetCreationRequest.creationRequestForAsset().addResourceWithType(.Video, fileURL: fileURL, options: nil)
}, completionHandler: { success, error in
defer {
do {
try fileManager.removeItemAtURL(fileURL)
} catch let removeError {
print(removeError)
}
}
guard success && error == nil else {
print(error)
return
}
print("SUCCESS")
})
}
task.resume()
}
注意,由于 NSURLSession
对确保不执行不安全请求更为严格,您可能需要更新 info.plist
(右键单击它并选择“打开方式”-“源代码”)并将其添加到文件中:
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>sample-videos.com</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true/>
<!--Include to allow HTTP requests-->
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--Include to specify minimum TLS version-->
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
但是,当我完成所有这些操作时,视频已成功下载并添加到我的照片库中。请注意,我在这里删除了所有同步请求(NSURLSession
是异步的,performChanges
也是如此),因为您几乎从不想执行同步请求(当然也永远不会在主队列上) )。
关于ios - Swift 将视频 NSData 写入图库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38732839/
欢迎光临 OGeek|极客世界-中国程序员成长平台 (http://jike.in/) | Powered by Discuz! X3.4 |