UIImagePickerController: Strange result of video compression - iphone

In my app, the user can either record a video or select one from his library. Naturally, I use a UIImagePickerController with it's sourceType set to either UIImagePickerControllerSourceTypeCamera or UIImagePickerControllerSourceTypePhotoLibrary.
The videoQuality is set to UIImagePickerControllerQualityTypeMedium in both cases.
Now, I did the following: I took a 15 sec video with my iPhone lying on it's back, so it's pitch-black. When I choose this video from the library, it is about 0.6 MB big. When I shoot the same video from within my app (15 sec, pitch-black), I get a file of over 4 MB.
Can anybody confirm this? I can hardly believe that I'm the first one to notice but then again, there is not much space for me to screw it up here (which I probably did nonetheless). Or does anybody have an explanation/solution for this?
(I'm at iOS 5.1 with an iPhone 4)

have you figured it out?
Now I have the same problem, a video in PhotoLibrary(2 minutes more); When I get it using UIImagePickerController, it's just about 30 Mb; But I get by the asset.defaultRepresentation(use this way(Getting video from ALAsset)), it reaches about 300Mb; Maybe the UIImagePickerController compressed the data in some way; I need to figure it out, but make no progress.......
================
EDIT: UIVideoEditorController can compress video to small size; and you can set the videoQuality just like UIImagePickerController.
maybe like this: when you use UIImagePickerController to chose a video, and set allowsEditing=YES, it will present UIVideoEditorController to compress video, then you get the compressed video in small size.

I've figured it out now. The solution is not to decrease the dimensions, but the bitrate. That is I think what Apple is doing when you select a video from the library.
Check out my answer here: https://stackoverflow.com/a/16035330/884119

Best way to compress the Video.
Here is the code.
-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{
NSString *tempFilePath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
NSData *data = [NSData dataWithContentsOfURL:videoURL];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSDate *now = [NSDate dateWithTimeIntervalSinceNow:0];
NSString *caldate = [NSString stringWithFormat:#"%#.mov",[now description]];
caldate = [caldate stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *path = [NSString stringWithFormat:#"%#/%#", documentsDirectory,caldate];
NSString *mediaType = [info objectForKey: UIImagePickerControllerMediaType];
NSURL *selectedVideoUrl;
if (CFStringCompare ((__bridge CFStringRef) mediaType, kUTTypeMovie, 0)
== kCFCompareEqualTo) {
tempFilePath = [[info objectForKey:UIImagePickerControllerMediaURL] path];
selectedVideoUrl = [info objectForKey:UIImagePickerControllerMediaURL];
}
NSLog(#"old move %#",path);
NSURL *url = [NSURL fileURLWithPath:tempFilePath];
[data writeToFile:path atomically:YES];
//Delete the original asset
NSArray *paths1 = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory1 = [paths1 objectAtIndex:0];
NSString *path1 = [NSString stringWithFormat:#"%#/%#", documentsDirectory1,caldate];
NSURL *url1 = [NSURL fileURLWithPath:path1];
NSLog(#"new move %#",path);
[self convertVideoToLowQuailtyWithInputURL:url outputURL:url1 handler:Nil];
[picker dismissModalViewControllerAnimated: YES];
}
-(void)convertVideoToLowQuailtyWithInputURL:(NSURL*)inputURL
outputURL:(NSURL*)outputURL
handler:(void (^)(AVAssetExportSession*))handler{
AVURLAsset *asset = [AVURLAsset URLAssetWithURL:inputURL options:nil];
AVAssetExportSession *exportSession = [[AVAssetExportSession alloc] initWithAsset:asset presetName:AVAssetExportPresetMediumQuality];
exportSession.outputURL = outputURL;
if ([[UIApplication sharedApplication]canOpenURL:inputURL]){
NSLog(#"open");
}
exportSession.outputFileType = AVFileTypeQuickTimeMovie;
NSLog(#"errrsfseSession %#", exportSession.error);
[exportSession exportAsynchronouslyWithCompletionHandler:^(void)
{
if(exportSession.status != AVAssetExportSessionStatusCompleted){
NSLog(#"exportSession %#", exportSession.error);
}
if (exportSession.status == AVAssetExportSessionStatusCompleted)
{
NSLog(#"doneszdfsadj");
}
}];
}

Related

UIImage gets corrupted while Downloading

I have developed iOS App, in which i am downloading image from server and saving it in my Document directory.
But problem which i am facing is, sometimes my images getting corrupted when i download, even if the server response isSuccessful.
Here is my code snippet,
urlFile is path of UIImage which is on server e.g: www.abcd.com/images/pqr.jpg
fileName which i am using for saving image name in my DocDirectory.
- (void)downloadFile:(NSString *)urlFile withName:(NSString *)fileName
{
NSString *trimmedString = [urlFile stringByTrimmingCharactersInSet:
[NSCharacterSet whitespaceAndNewlineCharacterSet]];
NSLog(#"trimmedString=%#",trimmedString);
if ([trimmedString length]>0)
{
HTTPEaterResponse *response = [HTTPEater get:[NSString stringWithFormat:#"%#",trimmedString]];
if ([response isSuccessful])
{
NSLog(#"isSuccessful");
[self saveImage:[[UIImage alloc] initWithData:[response body]] withName:fileName];
} else {
NSLog(#"Url response failed %#", [response description]);
}
}
}
- (void)saveImage:(UIImage *)image withName:(NSString *)name
{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSData *data = UIImagePNGRepresentation(image);
NSLog(#"image =%#",image);
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:name];
[fileManager createFileAtPath:fullPath contents:data attributes:nil];
}
When i see my Log, it shows:
trimmedString= www.abcd.com/images/pqr.jpg
isSuccessful
image =null
Thanks in advance.
I use the following code and it works for me.
NSData *thumbImageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:ImageURL]];
[thumbImageData writeToFile:cachedThumbnailFileName atomically:YES];
UIImage * image = [UIImage imageWithContentsOfFile:cachedThumbnailFileName];
imageView.image = image;
Hope it helps you. :)
To save image on directory use:
NSString *pngPath = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/Test.jpg"];
[UIImagePNGRepresentation(selectedImage) writeToFile:pngPath atomically:YES];
NSError *error;
NSFileManager *fileMgr = [NSFileManager defaultManager];
NSString *documentsDirectory = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents"];
have you logged the response [response body]?
Just try to convert that response as NSData and then save as image.
Using Base64Encoding class,you can convert the response as base64Data
NSData *imageData = [NSString base64DataFromString:[response body]];
[self saveImage:[[UIImage alloc] initWithData:imageData] withName:fileName];
i suggest yo use SDWebimage Class SDWebimage download.. i think its very helpful to you even i always prefer SDWebimage Library.
this are the some things.
An UIImageView category adding web image and cache management to the Cocoa Touch framework
An asynchronous image downloader
An asynchronous memory + disk image caching with automatic cache expiration handling
Animated GIF support
WebP format support
A background image decompression
A guarantee that the same URL won't be downloaded several times
A guarantee that bogus URLs won't be retried again and again
A guarantee that main thread will never be blocked
Performances!
Use GCD and ARC
instead u can use, "NSURLRequest" and "NSURLConnection"
for example if u get image URL then,
NSURL* aURL = [NSURL URLWithString:trimmedString];//get the url of string
NSURLRequest *aReq = [NSURLRequest requestWithURL:aURL];
NSURLConnection *aConnection = [NSURLConnection connectionWithRequest:aReq delegate:self]; //get a connection to url , since it confirms to delegate u need to implement delegate methods
if(aConnection == nil) //if it is nil then cancel and close the request
{
aConnection = nil;
[aConnection cancel];
}
// after this implement this delegate methods
- (void)connection:(NSURLConnection*)connection didReceiveData:(NSData*)received_data
{
if(image_data == nil) //if data is not initialised initialise it
{
image_data = [[NSMutableData alloc]init];
}
[self.image_data appendData:received_data];//append the received data
}
//this method is called after successful download of the image
- (void)connectionDidFinishLoading:(NSURLConnection *)connection;
{
// UIImage* sampleImage = [UIImage imageWithData:self.image_data];
// self.image = sampleImage; //convert the data to image
//since u hav complete downloaded date in "self.image_data"
NSString *imagePath = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:#"/myImage.png"];//set the name of the image and path may it saving in application directory check it out
[self.image_data writeToFile:imagePath atomically:YES]; //saving the data with name
}
Hope this helps u :)

Could not save .mp4 video file to iphone camera roll?

I received the video file contents in the format of NSData and I am playing that file in MPMoviePlayerController successfully with following code
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *FileExtension=[[NSString alloc]init];
if([contentType hasPrefix:#"video"] || [contentType isEqualToString:#"application/video"]) {
FileExtension=#"mov";
//FileExtension=#"mp4";
}
else
{
FileExtension=[contentType lastPathComponent];
}
//appFile is type of NSString.
appFile = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"MyFile.%#",FileExtension]];
//videoData is type of NSData
[videoData writeToFile:appFile atomically:YES];
NSURL *fileURL = [NSURL fileURLWithPath:appFile isDirectory:NO];
moviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
moviePlayerController.view.frame = self.view.bounds;
moviePlayerController.movieSourceType = MPMovieSourceTypeFile;
moviePlayerController.fullscreen = YES;
moviePlayerController.shouldAutoplay=NO;
[self.view addSubview:moviePlayerController.view];
[moviePlayerController prepareToPlay];
but I am unable to write/save this video file to camera roll,this is my code for writing code to the camera roll.
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
NSURL *filePathURL = [NSURL fileURLWithPath:appFile isDirectory:NO];
if ([library videoAtPathIsCompatibleWithSavedPhotosAlbum:filePathURL]) {
[library writeVideoAtPathToSavedPhotosAlbum:filePathURL completionBlock:^(NSURL *assetURL, NSError *error){
if (error) {
NSLog(#"Not success");
} else {
NSLog(#"success");
}
}];
}
this code is work fine when I set mimeType/file_format as .mov & .3Gp but I have problem related to save video to the camera roll when mimeType/file_format as .mp4 file.
You can convert your .mp4 to .mov if you change your appFile this way:
Your code:
appFile = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"MyFile.%#",FileExtension]];
New code:
appFile = [documentsDirectory stringByAppendingPathComponent:#"MyFile.mov"];
The SO automatically converts .mp4 to .mov

When we open pdf in iPhone then how to save this pdf in iphone

I am very new to iOS. I create PDF and load this PDF on UIWebView
now this time I want to save or download this PDF in iPhone when we tapped download button then all exits PDF supporter show like as open ibook ,open in chrome. This type of option show but when we tap any one then my application closed.
-(void)show_Button
{
NSArray *docDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDirectory = [docDirectories objectAtIndex:0];
NSString *filePAth = [docDirectory stringByAppendingPathComponent:#"myPDF.pdf"];
NSLog(#"filePath = %#", filePAth);
NSURL *url2 = [NSURL fileURLWithPath:filePAth];
NSLog(#"url2 = %#", url2);
UIDocumentInteractionController *docContr = [UIDocumentInteractionController
interactionControllerWithURL:url2];
docContr.delegate=self;
[docContr presentOpenInMenuFromRect:CGRectZero inView:self.view animated:YES];
}
so how to save or download this pdf in Iphone please solve this problem....
I believe you can simple use the belo two line:
NSData *myFile = [NSData dataWithContentsOfURL:[NSURL URLWithString:#"your_url"]];
[myFile writeToFile:[NSString stringWithFormat:#"%#/%#", [[NSBundle mainBundle] resourcePath], #"yourfilename.pdf"] atomically:YES];
I hope this it will help you,
Saving the pdf into app
NSData * imageData = [[NSData alloc] initWithContentsOfURL: [NSURL URLWithString: path]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"pdfname.pdf"];
NSError *writeError = nil;
[imageData writeToFile:filePath options:NSDataWritingAtomic error:&writeError];
if (writeError) {
NSLog(#"Error writing file: %#", writeError); }
Getting the pdf from the NSDocument Directory
NSString *stringPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)objectAtIndex:0];
NSArray *filePathsArray = [[NSFileManager defaultManager] subpathsOfDirectoryAtPath:documentsDirectory error:&error];
for(int i=0;i<[filePathsArray count];i++)
{
NSString *strFilePath = [filePathsArray objectAtIndex:i];
if ([[strFilePath pathExtension] isEqualToString:#"pdf"])
{
NSString *pdfPath = [[stringPath stringByAppendingFormat:#"/"] stringByAppendingFormat:strFilePath];
NSData *data = [NSData dataWithContentsOfFile:pdfPath];
if(data)
{
UIImage *image = [UIImage imageWithData:data];
[arrayOfImages addObject:image];
}
}
}

NOt able to convert from MPMediaItem(mp3 song) to NSData

I have tried following code :
These is my delegate method of MPMediPickerController :
- (void) mediaPicker: (MPMediaPickerController *) mediaPicker didPickMediaItems: (MPMediaItemCollection *) mediaItemCollection {
// Dismiss the media item picker.
[self dismissModalViewControllerAnimated: YES];
NSLog(#"%# %d",mediaItemCollection,mediaItemCollection.count);
NSArray *newMediaItem= [mediaItemCollection items];
MPMediaItem *item=[[newMediaItem objectAtIndex:0] retain];
[self uploadMusicFile:item];
}
This is my custom method MPMediaItem to NSData:
- (void) uploadMusicFile:(MPMediaItem *)song
{
NSURL *url = [song valueForProperty: MPMediaItemPropertyAssetURL];
AVURLAsset *songAsset = [AVURLAsset URLAssetWithURL: url options:nil];
AVAssetExportSession *exporter = [[AVAssetExportSession alloc] initWithAsset: songAsset
presetName: AVAssetExportPresetPassthrough];
exporter.outputFileType = #"public.mpeg-4";
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *exportFile = [documentsDirectory stringByAppendingPathComponent:
#"exported.mp4"];
NSURL *exportURL = [[NSURL fileURLWithPath:exportFile] retain];
exporter.outputURL = exportURL;
[exporter exportAsynchronouslyWithCompletionHandler:
^{
NSData *data = [NSData dataWithContentsOfFile: [documentsDirectory
stringByAppendingPathComponent: #"exported.mp4"]];
NSLog(#"%#",data);
}];
}
I am getting "null" in NSlog.
I have also check this post :
how to convert nsdata to MPMediaitem song iOS Sdk
but not getting solution.
I am using xcode 4.6 and ios 6.1.
Can any one tell me what is wrong here?

MPMoviePlayerController doesn't play newly saved video file

I'm using an imagePickerController to record video. In the imagePickerController:didFinishPickingMediaWithInfo: function I'm trying to set the video to a previously defined MPMoviePlayerController:
if ([mediaType isEqualToString:(NSString *)kUTTypeMovie]){
NSURL *movieUrl = [info objectForKey:UIImagePickerControllerMediaURL];
[self.moviePlayer setContentURL:movieUrl]];
}
This is working fine and the video is indeed playing.
But I want to save the file for later use. When I do this and use the saved file for the moviePlayer, nothing happens:
I've tried this (saving the data to a new file)
NSString *directory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *newPath = [directory stringByAppendingPathComponent:#"myMovie.mov"];
NSData *videoData = [NSData dataWithContentsOfURL:movieUrl];
[videoData writeToFile:newPath atomically:NO];
[self.moviePlayer setContentURL:[NSURL URLWithString:newPath]];
or this (copying the temp video file to my document folder)
NSString *directory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *newPath = [directory stringByAppendingPathComponent:#"myMovie.mov"];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSError *error = nil;
[fileManager copyItemAtPath:[videoUrl path] toPath:newPath error:&error];
[self.moviePlayer setContentURL:[NSURL URLWithString:newPath]];
Without any success, even though the file at newPath does exist... What am I doing wrong?
Ok I finally found the issue. The problem was not in fact with the MPMoviePlayerController but with the line:
[self.moviePlayer setContentURL:[NSURL URLWithString:newPath]];
I fixed it by replacing that line with:
[self.moviePlayer setContentURL:[NSURL fileURLWithPath:newPath isDirectory:NO]];
Hope that will help someone else!
use the code below:
NSData *movieData;
NSError *dataReadingError = nil;
movieData = [NSData dataWithContentsOfURL: movieURL options:NSDataReadingMapped error:&dataReadingError];
if(movieData != nil)
NSLog(#"Successfully loaded the data.");
else
NSLog(#"Failed to load the data with error = %#", dataReadingError);