How can I export video using AVAssetExportSession and save result video in a custom album, for example My Own Videos?
First you need to create a folder:
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
NSString *folderName = #"My Own Videos";
[library addAssetsGroupAlbumWithName:folderName
resultBlock:^(ALAssetsGroup *group)
{
NSLog(#"Added folder:%#", folderName);
}
failureBlock:^(NSError *error)
{
NSLog(#"Error adding folder");
}];
Then, find the folder:
__block ALAssetsGroup* folder;
[library enumerateGroupsWithTypes:ALAssetsGroupAlbum
usingBlock:^(ALAssetsGroup *group, BOOL *stop)
{
if ([[group valueForProperty:ALAssetsGroupPropertyName] isEqualToString:folderName])
{
folder = group;
}
}
failureBlock:^(NSError* error)
{
// Error handling.
}];
And add your video to it. Save the asset to Library:
AVURLAsset *videoAsset = ...
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:videoAsset
presetName:AVAssetExportPreset1280x720];
exportSession.outputURL = [[NSFileManager defaultManager] URLForInterviewWithFileName:newFileName];
exportSession.outputFileType = AVFileTypeMPEG4;
[exportSession exportAsynchronouslyWithCompletionHandler:^{ ...
And put it into the album:
[folder addAsset:asset];
Hope it helps.
after export session (when you have the url)
-(void)saveVideoUrl:(NSURL*)url toCollection:(NSString *)collectionTitle {
NSLog(#"entered %s", __PRETTY_FUNCTION__);
__block PHFetchResult *photosAsset;
__block PHAssetCollection *collection;
__block PHObjectPlaceholder *placeholder;
// Find the album
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:#"title = %#", collectionTitle];
// this is how we get a match for album Title held by 'collectionTitle'
collection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:fetchOptions].firstObject;
// check if album exists
if (!collection)
{
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
NSLog(#" Album did not exist, now creating album: %#",collectionTitle);
// Create the album
PHAssetCollectionChangeRequest *createAlbum = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:collectionTitle];
placeholder = [createAlbum placeholderForCreatedAssetCollection];
} completionHandler:^(BOOL didItSucceed, NSError *error) {
if (didItSucceed)
{
PHFetchResult *collectionFetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:#[placeholder.localIdentifier] options:nil];
collection = collectionFetchResult.firstObject;
}
}];
}
// Save to the album
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *assetRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:url];
placeholder = [assetRequest placeholderForCreatedAsset];
photosAsset = [PHAsset fetchAssetsInAssetCollection:collection options:nil];
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection assets:photosAsset];
[albumChangeRequest addAssets:#[placeholder]];
} completionHandler:^(BOOL didItSucceed, NSError *error) {
if (didItSucceed)
{ // if YES
NSLog(#" Looks like Image was saved in camera Roll as %#", placeholder.localIdentifier);
NSLog(#"placeholder holds %#", placeholder.debugDescription );
}
else
{
NSLog(#"%#", error);
}
}];
}
Related
I am trying to delete a photo from the photo gallery of the phone, but the deleted image was in the deleted directory, there is a way to delete the picture which is in the deleted directory of the phone?
There is my code :
-(void)deleteCaptureProcess{
PHAsset *asset = nil;
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"creationDate" ascending:YES]];
PHFetchResult *fetchResult = [PHAsset fetchAssetsWithMediaType:PHAssetMediaTypeImage options:fetchOptions];
if (fetchResult != nil && fetchResult.count > 0) {
// get last photo from Photos
asset = [fetchResult lastObject];
}
if (asset) {
PHContentEditingInputRequestOptions *editOptions = [[PHContentEditingInputRequestOptions alloc] init];
[asset requestContentEditingInputWithOptions:editOptions completionHandler:^(PHContentEditingInput *contentEditingInput, NSDictionary *info) {
if (contentEditingInput.fullSizeImageURL) {
NSLog(#"¨PATH %#",contentEditingInput.fullSizeImageURL);
NSArray *lines = [[NSString stringWithFormat:#"%#", contentEditingInput.fullSizeImageURL] componentsSeparatedByString: #"/"];
NSString *imageNZma = lines[[lines count]-1];
NSMutableArray *persons = [[NSMutableArray alloc]initWithCapacity:0];
[persons addObject:contentEditingInput.fullSizeImageURL];
__block PHAssetCollection *albumCollection = [[PHAssetCollection alloc] init];
PHFetchOptions *albumOptions = [[PHFetchOptions alloc] init];
[albumOptions setPredicate:[NSPredicate predicateWithFormat:#"estimatedAssetCount >= 0"]];
NSLog(#"%#",albumOptions);
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Request creating an asset from the image.
PHAssetChangeRequest* createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:[UIImage imageNamed:imageNZma]];
// Request editing the album.
PHAssetCollectionChangeRequest* albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:albumCollection];
// Get a placeholder for the new asset and add it to the album editing request.
PHObjectPlaceholder* assetPlaceholder = [createAssetRequest placeholderForCreatedAsset]; [albumChangeRequest addAssets:#[ assetPlaceholder ]];
} completionHandler:^(BOOL success, NSError* error) {
NSLog(#"Finished adding asset. %#", (success ? #"Success" : error));
}];
__block PHObjectPlaceholder *assetPlaceholder = nil;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest * request = [PHAssetChangeRequest creationRequestForAssetFromImage: [UIImage imageNamed:imageNZma]];
assetPlaceholder = request.placeholderForCreatedAsset;
} completionHandler:^(BOOL success, NSError *error) {
NSLog(#"creation success %d - error: %# - place: %#", success, error, assetPlaceholder);
PHFetchResult * result = [PHAsset fetchAssetsWithLocalIdentifiers: #[assetPlaceholder.localIdentifier] options: nil];
NSLog(#"Asset fetching: %#", result);
[[PHPhotoLibrary sharedPhotoLibrary] performChanges: ^{
[PHAssetChangeRequest deleteAssets: #[asset]];
} completionHandler:^(BOOL success, NSError *error) {
// NSLog(#"deletion success %d - error: %# - place: %#", success, error, assetPlaceholder);
}];
}];
}
}];
}
}
So my question is : there is a way to delete directly the image from the deleted folder after the image in gallery was deleted ?
Thank for help
I need a little bit of help in here, I have a method that saves an UIImage into the my custom images folder, but images saving into the camera roll folder as well which is i don't want.
Please, can anyone suggest me how can i restrict to save into camera roll folder ?
NSString *albumName = #"myApp";
void (^saveBlock)(PHAssetCollection *assetCollection) = ^void(PHAssetCollection *assetCollection) {
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:image];
PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
[assetCollectionChangeRequest addAssets:#[[assetChangeRequest placeholderForCreatedAsset]]];
} completionHandler:^(BOOL success, NSError *error) {
if (!success) {
NSLog(#"Error creating asset: %#", error);
}
}];
};
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:#"localizedTitle = %#", albumName];
PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:fetchOptions];
if (fetchResult.count > 0) {
saveBlock(fetchResult.firstObject);
} else {
__block PHObjectPlaceholder *albumPlaceholder;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCollectionChangeRequest *changeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:albumName];
albumPlaceholder = changeRequest.placeholderForCreatedAssetCollection;
} completionHandler:^(BOOL success, NSError *error) {
if (success) {
PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:#[albumPlaceholder.localIdentifier] options:nil];
if (fetchResult.count > 0) {
saveBlock(fetchResult.firstObject);
}
} else {
NSLog(#"Error creating album: %#", error);
}
}];
}
NSLog(#"Count : %lu",(unsigned long)[arrForHereLoImages count]);
Camera Roll contains all the devices pictures. This is by design in iOS. You can't prevent that.
Your image is not saved twice but actually saved in the camera roll and referenced in your custom Album.
I have more than 10 videos url in one view which is coming from Web service. I am showing these videos thumbnails in UITableview.
I am Using following code where I m Saving These Videos to gallery in particular folder
This is my code::
NSURL *url = [NSURL URLWithString:Urlstr];
NSData *data = [NSData dataWithContentsOfURL:url];
// Write it to cache directory
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:#"file.mov"];
[data writeToFile:path atomically:YES];
// After that use this path to save it to PhotoLibrary
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library addAssetsGroupAlbumWithName:#"MyFolderName" resultBlock:^(ALAssetsGroup *group)
{
//How to get the album URL?
// saving the video in gallery though file path and document directory
[library writeVideoAtPathToSavedPhotosAlbum:[NSURL fileURLWithPath:path] completionBlock:^(NSURL *assetURL, NSError *error) {
if (error) {
NSLog(#"%#", error.description);
}else {
NSLog(#"Done :)");
}
}];
}
failureBlock:^(NSError *error) {
//Handle the error
}];
Now the issues is it is not saving my video to My folder. But it creates the folder and saving the video in default video folder of gallery.
Anyone please suggest me why it going like this.
- (void)createAlbumInPhotosLibrary:(NSString *)photoAlbumName videoAtFile:(NSURL *)videoURL {
// RELIVIT_moments
__block PHFetchResult *photosAsset;
__block PHAssetCollection *collection;
__block PHObjectPlaceholder *placeholder;
// Find the album
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:#"title = %#", photoAlbumName];
collection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
subtype:PHAssetCollectionSubtypeAny
options:fetchOptions].firstObject;
// Create the album
if (!collection)
{
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCollectionChangeRequest *createAlbum = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:photoAlbumName];
placeholder = [createAlbum placeholderForCreatedAssetCollection];
} completionHandler:^(BOOL success, NSError *error) {
if (success)
{
PHFetchResult *collectionFetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:#[placeholder.localIdentifier]
options:nil];
collection = collectionFetchResult.firstObject;
[self saveVideoInRelivitFolderSetPlaceHolder:placeholder photosAsset:photosAsset collection:collection VideoAtFile:videoURL];
}
}];
} else {
[self saveVideoInRelivitFolderSetPlaceHolder:placeholder photosAsset:photosAsset collection:collection VideoAtFile:videoURL];
}
}
- (void)saveVideoInRelivitFolderSetPlaceHolder:(PHObjectPlaceholder *)placeholderLocal photosAsset:(PHFetchResult *)photosAssetLocal collection:(PHAssetCollection *)collectionLocal VideoAtFile:(NSURL *)videoURL {
__block PHFetchResult *photosAsset = photosAssetLocal;
__block PHAssetCollection *collection = collectionLocal;
__block PHObjectPlaceholder *placeholder = placeholderLocal;
// Save to the album
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *assetRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:videoURL];
placeholder = [assetRequest placeholderForCreatedAsset];
photosAsset = [PHAsset fetchAssetsInAssetCollection:collection options:nil];
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection
assets:photosAsset];
[albumChangeRequest addAssets:#[placeholder]];
} completionHandler:^(BOOL success, NSError *error) {
if (success)
{
NSLog(#"done");
}
else
{
NSLog(#"%#", error.localizedDescription);
}
}];
}
I am creating a specific album in my camera roll.. But for my every run, its creating a new album in my camera roll instead of putting the videos together to the same album.. Ideas?
__block PHObjectPlaceholder *assetCollectionPlaceholder;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
// Create new album.
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCollectionChangeRequest *createAlbumRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:#"Eye Movement"];
assetCollectionPlaceholder = createAlbumRequest.placeholderForCreatedAssetCollection;
} completionHandler:^(BOOL success, NSError *error) {
if (success) {
PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:#[assetCollectionPlaceholder.localIdentifier] options:nil];
PHAssetCollection *assetCollection = fetchResult.firstObject;
// Add it to the photo library
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest* createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:outputFileURL];
PHAssetCollectionChangeRequest* assetRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
[assetRequest addAssets:#[[createAssetRequest placeholderForCreatedAsset]]];
//PHAssetCollectionChangeRequest *assetCollectionChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:assetCollection];
//[assetCollectionChangeRequest addAssets:#[[createAssetRequest placeholderForCreatedAsset]]];
} completionHandler:^(BOOL success, NSError *error) {
if (!success) {
NSLog(#"Error creating asset: %#", error);
}
}];
} else {
//NSLog(#"Error creating album: %#", error);
NSLog(#"didFinishRecordingToOutputFileAtURL - success for ios9");
}
}];
You have to check to see if the album is created first, then tell the app to create the album if it does not exist.
__block PHFetchResult *photosAsset;
__block PHAssetCollection *collection;
__block PHObjectPlaceholder *placeholder;
// Find the album
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:#"title = %#", #"Your Album Name Here"];
collection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
subtype:PHAssetCollectionSubtypeAny
options:fetchOptions].firstObject;
// Create the album
if (!collection)
{
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCollectionChangeRequest *createAlbum = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:#"Your Album Name Here"];
placeholder = [createAlbum placeholderForCreatedAssetCollection];
} completionHandler:^(BOOL success, NSError *error) {
if (success)
{
PHFetchResult *collectionFetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:#[placeholder.localIdentifier]
options:nil];
collection = collectionFetchResult.firstObject;
}
}];
}
I am using following code to save image to my custom folder created in iOS photo gallery:
I get this error: Error Domain=NSCocoaErrorDomain Code=-1 "(null)"
Can anyone help me out on this ?
+(BOOL)saveToAlbum:(NSString*)albumName image:(UIImage*)image{
__block PHFetchResult *photosAsset;
__block PHAssetCollection *collection;
__block PHObjectPlaceholder *placeholder;
__block BOOL retStat = false;
NSData *newImageSize = UIImageJPEGRepresentation(image, 1);
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest *assetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:[UIImage imageWithData:newImageSize]];
placeholder = [assetRequest placeholderForCreatedAsset];
photosAsset = [PHAsset fetchAssetsInAssetCollection:[self findAlbumAssetCollection:albumName] options:nil];
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection
assets:photosAsset];
[albumChangeRequest addAssets:#[placeholder]];
} completionHandler:^(BOOL success, NSError *error) {
if (success){
retStat = true;
}
else{
NSLog(#"%#", error);
}}];
}
Answering here so someone can find this in google search results and save themselves the time I wasted: If you get this error creating an asset, check your phone storage. I got this error as a propagation of another silent error because my phone had 0 bytes (yes, 0 bytes) available storage space.
Thanks Mr.T for providing me a hint(collection was nil at albumChangeRequest)..Here is the correct solution for this.
+(BOOL)saveToAlbum:(NSString*)albumName image:(UIImage*)image{
__block BOOL retStat = false;
NSData *newImageSize = UIImageJPEGRepresentation(image, 1);
UIImage *imageNew = [UIImage imageWithData:newImageSize];
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHFetchResult *photosAsset;
PHAssetCollection *collection = [self findAlbumAssetCollection:albumName];
PHObjectPlaceholder *placeholder;
placeholder = [[PHAssetChangeRequest creationRequestForAssetFromImage:imageNew] placeholderForCreatedAsset];
photosAsset = [PHAsset fetchAssetsInAssetCollection:collection options:nil];
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection assets:photosAsset];
[albumChangeRequest addAssets:#[placeholder]];
} completionHandler:^(BOOL success, NSError *error) {
if (success){
retStat = true;
}
else{
NSLog(#"%#", error);
}}];
return retStat;}
+(PHAssetCollection*)findAlbumAssetCollection:(NSString*)albumName{
PHAssetCollection *collection;
PHFetchOptions *fetchOptions = [[PHFetchOptions alloc] init];
fetchOptions.predicate = [NSPredicate predicateWithFormat:#"title = %#", albumName];
collection = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum
subtype:PHAssetCollectionSubtypeAny
options:fetchOptions].firstObject;
return collection;
}