MPMoviePlayerController doesn't play newly saved video file - iphone

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);

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 :)

AVAudioPlayer play from buffer

I want to stream audio file from google drive, the only method from google drive sdk from which I can track what is downloaded is [fetcher setReceivedDataBlock:^(NSData *dataReceivedSoFar), so I implemented something like this, but I am not so sure if this is a good solution so I am asking an advice from you guys.
Ok, since I can only get dataReceivedSoFar, I am deleting the already downloaded data from it, and then appending the new data to saved data, and start playing with AVAudioPlayer when the data length is greater than 100 000 bytes.
Please tell me if this is a good solution and if you have some advice regarding it.
Code:
GTMHTTPFetcher *fetcher =
[[self driveService].fetcherService fetcherWithURLString:song.filePath];
NSArray *myPathList = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDir = [myPathList objectAtIndex:0];
NSString *songPath = [[NSString alloc] initWithString: [cachesDir stringByAppendingPathComponent:[NSString stringWithFormat:#"Song.%#", [song.name pathExtension]]]];
[fetcher setReceivedDataBlock:^(NSData *dataReceivedSoFar) {
NSFileManager *filemgr;
filemgr = [NSFileManager defaultManager];
if (![filemgr fileExistsAtPath: songPath ] == YES)
[filemgr createFileAtPath:songPath contents:nil attributes:nil];
NSData *currentData = [NSData dataWithContentsOfFile:songPath];
NSLog(#"LENGTH: %d", currentData.length);
NSMutableData *mutableData = [NSMutableData dataWithData:dataReceivedSoFar];
if (currentData.length > 0) {
[mutableData replaceBytesInRange:NSMakeRange(0, [currentData length]) withBytes:NULL length:0];
}
NSFileHandle *handle = [NSFileHandle fileHandleForUpdatingAtPath:songPath];
[handle seekToEndOfFile];
[handle writeData:mutableData];
//[handle synchronizeFile];
[handle closeFile];
if (!self.audioPlayer.playing && dataReceivedSoFar.length > 100000)
{
NSURL *URL = [NSURL fileURLWithPath:songPath];
self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:URL error:nil];
[self.audioPlayer play];
NSLog(#"Audio player started playing");
}

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];
}
}
}

Too much time to get and merge video frames and write movies

I am building an app in which I have to get a thumbnail from a recorded video. I have an array of alpha video frames. I have to merge each set of frames and then make a movie with these final frames. Here is the piece of code I am dealing with:
-(void)createFrameForVideo
{
NSString *filePath = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:#"/Documents/movie.mp4"]];
NSURL *outputURL = [NSURL fileURLWithPath:filePath];
player = [[MPMoviePlayerController alloc]initWithContentURL:outputURL];
float frame = 0.00;
int count = 14;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
docPath = [docPath stringByAppendingPathComponent:#"OutPut"];
BOOL success = [fileManager fileExistsAtPath:docPath];
if (success) {
[fileManager removeItemAtPath:docPath error:nil];
}
[fileManager createDirectoryAtPath:docPath withIntermediateDirectories:YES attributes:nil error:nil];
for (frame = (frameStartTime); frame < (frameStartTime+7); frame+=0.033)
{
#autoreleasepool
{
UIImage * singleFrameImage = [player thumbnailImageAtTime:frame timeOption:MPMovieTimeOptionExact];
[player pause];
NSString *imageName = [NSString stringWithFormat:#"export2%d.png",count];
NSString * file = [[NSBundle mainBundle]pathForResource:imageName ofType:nil];
UIImage *overlayImage = [UIImage imageWithData:[NSData dataWithContentsOfFile:file]];
count = count + 1;
NSString *imagePath = [NSString stringWithFormat:#"%#/%#", docPath, imageName];
if (overlayImage)
{
UIImage * outImage = [self mergeImage:singleFrameImage withImage:overlayImage];
NSData *imgData = [[NSData alloc] initWithData:UIImagePNGRepresentation(outImage)];
[fileManager createFileAtPath:imagePath contents:imgData attributes:nil];
[imgData release];
}
else
{
NSData *imgData = UIImagePNGRepresentation(singleFrameImage);
[fileManager createFileAtPath:imagePath contents:imgData attributes:nil];
}
[outputFramesArray addObject:imagePath];
}
}
[player release];
if([fileManager fileExistsAtPath:filePath])
{
[fileManager removeItemAtPath:filePath error:nil];
}
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:#"/Documents/movie1.mp4"]];
NSLog(#"filePath %#", path);
if ([[NSFileManager defaultManager] fileExistsAtPath:path]) {
[[NSFileManager defaultManager] removeItemAtPath:path error:nil];
}
[self writeImageAsMovie:outputFramesArray toPath:path size:CGSizeMake(480, 320) duration:10];
NSLog(#"hello Your layering is completed");
[outputFramesArray removeAllObjects];
[outputFramesArray release];
success = [fileManager fileExistsAtPath:docPath];
if (success) {
[fileManager removeItemAtPath:docPath error:nil];
}
//[self performSelectorOnMainThread:#selector(CompileFilesToMakeMovieWithAudio) withObject:Nil waitUntilDone:YES];
[self CompileFilesToMakeMovieWithAudio];
// [self compileFinalOutputMovie];
}
The problem is its taking much time to deal with frames in the whole loop. Could anyone please help speed up the process. I already have tried ffmpeg, but I think the problem is in merging. If anyone has suggestions, please share them.
Try using instruments to see where your memory is getting tied up and if there are any leaks.
I had a similar problem recently with leaks in a piece of code that ran constantly in a loop like that. Changing the local variables into instance variables and then just reusing the variable kept it from allocating too much memory for the application.
Your issue is one of basic approach. If you want to get better execution time then you need to change the basic way you app works. There is not a specific "change this code" step that will make your existing code execute faster.
What you should try is to encode the video frame and then write directly into the compiled h.264, instead of what you do now which is to create each frame and then combine them all together at the end in another loop. Like so:
1: Read Input PNG
2: Read Video Frame
3: Combine Video frame and input PNG
4: Write combined frame to movie via AVAsset apis.
That avoids having to read each frame 2 times and it avoids writing all the PNG images to disk again. IO takes a lot of time and compressing the images to PNG takes a lot of time. The suggested approach would be a lot faster because it would avoid these unneeded steps.