問題描述
IOS ‑ UISaveVideoAtPathToSavedPhotosAlbum 如何返回保存的視頻路徑? (IOS ‑how could UISaveVideoAtPathToSavedPhotosAlbum return the saved video path?)
‑ (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSURL *videoURL = [info objectForKey:UIImagePickerControllerMediaURL];
//get the videoURL
NSString *tempFilePath = [videoURL path];
if ( UIVideoAtPathIsCompatibleWithSavedPhotosAlbum(tempFilePath))
{
// Copy it to the camera roll.
UISaveVideoAtPathToSavedPhotosAlbum(tempFilePath, self, @selector(video:didFinishSavingWithError:contextInfo:), tempFilePath);
}
}
I use UISaveVideoAtPathToSavedPhotosAlbum to save video recorded. And I want to know the absolute path in the album where I saved the recorded video.
How could I get the saved Path? UISaveVideoAtPathToSavedPhotosAlbum does not return any.
and in the callback function video:didFinishSavingWithError:contextInfo: there is still not path info.
‑‑‑‑‑
參考解法
方法 1:
As far as I know.. You cannot get the path for the videos saved in the Photo album. If you want the files list to be replayed from your app. You can have all the videos inside your application.
Following is your sample code to put inside didFinishPickingMedia to store the videos in side documents.. So that you can keep track of it.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0]; // Get documents folder
NSString *dataPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%d", 1]];
NSString *fileName = [NSString stringWithFormat:@"%@ :%@.%@", itsIncidentType, [dateFormatter stringFromDate:incidentDate], @"mp4"];
[dateFormatter release];
if (![[NSFileManager defaultManager] fileExistsAtPath:dataPath])
[[NSFileManager defaultManager] createDirectoryAtPath:dataPath withIntermediateDirectories:NO attributes:nil error:&error]; //Create folder
NSURL *videoURL = [imageInfo objectForKey:UIImagePickerControllerMediaURL];
NSData *webData = [NSData dataWithContentsOfURL:videoURL];
self.itsVideoName = fileName;
[webData writeToFile:[NSString stringWithFormat:@"%@/%@",dataPath,fileName] atomically:TRUE];
Hope this helps you..
方法 2:
I recently had a similar problem and solved it that way.
Create category of PHAsset with two methods
PHAsset+Picking.h
#import <Photos/Photos.h>
@interface PHAsset (Picking)
+ (PHAsset *)retrievePHAssetWithLocalIdentifier:(NSString *)identifier;
+ (void)saveVideoFromCameraToPhotoAlbumWithInfo:(NSDictionary *)info
completion:(void(^)(PHAsset * _Nullable asset))completion;
@end
PHAsset+Picking.m
@implementation PHAsset (Picking)
+ (PHAsset *)retrievePHAssetWithLocalIdentifier:(NSString *)identifier {
PHAsset *asset = nil;
if (identifier) {
PHFetchResult *result = [PHAsset fetchAssetsWithLocalIdentifiers:@[identifier] options:nil];
asset = result.firstObject;
}
return asset;
}
+ (void)saveVideoFromCameraToPhotoAlbumWithInfo:(NSDictionary *)info
completion:(void(^)(PHAsset * _Nullable asset))completion
{
// get URL to file from picking media info
NSURL *url = info[UIImagePickerControllerMediaURL];
__block PHAssetChangeRequest *changeRequest = nil;
__block PHObjectPlaceholder *assetPlaceholder = nil;
// save video file to library
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
changeRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:url];
assetPlaceholder = changeRequest.placeholderForCreatedAsset;
} completionHandler:^(BOOL success, NSError *error) {
if (success) {
// get saved object as PHAsset
PHAsset *asset = [PHAsset retrievePHAssetWithLocalIdentifier:assetPlaceholder.localIdentifier];
completion(asset);
} else {
completion(nil);
}
}];
}
@end
Then use method saveVideoFromCameraToPhotoAlbumWithInfo inside
‑ (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
NSString *mediaType = [info objectForKey:UIImagePickerControllerMediaType];
if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]) {
Weakify(self);
void (^processAsset)(PHAsset *, NSDictionary *) = ^void(PHAsset *asset, NSDictionary *mediaInfo) {
[PHImageManager.defaultManager requestAVAssetForVideo:asset
options:nil
resultHandler:^(AVAsset *asset,
AVAudioMix *audioMix,
NSDictionary *assetInfo)
{
Strongify(self);
if ([asset respondsToSelector:@selector(URL)]) {
// URL to video file here ‑‑>
NSURL *videoURL = [asset performSelector:@selector(URL)];
// <‑‑
} else {
// asset hasn't property URL
// it is can be AVComposition (e.g. user chose slo‑mo video)
}
}];
};
if (UIImagePickerControllerSourceTypeCamera == picker.sourceType) {
// save video from camera
[PHAsset saveVideoFromCameraToPhotoAlbumWithInfo:info completion:^(PHAsset *asset) {
// processing saved asset
processAsset(asset, info);
}];
} else {
// processing existing asset from library
processAsset(info[UIImagePickerControllerPHAsset], info);
}
} else {
// image processing
}
}
(by lingzhao、Dilip Rajkumar、user3747329)