Showing video and images - objective-c

I have my video and images stored in the NSData format in a cache.I want to retrieve the image and show it on imageController also want to retrieve video and and show it on videoController.
I can distinguish them by looking towards the file extension. But the problem is in imageController i can init image by using the NSData:
NSData *data=[NSData dataWithContentsOfURL:[NSURL fileURLWithPath:filePath isDirectory:NO]];
UIImage *image=[[UIImage alloc]initWithData:data];
But how can i use the NSData to play the video?

If you can get their path extensions, you can just use separate implementations for each type. No need to have one way down the road, eh?
-(void)example:(NSString*)filePath {
if ([filePath.pathExtension isEqualToString:#"png"]) {
NSData *data=[NSData dataWithContentsOfURL:[NSURL fileURLWithPath:filePath isDirectory:NO]];
UIImage *image=[[UIImage alloc]initWithData:data];
} else if ([filePath.pathExtension isEqualToString:#"mp4"]) {
MPMoviePlayerController *player =
[[MPMoviePlayerController alloc] initWithContentURL: [NSURL urlWithString:filePath]];
[player prepareToPlay];
[player.view setFrame: myView.bounds]; // player's frame must match parent's
[myView addSubview: player.view];
// ...
[player play];
}
}

Related

Caching and saving videos in tableview

I'm displaying videos with tableview and would like to save urls/data in cache so user won't have to download the same video again when replayed.
However I'd like to keep them only until user quits the app. The next time he opens the app he'll have to download them again so I only need to save them for the app's active lifetime.
Should I still do caching or is there a more efficient way to do this?
-(void)loadVideo:(NSString *)urlString {
NSURL *url = [NSURL URLWithString:urlString];
NSString* cachePath = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString* file = [cachePath stringByAppendingPathComponent:#"/EGOCache.plist"];
NSDictionary *dict =[NSDictionary dictionaryWithContentsOfFile:file];
if ([dict objectForKey:urlString] )
{
NSData *data = [[EGOCache globalCache] dataForKey:urlString];
data = [NSURLConnection sendSynchronousRequest:
[NSURLRequest requestWithURL:url]
returningResponse:nil
error:nil];
NSLog(#"loading from cache %#",urlString);
}else{
NSData *data = [NSURLConnection sendSynchronousRequest:
[NSURLRequest requestWithURL:url]
returningResponse:nil
error:nil];
[[EGOCache globalCache] setData:data forKey:urlString];
NSLog(#"saving cache %#",urlString);
}
NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval: 10.0];
[self.videoPlayer setContentURL:[request URL]];}
AVFoundation allows for streaming a video file on disk.
I suggest you look into saving the video in the Documents folder or Caches folder and steam it to AVFoundation from there. Then when the user quits the app, applicationWillTerminate gets called and you can wipe the videos from disk.
EDIT
Using MPMoviePlayerController:
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL: URL-TO-FILE-ON-DISK];
[player prepareToPlay];
[player.view setFrame: myView.bounds]; // player's frame must match parent's
[myView addSubview: player.view];
// ...
[player play];

Generating thumbnail from video - ios7

I am using this for reference: Getting thumbnail from a video url or data in IPhone SDK
The method is using the MPMoviePlayerController class instead of the AVFoundation, and I think I want to use that as well because the people said that MPMoviePlayer way is faster than the AVFoundation way.
The problem is, the method used to create the thumbnails, [player thumbnailImageAtTime:1.0 timeOption:MPMovieTimeOptionNearestKeyFrame] is deprecated in iOS 7.0.
By looking at the apple docs, the remaining supported ways to create thumbnails are by the methods (void)requestThumbnailImagesAtTimes:(NSArray *)playbackTimes timeOption:(MPMovieTimeOption)option and (void)cancelAllThumbnailImageRequests. But, as the method signatures dictate, these methods return nothing. So how do I access the UIImage thumbnail created by these methods?
If it helps, this is what I have so far in terms of code:
self.videoURL = info[UIImagePickerControllerMediaURL];
NSData *videoData = [NSData dataWithContentsOfURL:self.videoURL];
//Create thumbnail image
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:self.videoURL];
[player requestThumbnailImagesAtTimes:#[#1] timeOption:MPMovieTimeOptionNearestKeyFrame];
//UIImage *thumbnail = ???
How do I get a UIImage reference to the thumbnail?
EDIT
I figured out how to create a notification for the thumbnail image request (using this question as reference). However, I realise that this method works asynchronously from the main thread, and so my notification handler method doesn't seem to ever be called.
This is what I have now.
self.videoURL = info[UIImagePickerControllerMediaURL];
NSData *videoData = [NSData dataWithContentsOfURL:self.videoURL];
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:self.videoURL];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(handleThumbnailImageRequestFinishNotification:) name:MPMoviePlayerThumbnailImageRequestDidFinishNotification object:player];
[player requestThumbnailImagesAtTimes:#[#1] timeOption:MPMovieTimeOptionNearestKeyFrame];
And then my handler method:
-(void)handleThumbnailImageRequestFinishNotification:(NSNotification*)notification
{
NSDictionary *userinfo = [notification userInfo];
NSError* value = [userinfo objectForKey:MPMoviePlayerThumbnailErrorKey];
if (value != nil)
{
NSLog(#"Error creating video thumbnail image. Details: %#", [value debugDescription]);
}
else
{
UIImage *thumbnail = [userinfo valueForKey:MPMoviePlayerThumbnailImageKey];
}
But the handler never gets called (or so it appears).
Try this way.
import AVFoundation framework
in *.h
#import <AVFoundation/AVFoundation.h>
in *.m
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:self.urlForConevW options:nil];
AVAssetImageGenerator *generateImg = [[AVAssetImageGenerator alloc] initWithAsset:asset];
NSError *error = NULL;
CMTime time = CMTimeMake(1, 65);
CGImageRef refImg = [generateImg copyCGImageAtTime:time actualTime:NULL error:&error];
NSLog(#"error==%#, Refimage==%#", error, refImg);
UIImage *FrameImage= [[UIImage alloc] initWithCGImage:refImg];
Here is a code to make a thumbnail of the video and save the images to the DocumentDirectory..
//pass the video_path to NSURL
NSURL *videoURL = [NSURL fileURLWithPath:strVideoPath];
AVURLAsset *asset1 = [[AVURLAsset alloc] initWithURL:videoURL options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset1];
generator.appliesPreferredTrackTransform = YES;
//Set the time and size of thumbnail for image
NSError *err = NULL;
CMTime thumbTime = CMTimeMakeWithSeconds(0,30);
CGSize maxSize = CGSizeMake(425,355);
generator.maximumSize = maxSize;
CGImageRef imgRef = [generator copyCGImageAtTime:thumbTime actualTime:NULL error:&err];
UIImage *thumbnail = [[UIImage alloc] initWithCGImage:imgRef];
//And you can save the image to the DocumentDirectory
NSData *data = UIImagePNGRepresentation(thumbnail);
//Path for the documentDirectory
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
[data writeToFile:[documentsDirectory stringByAppendingPathComponent:currentFileName] atomically:YES];
If your URL is to an HTTP live stream, then it won't return anything, per the docs. For a file URL, I found that I had to start the request after playing the movie, or it would never get called.

MPMoviePlayerController generate thumbnail of local video file and store it

I'm making an app that downloads movies from the server and stores them localy in the NSDocumentDirectory.
This works fine.
I want to add a thumbnail generated from each movie in front of the name in each cell.
My problem:
How can I generate a thumbnail from a movie after it is downloaded (so instantly, without having to play the movie first)? I want to store the thumbnails with the same name of the movie as a jpg in the NSDocumentDirectory.
My guess
-download movie and store it in NSDocumentDirectory (works)
-somehow load the movie in the MPMoviePlayerController's memory (don't know how)
-when loaded in memory, generate thumbnail with thumbnailImageAtTime (MPMovieTimeOptionNearestKeyFrame) (should work)
-store it (should work)
If anyone could help me...
Thanks
#import <MediaPlayer/MediaPlayer.h>
-(UIImage*)getFirstFrameFromVideoFile:(NSString*)sourceFilePath {
NSURL *videoURL = [NSURL fileURLWithPath:sourceFilePath];
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
UIImage *thumbnail = [player thumbnailImageAtTime:1.0 timeOption:MPMovieTimeOptionNearestKeyFrame];
//Player autoplays audio on init
[player stop];
[player release];
return thumbnail;
}
Other tasks you know already.
Yes, using MPMoviePlayer works... but you must be sure that you do not have another movie player playing elsewhere in your app (even the UIWebView plug-in...) or you will get in trouble.
I do this way:
UIImage *thumbnail = nil;
NSURL *url = [NSURL fileURLWithPath:pathname];
AVURLAsset *asset = [[AVURLAsset alloc] initWithURL:url options:nil];
AVAssetImageGenerator *generator = [[AVAssetImageGenerator alloc] initWithAsset:asset];
generator.appliesPreferredTrackTransform = YES;
NSError *error = nil;
CMTime time = CMTimeMake(3, 1); // 3/1 = 3 second(s)
CGImageRef imgRef = [generator copyCGImageAtTime:time actualTime:nil error:&error];
if (error != nil)
NSLog(#"%#: %#", self, error);
thumbnail = [[UIImage alloc] initWithCGImage:imgRef];
CGImageRelease(imgRef);
Hope this might help
This is the code I use which should generate the thumbnail
(added a big uiimageview for testing, works when I load a local image in it)
NSString *path;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
path = [[paths objectAtIndex:0] stringByAppendingPathComponent:#"snijtechniekendir/videos"];
path = [path stringByAppendingPathComponent:[videos objectAtIndex:indexPath.row]];
NSURL *videoURL = [NSURL fileURLWithPath:path];
NSLog(#"video url: %#", videoURL);
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:videoURL];
UIImage *thumbnail = [player thumbnailImageAtTime:1 timeOption:MPMovieTimeOptionNearestKeyFrame];
UIImageView *cellimage = [[UIImageView alloc] initWithFrame:CGRectMake(2, 2 , 400, 400)];
[cell.contentView addSubview:cellimage];
NSData *imgData = UIImagePNGRepresentation(thumbnail);
NSLog(#"lenght of video thumb: %#", [imgData length]);
[self.view addSubview:cellimage];
[cellimage setImage:thumbnail];
This is the log for one video file
video url: file://localhost/Users/Home/Library/Application%20Support/iPhone%20Simulator/5.1/Applications/78C165BB-75A9-46A2-A257-469F8652A665/Documents/snijtechniekendir/videos/snijtechniek%2520brunoise.mp4
lenght of video thumb: (null)

How can I create custom Ads in my iPhone app?

I am developing an iPhone app for my University radio station, and I would like to insert ads (that look and feel just like iAds) but with my own custom designs/content/links so I can sell this adspace to possible sponsors.
Would anyone know how I can do this or point me in the right direction? I am building a "utility" style app.
I have a JSON file on my server with certain data about the ad (mine happens to be set up for one, but you could accomodate multiple the same way).
{"promo":"yes","imageURL":"http://somedomain/testAd.png","image2xURL":"http://somedomain/testAd#2x.png","link":"http://www.whereTheAdShouldDirect.com"}
Then, in the app, I have this amongst the rest of viewWillAppear:
NSURL *url = [NSURL URLWithString:#"http://www.mydomain/promo.php"];
NSString *response = [[NSString alloc] initWithContentsOfURL:url];
const char *convert = [response UTF8String];
NSString *responseString = [NSString stringWithUTF8String:convert];
NSDictionary *promo = [responseString JSONValue];
[response release];
if([[promo objectForKey:#"promo"] isEqualToString:#"yes"]){
self.linkURL = [NSURL URLWithString:[promo objectForKey:#"link"]];
NSURL *picURL = [NSURL URLWithString:[promo objectForKey:#"imageURL"]];
if([[[UIDevice currentDevice] systemVersion]intValue]>=4){
if([[UIScreen mainScreen] scale]==2.0){
picURL = [NSURL URLWithString:[promo objectForKey:#"image2xURL"]];
}
}
CGRect imgFrame = CGRectMake(0, 0, 320, 50);
UIButton *adImage=[[UIButton alloc] initWithFrame:imgFrame];
NSData * imageData = [NSData dataWithContentsOfURL:picURL];
UIImage * image = [UIImage imageWithData:imageData];
[adImage setBackgroundImage:image forState:UIControlStateNormal];
[adImage addTarget:self action:#selector(ad) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:adImage];
[adImage release];
}
and this method as well:
-(void)ad{
[[UIApplication sharedApplication] openURL:self.linkURL];
}
You may want to change that last method depending on how you want the ad to react (load a webview right in the app?)

how to convert nsdata to image?

I am developing an application in which I take NSData and convert it into image an display it in the image view. Now i want to save this data and display it again in UIImageView.
I used NSUserDefaults to save the NSData and again retrieve this data and convert into image and display it in image view.But i am not getting the image back.my code is as follows:
//for saving nsdata using nsuserdefaults method:-
NSUserDefaults *defsMVC=[NSUserDefaults standardUserDefaults];
[defsMVC setObject:stateMVC forKey:#"MapImageObject"];
//for retrieving nsdata from nsuserdefaults and display it in imageview
NSUserDefaults *defsMVC=[NSUserDefaults standardUserDefaults];
NSData *stringmapdata=[defsMVC dataForKey:#"MapImageObject"];
UIImageView *imageView=[[UIImageView alloc]initWithFrame:CGRectMake(0, 6, 320,415)];
UIImage *image = [UIImage imageWithData:stringmapdata];
[imageView setImage:image];
[image release];
[self.view addSubview:imageView];
[self.view sendSubviewToBack:imageView];
[imageView release];
I don't think you should be storing the data in the user Defaults, try storing it in a file like "yourimage.png", then you can simply do [[NSImage alloc] initWithConentsOfFile:path];
Also try using NSArchiver before saving it in the user defaults:
NSImage *image = [NSUnarchiver unarchiveObjectWithData:[[NSUserDefaults standardUserDefaults] objectForKey:#"someKey"]];
And for archiving it to the user defaults:
[[NSUserDefaults standardUserDefaults] setObject:[NSArchiver archivedDataWithRootObject:image] forKey:#"someKey"];
Gotta love Cocoa =)
My image is stored in 6th column in a form of NSData, first I have to get that data into NSData object. Than convert that NSData into image.
data = [[NSData alloc] initWithBytes:sqlite3_column_blob(statement, 6)
length:sqlite3_column_bytes(statement, 6)];
img = [UIImage imageWithData:data];
imgdata = [[NSMutableArray alloc]initWithObjects:img, nil];