I found that VLC.app save video to album quickly. But my code will cost long time. Or it crash. How can I optimazed it. (compare with same large video)
Here is my code.
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
assetId = [PHAssetCreationRequest creationRequestForAssetFromVideoAtFileURL:fileUrl].placeholderForCreatedAsset.localIdentifier;
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (!success) {
if(onError)onError(error);
return ;
}
PHAssetCollection *collection = [self getAlbumCollection:collectionStr];
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetCollectionChangeRequest *request = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection];
PHAsset *asset = [PHAsset fetchAssetsWithLocalIdentifiers:#[assetId] options:nil].firstObject;
[request addAssets:#[asset]];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
if (!success) {
if(onError)onError(error);
return;
}
if(onComplete)onComplete(fileUrl);
}];
}];
Related
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'm using the following code to export a video to a custom Photos collection:
PHPhotoLibrary *photoLibrary = [PHPhotoLibrary sharedPhotoLibrary];
__block PHAssetCollection *album;
PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeAlbum subtype:PHAssetCollectionSubtypeAny options:nil];
for( int i = 0; i < fetchResult.count; i++)
{
PHAssetCollection *collection = [fetchResult objectAtIndex:i];
if([collection.localizedTitle isEqualToString:#"Pose Pro"])
{
album = collection;
break;
}
}
if( !album )
{
__block PHObjectPlaceholder *placeHolder;
[photoLibrary performChanges:^{
PHAssetCollectionChangeRequest *changeRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:#"Pose Pro"];
placeHolder = changeRequest.placeholderForCreatedAssetCollection;
} completionHandler:^(BOOL success, NSError * _Nullable error) {
PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:#[placeHolder.localIdentifier] options:nil];
album = fetchResult.firstObject;
}];
}
[photoLibrary performChanges:^{
PHAssetChangeRequest *assetChangeRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:_videoURL];
PHObjectPlaceholder *assetChangePlaceHolder = assetChangeRequest.placeholderForCreatedAsset;
PHFetchResult *videoAssets = [PHAsset fetchAssetsInAssetCollection:album options:nil];
PHAssetCollectionChangeRequest *albumChangeRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:album assets:videoAssets];
[albumChangeRequest addAssets:#[assetChangePlaceHolder]];
} completionHandler:^(BOOL success, NSError * _Nullable error) {
NSLog(#"Error: %#", [error localizedDescription]);
}];
When this code runs I get the following error message:
Error Domain=NSCocoaErrorDomain Code=-1 "(null)"
This code looks very similar to other code samples. Does anyone have any idea what I could be doing wrong?
I figured it out. The video URL was referencing the video's containing folder and not the actual video itself.
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;
}
}];
}
For iOS9, ALAssetsLibrary is deprecated. So how to change it as PHPPhotoLibrary instead of ALAssets?
if (RecordedSuccessfully && recording == NO) {
//----- RECORDED SUCESSFULLY -----
NSLog(#"didFinishRecordingToOutputFileAtURL - success");
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:outputFileURL])
{
[library writeVideoAtPathToSavedPhotosAlbum:outputFileURL
completionBlock:^(NSURL *assetURL, NSError *error)
{
if (error)
{
}
}];
}
// i have tried this, but didnt work
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest* createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:outputFileURL];
NSParameterAssert(createAssetRequest);
}
completionHandler:^(BOOL success, NSError *error) {}];
}
}
// Save to the album
__block PHObjectPlaceholder *placeholder;
[[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
PHAssetChangeRequest* createAssetRequest = [PHAssetChangeRequest creationRequestForAssetFromVideoAtFileURL:outputFileURL];
placeholder = [createAssetRequest placeholderForCreatedAsset];
} completionHandler:^(BOOL success, NSError *error) {
if (success)
{
NSLog(#"didFinishRecordingToOutputFileAtURL - success for ios9");
}
else
{
NSLog(#"%#", error);
}
}];