How can I use MPMoviePlayerController within my application? - iphone

I'm having trouble implementing MPMoviePlayerController. I've downloaded and run the MoviePlayer app, and it works fine, but I'm unable to reproduce this functionality in my own app. I have added the MediaPlayer Framework and imported to my app.
Here are the relevant parts of my code:
UITableViewController class:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
if (indexPath.section==1) {
MyAppDelegate *appDelegate =
(MyAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate initAndPlayMovie:[self localMovieURL]];
}
}
MyAppDelegate:
-(void)initAndPlayMovie:(NSURL *)movieURL
{
// Initialize a movie player object with the specified URL
MPMoviePlayerController *mp = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
if (mp)
{
self.moviePlayer = mp;
[mp release];
[self.moviePlayer play];
}
}
I did some debugging in
- (void) moviePreloadDidFinish:(NSNotification*)notification {
NSLog(#"moviePreloadDidFinish");
}
and in
- (void) moviePlayBackDidFinish:(NSNotification*)notification {
NSLog(#"moviePlayBackDidFinish");
}
I noticed that the movie loads correctly and plays, I guess somewhere in the background, for the appropriate amount of time, but I just can't see the Movie Player. The view never changes from my TableViewController!
Any Ideas? Please help!!!

Related

cant stream from youtube

Im trying to stream a video from youtube when the user select a row in my tableview,
heres the code:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *videoURLString = [self.listaVideos objectAtIndex:[indexPath row]];
NSURL *videoURL = [NSURL URLWithString:videoURLString];
self.theMovie = [[MPMoviePlayerViewController alloc] initWithContentURL:videoURL];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:[self.theMovie moviePlayer]];
[self.view addSubview:self.theMovie.view];
[self.theMovie setWantsFullScreenLayout:NO];
[self presentMoviePlayerViewControllerAnimated:theMovie];
[[self.theMovie moviePlayer] play];
}
-(void)moviePlayBackDidFinish:(NSNotification*)notification
{
NSLog(#"ENded");
}
And the error: Unbalanced calls to begin/end appearance transitions for <MPMoviePlayerViewController: 0x7a256a0>.
Try removing
[self.view addSubview:self.theMovie.view];
You appear to be adding it the view, then presenting it. (If you don't want to present it, remove that line instead)
MPMoviePlayerViewController can't stream YouTube videos.
Oh, also what Amit Shah said as well (removing the addSubview: will take care of the unbalanced calls, but not the inability to play videos).
Below is the code which the video from youtube url.If you are really looking for streaming the Video from Youtube then, rely on below code it's very easy & event you don't have to take much care of Event Handling , buffering etc...
#interface VideoPlayerContrl : UIViewController {
IBOutlet UIWebView *youtubeVideo;
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
NSString *htmlString = #"<html><head>\n"
"<meta name = \"viewport\" content = \"initial-scale = 1.0, user-scalable = no, width = 212\"/></head>\n"
"<body style=\"background:#F00;margin-top:0px;margin-left:0px\">\n"
"<div><object width=\"212\" height=\"172\">\n"
"<param name=\"movie\" value=\"http://www.youtube.com/v/oHg5SJYRHA0&f=gdata_videos&c=ytapi-my-clientID&d=nGF83uyVrg8eD4rfEkk22mDOl3qUImVMV6ramM\"></param>\n"
"<param name=\"wmode\" value=\"transparent\"></param>\n"
"<embed src=\"http://www.youtube.com/v/oHg5SJYRHA0&f=gdata_videos&c=ytapi-my-clientID&d=nGF83uyVrg8eD4rfEkk22mDOl3qUImVMV6ramM\"\n"
"type=\"application/x-shockwave-flash\" wmode=\"transparent\" width=\"247\" height=\"178\"></embed>\n"
"</object></div></body></html>\n";
[youtubeVideo loadHTMLString:htmlString baseURL:[NSURL URLWithString:#"https://s3.amazonaws.com/adplayer/colgate.mp4"]];
}
Hope that would have solved your problem :)

Pause video upon applicationWillResignActive and Play upon applicationDidBecomeActive

Okay, my code plays a movie fullscreen with no controls for the user, (basically a cinematic). After the movie is done my NSNotification fires and loads a view.
However, when the user hits the home button during one of these movies, it pauses, but there is no way to get it to play again, since I took away the controls. I tried putting [playerController play] and [playerController shouldAutoplay] in my AppDelegate.m under applicationDidBecomeActive, but it's not defined there so it doesn't know what playerController is.
Can anyone help me properly pause and play this video if a user gets a text or hits the home button?
-(IBAction)playMovie:(id)sender {
NSString *movieUrl = [[NSBundle mainBundle] pathForResource:#"Initiate" ofType:#"m4v"]; playerController = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:movieUrl]];
[playerController.view setFrame: self.view.bounds];
[self.view addSubview:playerController.view];
playerController.controlStyle = MPMovieControlStyleNone;
[playerController shouldAutoplay];
[playerController play];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playbackFinished:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:playerController];
}
- (void)playbackFinished:(NSNotification*) notification {
playerController = [notification object];
[[NSNotificationCenter defaultCenter]
removeObserver:self
name:MPMoviePlayerPlaybackDidFinishNotification
object:playerController];
ViewController *viewController = [[ViewController alloc] initWithNibName:#"ViewController" bundle:nil];
viewController.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:viewController animated:YES];
EDIT:
Header
//ViewController.h
#interface ViewController : UIViewController {
MPMoviePlayerController *playerController;
}
Implementation
//ViewController.m
playerController = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:movieUrl]];
AppDelegate *sharedAppDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
sharedAppDelegate.pointer = playerController;
when implementing your player, send all necessary pointers to app delegate:
AppDelegate *sharedAppDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
sharedAppDelegate.yourPointer = yourPlayer;
use this methomd from appDelegate.m:
- (void)applicationWillResignActive:(UIApplication *)application
{
/*
Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
*/
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
/*
Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
*/
}

MPMoviePlayerController : orientation problem

finally I have to post my problem here. Yes it could be duplicate question here as I have referred many answers regarding to this question.But I could not find any fix. (Also didn't find any question regarding to tab-bar app specific so...) And I don't want to use MPMoviePlayerViewController
I have tab-bar application. In last tab's VC there is a button. On click event I want to start movie player. For that I am using MPMoviePlayerController. Its all fine when orientation is Portrait . But regarding to changes, now I have to play it in landscape mode only.
here is my code :
-(void)playMovie
{
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
[self.scrollView addSubview:moviePlayer.view];
[moviePlayer play];
[moviePlayer setFullscreen:TRUE];
}
-(void)btnPlayHandler:(id)sender
{
NSLog(#"btnPlayHandler");
NSURL * videoUrl = [NSURL URLWithString:[NSString stringWithFormat:#"%#",[dictResponse valueForKey:#"VideoPath"]]];
moviePlayer = [[MPMoviePlayerController alloc]initWithContentURL:videoUrl];
//[moviePlayer.view setFrame:CGRectMake(20, 40, 280, 222)];
moviePlayer.fullscreen = YES ;
moviePlayer.shouldAutoplay = NO ;
[self performSelector:#selector(playMovie) withObject:nil afterDelay:1];
}
- (void) movieWillExit:(NSNotification *)notification
{
[[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationPortrait];
}
- (void) movieExit:(NSNotification *)notification
{
[moviePlayer stop];
[moviePlayer.view removeFromSuperview];
moviePlayer = nil ;
[btnPlay setHidden:FALSE];
}
- (void)moviePreLoad:(NSNotification *)notification
{
NSLog(#"moviePreLoad");
}
- (void)moviePlaybackComplete:(NSNotification *)notification
{
NSLog(#"moviePlaybackComplete");
[btnPlay setHidden:FALSE];
}
Only device's orientation is changed not player's view ! How to accomplish this ??? Is it because the tab-bar application ?
You are making the window landscape, but as you have set the MPMoviePlayer view in scrollview, it is not rotating. try to rotate the scrollview according to your orientation.
See this link http://blog.sallarp.com/shouldautorotatetointerfaceorientation/. Hopefully it will solve your problem.

MPMoviePlayerViewController running in background and using Remote Controls

I'm currently running on iOS 4.3.5 and trying to get my MPMoviePlayerViewController to continue playing after entering background.
I implemented everything as it is described on
http://developer.apple.com/library/ios/#documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html
and
http://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/RemoteControl/RemoteControl.html
I have also set the UIBackgroundMode to audio.
My custom MPMoviePlayerViewController class is called like this from a TabBarApplication:
NSURL *streamUrl = [NSURL URLWithString:STREAM_URL];
self.playerViewController = [[CustomMoviePlayerViewController alloc] initWithContentURL:streamUrl];
// Register for the playback finished notification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMovieFinishedCallback:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:self.playerViewController.moviePlayer];
// Present
[self presentMoviePlayerViewControllerAnimated:self.playerViewController];
// Play the movie!
self.playerViewController.moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;
[self.playerViewController.moviePlayer prepareToPlay];
[self.playerViewController.moviePlayer play];
Inside my CustomMovePlayerController looks like the following:
-(void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
}
-(void)viewWillAppear:(BOOL)animated {
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
-(void)viewWillDisappear:(BOOL)animated {
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
[super viewWillDisappear:animated];
}
-(BOOL)canBecomeFirstResponder {
return YES;
}
-(void)remoteControlReceivedWithEvent:(UIEvent *)event {
[super remoteControlReceivedWithEvent:event];
NSLog(#"remoteControlReceived");
NSLog(#"%d", [[AVAudioSession sharedInstance] isActive]);
if (event.type == UIEventTypeRemoteControl) {
switch (event.subtype) {
case UIEventSubtypeRemoteControlPlay:
[self.moviePlayer play];
break;
case UIEventSubtypeRemoteControlPause:
[self.moviePlayer pause];
break;
default:
break;
}
}
}
The main problem with my MPMoviePlayerViewController is, that it doesn't respond to the remoteControlReceivedWithEvent message, why is that? Am I subclassing the wrong thing? Does my Tabbar based app prevent me from doing that?
Last but not Least - applicationDidFinishLaunchingWithOptions contains following:
AVAudioSession *audioSession = [AVAudioSession sharedInstance];
[audioSession setCategory:AVAudioSessionCategoryPlayback error:nil];
[audioSession setActive:YES error:nil];
I just can't figure out what's missing... all help is greatly appreciated!
I think I can answer both questions :)
The background issue:
What file format are you trying to play? My app has been using a MPMoviePlayerViewController for background audio for a while, but recently had reports that it wasn't playing in the background anymore.
Turns out it was AAC files; they're podcasts with chapters and cover art per chapter... iOS 5 added improved support for them, but it must make the MPMoviePlayerViewController think it's playing video. Background video was turned off around iOS 4.3, from what I can find.
Try it with a plain MP3 file, that still works for me. I'm about to log the AAC problem as a bug with Apple.
The remote control issue:
Both the lock screen and notification bar remote control buttons send the UIEventSubtypeRemoteControlTogglePlayPause event, not play and pause separately. So I handle events like this:
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
switch (event.subtype) {
case UIEventSubtypeRemoteControlTogglePlayPause:
if (controller.playbackState == MPMusicPlaybackStatePlaying) {
[controller pause];
} else {
[controller play];
}
break;
//etc
}

Playing video in custom size screen - view in iPhone

Suppose user taps on a button and video begins to play. Now when video plays, it always in full screen mode.
Video should be played in a portrait mode (but normally video is played in landscape mode). How can I do this?
Just an update, the latest iPhone SDK 3.2+ will now allow the programmers to show the video in any desired size and Orientation, New MPMoviePlayerView is provided, which is a property of MPMoviePlayerController, this view will have the video, which you can add as a subview to your view.
#interface MPMoviePlayerController (extend)
-(void)setOrientation:(int)orientation animated:(BOOL)value;
#end
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieUR];
[moviePlayer setOrientation:UIDeviceOrientationPortrait animated:NO];
if (moviePlayer)
{
[self.moviePlayer play];
}
This Solution will be rejected by Apple, as setOrientation for movie player is the Private API. You need to be careful, but it may work on Jailbroke iPhones.
From the documented docs i do not think this is possible using the built in media player
Try this out.
I found something new.
#interface MPMoviePlayerController (extend)
-(void)setOrientation:(int)orientation animated:(BOOL)value;
#end
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:movieUR];
[moviePlayer setOrientation:UIDeviceOrientationPortrait animated:NO];
if (moviePlayer)
{
[self.moviePlayer play];
}
Here's what I did. Add NSNotification to notify you when preloading of the video finishes.
- (void)playVideoUrl:(NSString *)videoUrl {
NSURL *url = [NSURL URLWithString:videoUrl];
MPMoviePlayerController* theMovie=[[MPMoviePlayerController alloc]
initWithContentURL:url];
[[NSNotificationCenter defaultCenter] addObserver:self
//MPMoviePlayerContentPreloadDidFinishNotification
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(myMovieFinishedPreloading:)
name:MPMoviePlayerContentPreloadDidFinishNotification
object:theMovie];
// Movie playback is asynchronous, so this method returns immediately.
[theMovie play];
}
Callback selector:
-(void)myMovieFinishedPreloading:(NSNotification*)aNotification {
NSArray *windows = [[UIApplication sharedApplication] windows];
UIWindow *moviePlayerWindow = nil;
if ([windows count] > 1)
{
moviePlayerWindow = [[UIApplication sharedApplication] keyWindow];
}
CGAffineTransform transform = CGAffineTransformMakeScale(0.5, 0.5);
transform = CGAffineTransformRotate(transform, -90.0f*M_PI/180.0f);
[moviePlayerWindow setTransform:transform];
}