I'm developing an app where user can record video and save it in the library/or custom album. I'm able to create the custom album and record the video and save it in the default photo library i.e., camera roll.. But i'm unable to save it to the custom album. and other thing is the saved videos in the album must be showed in the collection view of the app i.e., like the gallery view.. so that user can able to click on the videos for the play.. it might be in the grid view/ collection view or might be in the table view where the UIImage should should display the videos saved in the album..
Here's code section which i used in the app development for creating the custom album.
ALAssetsLibrary* libraryFolder = [[ALAssetsLibrary alloc] init];
[libraryFolder addAssetsGroupAlbumWithName:#"HEP" resultBlock:^(ALAssetsGroup *group)
{
NSLog(#"Adding Folder:'My Album', success: %s", group.editable ? "Success" : "Already created: Not Success");
} failureBlock:^(NSError *error)
{
NSLog(#"Error: Adding on Folder");
}];
For recording the video in the app.
- (IBAction)StartRecord:(id)sender {
UIImagePickerController *picker = [[UIImagePickerController alloc] init];
picker.delegate = self;
picker.allowsEditing = YES;
picker.sourceType = UIImagePickerControllerSourceTypeCamera;
picker.mediaTypes = [[NSArray alloc] initWithObjects:(NSString *)kUTTypeMovie, nil];
[self presentViewController:picker animated:YES completion:NULL];
}
For saving it in the album i.e., default photo album not the custom album i created.
-(BOOL)startMediaBrowserFromViewController:(UIViewController*)controller usingDelegate:(id )delegate {
// 1 - Validations
if (([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeSavedPhotosAlbum] == NO)
|| (delegate == nil)
|| (controller == nil)) {
return NO;
}
// 2 - Get image picker
UIImagePickerController *mediaUI = [[UIImagePickerController alloc] init];
mediaUI.sourceType = UIImagePickerControllerSourceTypeSavedPhotosAlbum;
mediaUI.mediaTypes = [[NSArray alloc] initWithObjects: (NSString *) kUTTypeMovie, nil];
// Hides the controls for moving & scaling pictures, or for
// trimming movies. To instead show the controls, use YES.
mediaUI.allowsEditing = YES;
mediaUI.delegate = delegate;
// 3 - Display image picker
[controller presentModalViewController:mediaUI animated:YES];
return YES;
}
Since i'm beginner in iOS still learning.. I'm searching since for a month now. So please help me.
First create your album folder with below code & make sure this code paste in AppDelegate.m file didFinishLaunchingWithOptions method :
ALAssetsLibrary* libraryFolderSozialConnectVideo = [[ALAssetsLibrary alloc] init];
[libraryFolderSozialConnectVideo addAssetsGroupAlbumWithName:#"HEP" resultBlock:^(ALAssetsGroup *group)
{
NSLog(#"HEP Folder Created");
} failureBlock:^(NSError *error) {
NSLog(#"Error: Adding on Folder");
}];
Now, use below function for download your video in HEP folder :
- (void)downloadVideo:(NSURL *)videoURL {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(#"Downloading Started");
NSData *urlData = [NSData dataWithContentsOfURL:videoURL];
if (urlData) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [NSString stringWithFormat:#"%#/%#", documentsDirectory,#"thefile.mp4"];
[urlData writeToFile:filePath atomically:YES];
dispatch_async(dispatch_get_main_queue(), ^{
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
[self.library saveVideo:[NSURL fileURLWithPath:filePath] toAlbum:#"HEP" completion:^(NSURL *assetURL, NSError *error)
{
NSLog(#"Success downloaded");
} failure:^(NSError *error) {
NSLog(#"Error : %#", [error localizedDescription]);
[MBProgressHUD hideAllHUDsForView:self.view animated:YES];
[self.navigationController popViewControllerAnimated:YES];
}];
});
}
}); }
for videoURL in your didFinishPickingMediaWithInfo method call above function with below code :
self.library = [[ALAssetsLibrary alloc] init];
[self downloadVideo:[info valueForKey:UIImagePickerControllerMediaURL]];
I hope this works . . .
Related
I have a CollectionView with images and in the next ViewController I am recording a video using Av captured sessions and i am saving it in to the mobile document directory,Then i am coming back to the collection and i am reloading the collection view now i want the recored video in the collection view cell with out using any api.
I used the below code to save the recored video in the directory
'- (void)saveRecordedFile:(NSURL *)recordedFile {
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
ALAssetsLibrary *assetLibrary = [[ALAssetsLibrary alloc] init];
[assetLibrary writeVideoAtPathToSavedPhotosAlbum:recordedFile
completionBlock:
^(NSURL *assetURL, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
NSString *title;
NSString *message;
if (error != nil) {
title = #"Failed to save video";
message = [error localizedDescription];
}
else {
title = #"Saved!";
message = nil;
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
UIStoryboard *storybord=[UIStoryboard storyboardWithName:#"Main" bundle:nil];
shareViewController *shareview=[storybord instantiateViewControllerWithIdentifier:#"share"];
[self presentViewController:shareview animated:YES completion:nil];
});
}];
});
can any body help out to solve this problem.solution view code is appreciated. i recored video by referring this https://github.com/shu223/SlowMotionVideoRecorder
1) You can achieve it by getting the center frame of the video which you have stored in the document directory.
2) You can store the center frame image of the video to document directory so that you don't have to generate everytime.
3) Display video thumbnail inside collectionview.
Refer this link for get frame of the video :
Create thumbnail from a video url in IPhone SDK
EDIT:
NSString *videoPath = [videoURL path];
MPMoviePlayerViewController *videoPlayerView = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:videoPath]];
[self presentMoviePlayerViewControllerAnimated:videoPlayerView]; [videoPlayerView.moviePlayer play];
I have a problem, after record video, I click on Use button to save this video to library but after save done, I can not tap on Play button or Retake button. This is my code :
-(void)actionLaunchAppCamera
{
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera])
{
UIImagePickerController * imagePickerController = [[UIImagePickerController alloc] init];
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
imagePickerController.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeMovie];
imagePickerController.sourceType = UIImagePickerControllerSourceTypeCamera;
imagePickerController.showsCameraControls = YES;
imagePickerController.allowsEditing = YES;
imagePickerController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;
imagePickerController.delegate = self;
imagePickerController.cameraDevice = UIImagePickerControllerCameraDeviceRear;
[self presentModalViewController:imagePickerController animated:YES];
//[imagePickerController release];
}
}
}
saving the image that was taken
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
NSURL *recordedVideoURL= [info objectForKey:UIImagePickerControllerMediaURL];
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:recordedVideoURL]) {
[library writeVideoAtPathToSavedPhotosAlbum:recordedVideoURL
completionBlock:^(NSURL *assetURL, NSError *error){
[library assetForURL:assetURL resultBlock:^(ALAsset *asset) {
NSDate* date = [asset valueForProperty:ALAssetPropertyDate];
NSLog(#"Date Time Modify %#",date);
NSDateFormatter* formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat: #"dd.MM.yyyy HH:mm:ss"];
NSString* CurrentDateStamp = [formatter stringFromDate:date];
NSLog(#"NameVideo %#",asset.defaultRepresentation.filename);
NSLog(#"DateModify %#",CurrentDateStamp);
NSLog(#"Size: %lld", asset.defaultRepresentation.size);
} failureBlock:nil];
actionSheetUpload= [[UIActionSheet alloc] initWithTitle:#"Do you want to upload this video?" delegate:self cancelButtonTitle:#"Cancel" destructiveButtonTitle:#"Upload" otherButtonTitles:nil];
actionSheetUpload.actionSheetStyle = UIActionSheetStyleBlackOpaque;
[actionSheetUpload showInView:[UIApplication sharedApplication].keyWindow];
[actionSheetUpload release];
}
];
}
[library release];
}
Any ideas? Thanks in advance
Maybe you not dismiss picker with - (void)dismissViewControllerAnimated: (BOOL)flag completion: (void (^)(void))completion
The Code is just fine for saving the video, If you want to get it play. Then You need to use player to get it play.
For Example:
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSURL *recordedVideoURL= [info objectForKey:UIImagePickerControllerMediaURL];
.// Save Your Stuff
.
.
MPMoviePlayerController *movieplayer =[[MPMoviePlayerController alloc] initWithContentURL: recordedVideoURL];
[[movieplayer view] setFrame:
[self.view bounds]];
[self.view addSubview:
[movieplayer view]];
[movieplayer play];
}
Edit:
For Uploading a Video, According to your code :
Declare the NSURL *recordedVideoURL;
-(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{
//NSLog(#"but ind %d", buttonIndex);
if (buttonIndex == uploadBTnIndex) {
NSData *videoData = [NSData dataWithContentsOfURL:recordedVideoURL];
//Use this NSData to upload, So what else your problem to upload using web Services ?
}
I know how to save a picture and this is the code until now. This code shows that the user taps a button and is able to take a photo.
-(IBAction)TakePhoto {
picker = [[UIImagePickerController alloc]init];
picker.delegate = self;
[picker setSourceType:UIImagePickerControllerSourceTypeCamera];
[self presentViewController:picker animated:YES completion:nil];
}
- (IBAction)ChooseExisting {
picker2 = [[UIImagePickerController alloc]init];
picker2.delegate = self;
[picker2 setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
[self presentViewController:picker2 animated:YES completion:nil];
}
- (void) imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
image = [info objectForKey:UIImagePickerControllerOriginalImage];
[imageview setImage:image];
//Save Your Image ======
UIImage *yourImage = imageview.image;//imageView.image;
NSString *docDirPath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
NSString *filePath = [docDirPath stringByAppendingPathComponent:#"myImageFile.png"];
[UIImagePNGRepresentation(yourImage) writeToFile:filePath atomically:YES];
[self dismissViewControllerAnimated:YES completion:nil];
}
- (void)imagePickerControllerDidCancel:(UIImagePickerController *)picker {
[self dismissViewControllerAnimated:YES completion:NULL];
}
However I want to sort my saved pictures into 6 Category or Genres which the user has to tap using the segment view control. Is this possible to do? I am very new in ios programming and objective-c in xcode and confused with many view controllers however I really like this to work and I a cannot find any resource about this topic. Thanks.
Here is a good demo for saving images to particular album using ALAssetsLibrary:
http://www.touch-code-magazine.com/ios5-saving-photos-in-custom-photo-album-category-for-download/
I hope it will help you out...
or
You can create different libraries using this piece of code:
-(void)createDirectory:(NSString *)directoryName atFilePath:(NSString *)filePath
{
NSString *filePathAndDirectory = [filePath stringByAppendingPathComponent:directoryName];
NSError *error;
if (![[NSFileManager defaultManager] createDirectoryAtPath:filePathAndDirectory
withIntermediateDirectories:NO
attributes:nil
error:&error])
{
NSLog(#"Create directory error: %#", error);
}
}
And fetch the images through their respective paths!!!
For more information see this: http://kmithi.blogspot.in/2012/08/ios-application-directory-structure.html
My app let the user take a picture, and add an overlay before saving it.
I'd like to let the user share his picture using whatever app able to handle images (i.e : email, facebook, twitter...), like an Intent on Android.
I tried to use UIDocumentController, but it doesn't show Facebook or Twitter as it does in the official gallery. It also makes my app crashes after taking the second picture.
Is there a simple way to do so ? I don't wan't to use the Facebook SDK and so on.
Here is what I do when the picture is taken :
[stillImageOutput captureStillImageAsynchronouslyFromConnection:videoConnection completionHandler:
^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
if(!error){
//Resize the picture and add the overlay
UIImage *picture = [self imageFromSampleBuffer:imageSampleBuffer];
//Custom code letting me save the picture in a specific album
[self.library saveImage:picture toAlbum:#"myApp" metadata:metadata withCompletionBlock:^(NSError *error,NSURL* assetURL) {
if (error!=nil) {
NSLog(#"Big error: %#", [error description]);
} else {
NSLog(#"Image Saved");
NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:#"tmp.jpg"];
//Only way to use UIDocumentController is to save the file at a known location
NSData* imagedata = UIImageJPEGRepresentation(picture, 0.9f);
[imagedata writeToFile:path atomically:NO];
NSLog(#"%#",path);
docController.URL = [NSURL fileURLWithPath:path];
// This make my app crash after the second picture
[docController presentPreviewAnimated:YES];
}
}];
} else {
NSLog(#"%#",error);
}
}];
iOS has an inbuilt social sharing kit. You can share images via Email, Facebook and Twitter. But for using Google+ and other social services you will need their respective SDKs.
1) For Facebook
SLComposeViewController *controller = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
[controller setInitialText:message];
[controller addImage:image];
[self presentViewController:controller animated:YES completion:Nil];
2) For twitter replace SLServiceTypeFacebook with SLServiceTypeTwitter.
3) For Email
MFMailComposeViewController *emailShareController = [[MFMailComposeViewController alloc] init];
emailShareController.mailComposeDelegate = self;
[emailShareController setSubject:#"Share Image"];
[emailShareController setMessageBody:message isHTML:NO];
[emailShareController addAttachmentData:UIImageJPEGRepresentation(image, 1) mimeType:#"image/jpeg" fileName:#"your_image.jpeg"];
if (emailShareController) [self presentViewController:emailShareController animated:YES completion:nil];
4) Remember to add Social.Framework to your project and the following header files
#import <MessageUI/MFMailComposeViewController.h>
#import <Social/Social.h>
#import <MobileCoreServices/MobileCoreServices.h>
5) Set your view controller as delegate of
MFMailComposeViewControllerDelegate
Dismiss MailViewController once mail is send-
- (void)mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
{
[self dismissViewControllerAnimated:YES completion:nil];
}
I'm trying to build an app that will display a collection of magazines that can be downloaded and then read. What I want to happen is if the magazine isn't downloaded, a download will commence when a cell is tapped and a progressview will appear in the corresponding cell showing the download progress. I have subclassed UICollectionViewCelland added a UIProgressView property. So far, I've been able to check whether the file is downloaded and if it isn't, download it, and if it is, just open it using a PDF library called VFR Library. I can also update a progress view placed outside of the UICollectionViewCell but I can't update one placed within the UICollectionViewCell. Unfortunately, most of my logic for downloading and updating the progressview is within didSelectItemAtIndexPath:. I know this isn't elegant but my experience level isn't high enough that I can effectively develop my own classes to work together seamlessly. But once I figure this out I'll work on refining the code and abstracting things away a bit. Anyway, here's what I'm doing in didSelectItemAtIndexPath:
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
IssueCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:#"Cell" forIndexPath:indexPath];
self.navBarLabel.hidden = YES;
self.mainProgressView.hidden = NO;
self.view.userInteractionEnabled = NO;
//self.activityIndicator.hidden = NO;
[self.activityIndicator startAnimating];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[[paths objectAtIndex:0] stringByAppendingPathComponent:[NSString stringWithFormat:#"issue%ld", (long)indexPath.row]]stringByAppendingPathExtension:#"pdf"];
if ([[NSFileManager defaultManager]fileExistsAtPath:path])
{
ReaderDocument *document = [ReaderDocument withDocumentFilePath:path password:nil];
if (document != nil)
{
//opens PDF for viewing
ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
readerViewController.delegate = self;
readerViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
readerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:readerViewController animated:YES completion:nil];
self.mainProgressView.hidden = YES;
self.navBarLabel.hidden = NO;
self.view.userInteractionEnabled = YES;
//self.activityIndicator.hidden = YES;
[self.activityIndicator stopAnimating];
}
}
else
{
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlArray[indexPath.row]]];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.outputStream = [NSOutputStream outputStreamToFileAtPath:path append:NO];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(#"Successfully downloaded file to %#", path);
ReaderDocument *document = [ReaderDocument withDocumentFilePath:path password:nil];
if (document != nil)
{
//opens PDF for viewing
ReaderViewController *readerViewController = [[ReaderViewController alloc] initWithReaderDocument:document];
readerViewController.delegate = self;
readerViewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
readerViewController.modalPresentationStyle = UIModalPresentationFullScreen;
[self presentViewController:readerViewController animated:YES completion:nil];
self.mainProgressView.hidden = YES;
self.navBarLabel.hidden = NO;
//self.activityIndicator.hidden = YES;
self.view.userInteractionEnabled = YES;
[self.activityIndicator stopAnimating];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Download Failed" message:#"There was a problem downloading this issue" delegate:self cancelButtonTitle:#"OK" otherButtonTitles: nil];
[alertView show];
self.mainProgressView.hidden = YES;
self.navBarLabel.hidden = NO;
[self.activityIndicator stopAnimating];
//self.activityIndicator.hidden = YES;
self.view.userInteractionEnabled = YES;
NSLog(#"Error: %#", error);
}];
[operation setDownloadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) {
float percentDone =((float)((int)totalBytesWritten) / (float)((int)totalBytesExpectedToWrite));
self.mainProgressView.progress = percentDone;
[cell.progressView setProgress:percentDone];
[self.collectionView reloadData];
// [cell.progressView performSelectorOnMainThread:#selector(loadingProgress:) withObject:[NSNumber numberWithFloat:percentDone] waitUntilDone:NO];
NSLog(#"Sent %lld of %lld bytes, %#", totalBytesWritten, totalBytesExpectedToWrite, path);
}];
[operation start];
}
}
So is there any way that I can update the progress view within a corresponding cell within this method or is there something else I need to do to get it to work? Thanks for any help you can give.
Well, I've finally solved my own problem. Apparently the problem was due to not fully understanding how to reference a particular item in a UICollectionView. All I had to do was create a method that actually did this and then call it in the "setDownloadProgressBlock:" method above. The method I wrote for this is:
- (void)setProgressAtIndex:(NSInteger)index withProgress:(float)progress
{
IssueCell *cell = (IssueCell *)[self.collectionView cellForItemAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]];
[cell.progressView setProgress:0.0];
[cell.progressView setProgress:progress];
}
The important line in this method is the first one where I grab a reference to the desired cell. This one actually grabs the cell that was tapped, whereas before I guess I was just referring to all the cells in general? I'm not too sure, but I would definitely appreciate it if someone had a better explanation.
This method was then called like so:
[self setProgressAtIndex:indexPath.row withProgress:percentDone];
Again, I did this inside the block in "setDownloadProgressBlock:".
Hopefully this helps someone else in the future!
Update your progress view on your main thread. Try using dispatch_sync(dispatch_get_main_queue()).