How to target NSNotification for different MPMoviePlayerControllers? - iphone

I'm trying to create an app that displays a unique info page after different videos play. Currently, I am displaying the info page with the moviePlayBackDidFinish notification method but I can't figure out how to customize it for different videos. Here's my code...thanks very much in advance!!
EDIT after subclassing movieplayercontroller...how do I use new property in NSNotification?
//subclassed movieplayercontroller
myMovie.h
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#interface myMovie: MPMoviePlayerViewController
{
myMovie *videoPlayer;
}
#property (nonatomic, strong) NSString *movieTitle;
#end
myMovie.m
#import "myMovie.h"
#interface myMovie ()
#end
#implementation myMovie
#synthesize movieTitle;
#end
//main viewcontroller
videoPlayViewController.h
#import <UIKit/UIKit.h>
#import <MediaPlayer/MediaPlayer.h>
#import "View2.h"
#import "myMovie.h"
#interface videoPlayViewController : UIViewController
-(IBAction) playMovie;
videoPlayViewController.m
#import "videoPlayViewController.h"
#import "myMovie.h"
#interface videoPlayViewController ()
#end
#implementation videoPlayViewController
-(void)playMovie
{
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"sample" ofType:#"mov"]];
myMovie *videoPlayer = [[myMovie alloc]
initWithContentURL:url];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:videoPlayer.moviePlayer];
videoPlayer.moviePlayer.controlStyle = MPMovieControlStyleDefault;
videoPlayer.moviePlayer.shouldAutoplay = NO;
videoPlayer.movieTitle = #"sample";
[self.view addSubview:videoPlayer.view];
[videoPlayer.moviePlayer setFullscreen:YES animated:YES];
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification {
MPMoviePlayerController *player = [notification object];
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:player];
NSLog(#"Is this working?");
View2 *second =[[View2 alloc] initWithNibName:nil bundle:nil];
[self presentModalViewController:second animated:YES];
[player.view removeFromSuperview];
}

Create a subclass of MPMoviePlayerController with a property (or many properties) to hold the info that you need when the video ends. Then, when the video ends, you'll get your customized MPMoviePlayerController in the notification object, and you can inspect the properties to find out whatever it was that you wanted to know about the movie that ended.

Related

Hide/Unhide IBOutlet(UIButton) when a IAP is complete

Alright, so I've been toying around with this for a couple days now and I haven't gotten this to work, looking to you for help!
Basically I want to "Unlock" a feature once an IAP is done. I've got the IAP code to work, but I want to change the button "sendMail" ('disabled' in Interface Builder) so that the user can interact with it.
//InputViewController.h
#import "IAPStore.h"
#interface InputViewController : UIViewController <MFMailComposeViewControllerDelegate, UIAlertViewDelegate>
#property(strong,nonatomic)IBOutlet UIButton *sendMail;
-(void)enableMail;
....
#end
//InputViewController.m
#import "InputViewController.h"
#import "IAPStore.h"
-(void)enableMail
{
[_sendMail setEnabled:YES];
NSLog(#"Unlocking Button");
}
//IAPStore.h
#import "InputViewController.h"
#interface IAPHelper : NSObject <UIAlertViewDelegate>
-(void)purchaseComplete;
...
#end
//IAPStore.m
#import "InputViewController.h"
-(void)purchaseComplete
{
UIAlertView *purchased = [[UIAlertView alloc]initWithTitle:#"In-App Purchase" message:#"Purchase complete! Thank you!" delegate:nil
cancelButtonTitle:#"OK" otherButtonTitles:nil];
GROWInputViewController *viewController = [[GROWInputViewController alloc] init];
[viewController enableMail];
[purchased show];
NSLog(#"button enabled");
}
So it prints out too the log but nothing is changed on the other view controller, but nothing is changed, any idea to what I'm doing wrong?
You could use NSNotificationCenter
In the viewDidLoad: method of InputViewController.m add this line of code:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(enableMail) name:#"purchaseCompleteNotification" object:nil];
And in the purchaseComplete method of IAPStore.m, replace this:
GROWInputViewController *viewController = [[GROWInputViewController alloc] init];
[viewController enableMail];
with this:
[[NSNotificationCenter defaultCenter] postNotificationName:#"purchaseCompleteNotification" object:nil];
This will cause a notification to be posted when the purchase is complete. Meanwhile, InputViewController has an 'observer' that is set to call your 'enableMail' method when that notification is posted.
Also, you'll want to add this method to your InputViewController.m, so that he is removed as an observer when deallocated.
-(void)dealloc{
[[NSNotificationCenter defaultCenter] removeObserver:self name:#"purchaseCompleteNotification" object:nil];
}

Viewing YouTube video inside app with return to previous ViewControlloer

I'm trying to integrate in my app a youtube video. But I want it to resume to the calling viewController when video finished. I've succeeded to almost implement that but in my way the user must press done button and then another to get back to the original ViewController.
This is the code I use, Please help, I prefer with ref to full code or code example.
YouTubeView.h :
#import <UIKit/UIKit.h>
#interface YouTubeView : UIWebView
{
}
- (YouTubeView *)initWithStringAsURL:(NSString *)urlString frame:(CGRect)frame mimeSubType:(NSString *)mimeType;
#end
YouTubeView.m :
#import "YouTubeView.h"
#interface YouTubeView ()
#end
#implementation YouTubeView
- (YouTubeView *)initWithStringAsURL:(NSString *)urlString frame:(CGRect)frame mimeSubType:(NSString *)mimeType
{
NSString *strMimeType;
if([mimeType length]>0)
{
strMimeType = mimeType;
}
else
{
strMimeType =#"x-shockwave-flash"; //#"x-shockwave-mp4";
}
if (self = [super init])
{
// Create webview with requested frame size
self = [[UIWebView alloc] initWithFrame:frame];
// HTML to embed YouTube video
NSString *videoHTML = [NSString stringWithFormat:#"\
<html>\
<head>\
<style type=\"text/css\">\
iframe {position:absolute; top:50%%; margin-top:-130px;}\
body {background-color:#000; margin:0;}\
</style>\
</head>\
<body>\
<iframe width=\"100%%\" height=\"240px\" src=\"%#\" frameborder=\"0\" allowfullscreen></iframe>\
</body>\
</html>", urlString];
[self loadHTMLString:videoHTML baseURL:nil];
}
return self;
}
- (void)dealloc
{
[super dealloc];
}
#end
And a button that points to *on main ViewController :
-(IBAction)runTestVideo:(id)sender {
NSString *strNormalVdoURL = [NSString stringWithFormat:#"http://www.youtube.com/embed/TgLqH9n57B0"];
YouTubeView *videoVw = [[YouTubeView alloc] initWithStringAsURL:[NSString stringWithFormat:#"%#",strNormalVdoURL] frame:CGRectMake(0,0,315,420) mimeSubType:#"x-shockwave-flash"];
[self.view addSubview:videoVw];
[videoVw release];
videoVw = nil;
}
Please help.
I'm not quite sure if my method would work on yours as for mine, I had the view hidden when the video is playing. After the user pressed the done button, the movie controller will exit and the view is shown.
- (void)viewDidLoad {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector (MPMoviePlayerDidExitFullScreen;) name:MPMoviePlayerDidExitFullscreenNotification object:nil];
}
- (void)MPMoviePlayerDidExitFullScreen:(NSNotification *)notification {
[[NSNotificationCenter defaultCenter] removeObserver:self name: MPMoviePlayerDidExitFullscreenNotification object:nil];
[movieController stop];
[movieController.view removeFromSuperview];
view.hidden = NO;
}

MPMoviePlayerViewController movie plays without being asked

I have a problem using MPMoviePlayerViewController. I'm trying to initialize the movie on viewDidLoad and then play the movie on touchesBegan. But the movie initially starts playing and on touchesBegan it only shows the finished movie.
ViewController.h file
#interface ViewController : UIViewController{
MPMoviePlayerController *moviePlayer;
MPMoviePlayerViewController *mpviewController;
MPMovieControlStyle controlStyle;}
- (IBAction)touchesBegan:(id)sender;
#property (nonatomic) MPMovieControlStyle controlStyle;
#end
ViewController.m
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
[self.view addSubview:mpviewController.view];
[moviePlayer play]; }
- (void)viewDidLoad
{
NSString *movpath = [[NSBundle mainBundle]
pathForResource:#"my_moviefile"
ofType:#"m4v"];
mpviewController =
[[MPMoviePlayerViewController alloc]
initWithContentURL:[NSURL fileURLWithPath:movpath]];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:#selector(movieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:mpviewController];
MPMoviePlayerController *mp = [mpviewController moviePlayer];
// [mp setMovieControlMode:MPMovieControlModeHidden];
// [mp.view setFrame:CGRectMake(0, 0, 250, 263)];
mp.controlStyle = MPMovieControlStyleNone;
[mp prepareToPlay];
[super viewDidLoad];
}
If I put all the code in touchesBeganit works as expected, but the movie still has to load, but I want to preload it and then do something again when it finished playing.
Any clues?
Regards
Consider putting your [super viewDidLoad] at the top of your viewDidLoad implementation. This often causes unpredictable problems.
Also, just try adding [mp pause] and mp.currentPlaybackTime = 0; at the end of viewDidLoad.
Make sure you set MPMoviePlayerController's property shouldAutoplay to NO when initializing the player.
From the Reference:
shouldAutoplay
A Boolean that indicates whether a movie should begin playback automatically.
#property (nonatomic) BOOL shouldAutoplay
Discussion
The default value of this property is YES. This property determines
whether the playback of network-based content begins automatically
when there is enough buffered data to ensure uninterrupted playback.
Availability
Available in iOS 3.2 and later.
Declared In
MPMoviePlayerController.h

Calling another UIViewController

I'm in a UITableView and the user has watched a video. After the video I would like the user to take a test. Just can't figure out how to call this view controller so I can start the test.
Im in the PlayListViewController and want to call the TestViewController.
The TestViewController.h is imported. At this stage all there is in the TestViewController is what comes with UIViewController and some stuff that I added in .xib. The test coding isn't done yet (that will be the next problem).
I would greatly appreciate if someone has the time to give me directions.
-(void) movieFinishedPlaying: (NSNotification *) note {
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:[player moviePlayer]];
[player release];
NSLog(#"Video has finished playing\n");
// To the test
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Info"
message:#"Now for the test!"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil];
[alert show];
[alert release];
// Call on test here
TestViewController *testVC = [[TestViewController alloc] init];
[self presentModalViewController:testVC animated:YES];
[testVC release];
}
I have this in the TestViewController.h
#import <UIKit/UIKit.h>
#interface TestViewController : UIViewController {
UIWindow *tVC;
UIViewController *testVC;
}
#property (nonatomic, retain) IBOutlet UIWindow *tVC;
#property (nonatomic, retain) IBOutlet UIViewController *testVC;
#end
And this in the m file
#import "TestViewController.h"
#implementation TestViewController
#synthesize testVC, tVC;
Register for MPMoviePlayerPlaybackDidFinishNotification notification before playing video (I guess you are using MPMoviePlayerController to play video, right?):
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playerPlaybackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:playerViewController];
and when it get's fired, present him the instance of TestViewController modally and unregister the notification:
- (void)playerPlaybackDidFinish:(NSNotification*)notification
{
TestViewController *testVC = [[TestViewController alloc] init];
[self presentModalViewController:testVC animated:YES];
[testVC release];
[[NSNotification defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification object:playerViewController];
}
presentModalViewController is deprecated in ios 6 so now it is
ViewController *vc = [[ViewController alloc]init];
[self presentViewController:vc animated:YES completion:NULL];

on iphone, how can i stream several videos one after one?

Right now i am use using mpmovieplayercontroller, but i need to close mpmovieplayercontroller for play another video.
Is there a way to play several videos without closing the mpmovieplayercontroller?
thx
You can subscribe to your MPMoviePlayerController's MPMoviePlayerPlaybackDidFinishNotification notification.
For example, you have:
// this is a PoC code, you can do it a lot cleaner
// in your .h
#property (nonatomic, retain) MPMoviePlayerController *moviePlayer;
#property (nonatomic, retain) NSMutableArray *movieUrls;
int indexPlayed;
// in your .m
- (void)setupPlayer { // or in your constructor, viewDidLoad, etc
moviePlayer = [[MPMoviePlayer alloc] init];
movieUrls = [NSMutableArray arrayWithObjects:nil, nil, nil]; // add your movie NSURLs here
indexPlayed = 0;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playerPlay:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
[self playerPlay:nil];
}
- (void)playerPlay:(NSNotification *)n {
if (indexPlayed < [movieUrls count]) {
moviePlayer.contentURL = [movieUrls objectAtIndex:indexPlayed++];
[moviePlayer play];
}
}