保存视频到图库,获取视频存放到图库的路径
Save video to the gallery and get the path for the video stored to Gallery
我想将从 UIImagePickerController
中选择的视频保存到相册。
之后我需要将 URL 提取到保存的路径。我看到一些预先存在的问题,这些问题使用现在已弃用的 ALAssetsLibrary
来回答。
喜欢:
有人可以指导我使用 Photo's framework
并达到上述预期结果吗?如果我有任何错误,请纠正我。
谢谢!!
首先,您需要在应用的 plist 文件中设置以下权限:
隐私 - 照片库使用说明
提供一个显示给用户的字符串,解释您请求权限的原因。
接下来,
import photos
然后使用此代码存储视频
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: fileURL)
}) { saved, error in
if saved {
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let fetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions).firstObject
// fetchResult is your latest video PHAsset
// To fetch latest image replace .video with .image
}
}
要从 PHAsset 中获取 url,请参考此
我通过创建 URL Class
的扩展来做到这一点
extension URL {
func saveVideo( success:@escaping (Bool,URL?)->()){
URLSession.shared.downloadTask(with: URLRequest(url: self)) { (url, response, error) in
let mgr = FileManager.default
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let destination = URL(fileURLWithPath: String(format: "%@/%@", documentsPath, "video.mp4"))
try? mgr.moveItem(atPath: /url?.path, toPath: /destination.path)
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: destination)
}) { completed, error in
if completed {
print("Video is saved!")
success(true,destination)
}
if error != nil{
success(false,nil)
}
}
}.resume()
}
}
当你想保存和播放时,你可以在 ViewController 中使用它作为
guard let urlToDownload = URL(string: videoURLStringToDownload) else { return }
urlToDownload.saveVideo(success: { (isSaved,url) in
guard let videoURL = url, isSaved else { return }
let player = AVPlayer(url: videoURL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player?.play()
}
})
导入 AVKit 用于通过 AVPlayerViewController
播放视频
导入 Photos 和 PhotosUI 以使用 PHAsset 保存视频。
希望对您有所帮助!
这样试试!
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]){
if mediaType.isEqualToString(kUTTypeMovie as NSString as String) || mediaType.isEqualToString(kUTTypeVideo as NSString as String){
let videoPath = info[UIImagePickerControllerMediaURL] as! NSURL // Path of video Url
PHPhotoLibrary.sharedPhotoLibrary().performChanges({
let createAssetRequest = PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(videoPath)
let assetPlaceholder = createAssetRequest?.placeholderForCreatedAsset
let albumChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: self.assetCollection, assets: self.photosAsset)
albumChangeRequest!.addAssets([assetPlaceholder!])
}, completionHandler: { (success, error) in
NSLog("Adding video to Library ->%@", (success ? "Success" : "Error"))
picker.dismissViewControllerAnimated(true, completion: nil)
})
}
}
这对我来说非常有效。
Swift 3.1 ->
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url!)
}) { saved, error in
if saved {
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
// After uploading we fetch the PHAsset for most recent video and then get its current location url
let fetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions).lastObject
PHImageManager().requestAVAsset(forVideo: fetchResult!, options: nil, resultHandler: { (avurlAsset, audioMix, dict) in
let newObj = avurlAsset as! AVURLAsset
print(newObj.url)
// This is the URL we need now to access the video from gallery directly.
})
}
}
如果你想获取保存的元素(不使用带日期顺序的排序描述符),你可以这样做:
var changeRequest: PHAssetChangeRequest?
var blockPlaceholder: PHObjectPlaceholder?
PHPhotoLibrary.shared().performChanges({
changeRequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url!)
blockPlaceholder = changeRequest?.placeholderForCreatedAsset
}) { saved, error in
if saved {
guard let placeholder = blockPlaceholder else {
return
}
let fetchOptions = PHFetchOptions()
let fetchResult:PHFetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [placeholder.localIdentifier], options: fetchOptions)
if let asset = fetchResult.firstObject {
//here you have the PHAsset
}
}
}
这是 Objective-C
的答案
代码示例:
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:[NSURL URLWithString:urlOfFile]];
} completionHandler:^(BOOL success, NSError *error) {
if (success)
{
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc]init];
fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:false]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeVideo options:fetchOptions];
PHAsset *lastAsset = [fetchResult lastObject];
[[PHImageManager defaultManager] requestAVAssetForVideo:lastAsset options:nil resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
//here's the url to the file
NSURL *url = (NSURL *)[(AVURLAsset *)asset URL];
}else{
NSLog(@"%@",error.description);
}
}];
我想将从 UIImagePickerController
中选择的视频保存到相册。
之后我需要将 URL 提取到保存的路径。我看到一些预先存在的问题,这些问题使用现在已弃用的 ALAssetsLibrary
来回答。
喜欢:
有人可以指导我使用 Photo's framework
并达到上述预期结果吗?如果我有任何错误,请纠正我。
谢谢!!
首先,您需要在应用的 plist 文件中设置以下权限:
隐私 - 照片库使用说明
提供一个显示给用户的字符串,解释您请求权限的原因。
接下来,
import photos
然后使用此代码存储视频
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: fileURL)
}) { saved, error in
if saved {
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
let fetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions).firstObject
// fetchResult is your latest video PHAsset
// To fetch latest image replace .video with .image
}
}
要从 PHAsset 中获取 url,请参考此
我通过创建 URL Class
的扩展来做到这一点extension URL {
func saveVideo( success:@escaping (Bool,URL?)->()){
URLSession.shared.downloadTask(with: URLRequest(url: self)) { (url, response, error) in
let mgr = FileManager.default
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let destination = URL(fileURLWithPath: String(format: "%@/%@", documentsPath, "video.mp4"))
try? mgr.moveItem(atPath: /url?.path, toPath: /destination.path)
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: destination)
}) { completed, error in
if completed {
print("Video is saved!")
success(true,destination)
}
if error != nil{
success(false,nil)
}
}
}.resume()
}
}
当你想保存和播放时,你可以在 ViewController 中使用它作为
guard let urlToDownload = URL(string: videoURLStringToDownload) else { return }
urlToDownload.saveVideo(success: { (isSaved,url) in
guard let videoURL = url, isSaved else { return }
let player = AVPlayer(url: videoURL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
playerViewController.player?.play()
}
})
导入 AVKit 用于通过 AVPlayerViewController
播放视频导入 Photos 和 PhotosUI 以使用 PHAsset 保存视频。
希望对您有所帮助!
这样试试!
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]){
if mediaType.isEqualToString(kUTTypeMovie as NSString as String) || mediaType.isEqualToString(kUTTypeVideo as NSString as String){
let videoPath = info[UIImagePickerControllerMediaURL] as! NSURL // Path of video Url
PHPhotoLibrary.sharedPhotoLibrary().performChanges({
let createAssetRequest = PHAssetChangeRequest.creationRequestForAssetFromVideoAtFileURL(videoPath)
let assetPlaceholder = createAssetRequest?.placeholderForCreatedAsset
let albumChangeRequest = PHAssetCollectionChangeRequest(forAssetCollection: self.assetCollection, assets: self.photosAsset)
albumChangeRequest!.addAssets([assetPlaceholder!])
}, completionHandler: { (success, error) in
NSLog("Adding video to Library ->%@", (success ? "Success" : "Error"))
picker.dismissViewControllerAnimated(true, completion: nil)
})
}
}
这对我来说非常有效。
Swift 3.1 ->
PHPhotoLibrary.shared().performChanges({
PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url!)
}) { saved, error in
if saved {
let fetchOptions = PHFetchOptions()
fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
// After uploading we fetch the PHAsset for most recent video and then get its current location url
let fetchResult = PHAsset.fetchAssets(with: .video, options: fetchOptions).lastObject
PHImageManager().requestAVAsset(forVideo: fetchResult!, options: nil, resultHandler: { (avurlAsset, audioMix, dict) in
let newObj = avurlAsset as! AVURLAsset
print(newObj.url)
// This is the URL we need now to access the video from gallery directly.
})
}
}
如果你想获取保存的元素(不使用带日期顺序的排序描述符),你可以这样做:
var changeRequest: PHAssetChangeRequest?
var blockPlaceholder: PHObjectPlaceholder?
PHPhotoLibrary.shared().performChanges({
changeRequest = PHAssetChangeRequest.creationRequestForAssetFromVideo(atFileURL: url!)
blockPlaceholder = changeRequest?.placeholderForCreatedAsset
}) { saved, error in
if saved {
guard let placeholder = blockPlaceholder else {
return
}
let fetchOptions = PHFetchOptions()
let fetchResult:PHFetchResult = PHAsset.fetchAssets(withLocalIdentifiers: [placeholder.localIdentifier], options: fetchOptions)
if let asset = fetchResult.firstObject {
//here you have the PHAsset
}
}
}
这是 Objective-C
的答案代码示例:
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
[PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:[NSURL URLWithString:urlOfFile]];
} completionHandler:^(BOOL success, NSError *error) {
if (success)
{
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc]init];
fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:false]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeVideo options:fetchOptions];
PHAsset *lastAsset = [fetchResult lastObject];
[[PHImageManager defaultManager] requestAVAssetForVideo:lastAsset options:nil resultHandler:^(AVAsset *asset, AVAudioMix *audioMix, NSDictionary *info) {
//here's the url to the file
NSURL *url = (NSURL *)[(AVURLAsset *)asset URL];
}else{
NSLog(@"%@",error.description);
}
}];