I added a MPMoviePlayerController's view to my view of a viewcontroller, that i present on an iPad with UIModalPresentationFormSheet. This works fine so far, but when i tap the fullscreen button, the movie view changes to fullscreen but after the animation the modal viewcontroller appears above the view.
The only code I use is the following:
- (void)viewDidLoad
{
[super viewDidLoad];
self.player = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL fileURLWithPath:url]];
[self.player prepareToPlay];
self.player.controlStyle = MPMovieControlStyleEmbedded;
self.player.view.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:self.player.view];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(willEnterFullScreen) name:MPMoviePlayerWillEnterFullscreenNotification object:self.player];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(didEnterFullScreen) name:MPMoviePlayerDidEnterFullscreenNotification object:self.player];
}
- (void) updateViewConstraints
{
[super updateViewConstraints];
if (!self.addedContraints) {
[self.player.view autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero];
self.addedContraints = YES;
}
}
This happens when I try to hide the viewcontrollers view.
Related
I have a split view controller set up as a video player. The master view is a list of available videos and the detail view should play the selected video from the list.
I'm able to send the required properties to the detail view from the master (url, start time, end time...) but I'm only getting audio.
When a selection is made from the master view a delegate -(void)didselectVid: method gets fired in the detail view.
- (void)viewDidLoad
{
[super viewDidLoad];
if (selectedBool) {
timer = [NSTimer
scheduledTimerWithTimeInterval:1.0
target:self
selector:#selector(timedJob)
userInfo:nil
repeats:YES];
[timer fire];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerPlaybackStateDidChange:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:nil];
NSString * videoStr = [NSString stringWithFormat:#"%#/%#", gameVideoURL , videoUrlStr];
NSString * urlStrEscaped = [videoStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL * dataURL = [NSURL URLWithString:urlStrEscaped];
moviePlayerCrl.movieSourceType = MPMovieSourceTypeStreaming;
moviePlayerCrl = [[MPMoviePlayerController alloc] initWithContentURL:dataURL];
[self registerForMovieNotifications];
}
}
- (void)registerForMovieNotifications
{
//movie is ready to play notifications
if ([self.moviePlayerCrl respondsToSelector:#selector(loadState)])
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerLoadStateChanged:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
[self.moviePlayerCrl prepareToPlay];
}
//movie has finished notification
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
}
- (void)moviePlayerLoadStateChanged:(NSNotification*)notification
{
NSLog(#"load state changed");
//unless state is unknown, start playback
if ([self.moviePlayerCrl loadState] != MPMovieLoadStateUnknown)
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
[self.moviePlayerCrl.view setFrame: CGRectMake(0,
[UIApplication sharedApplication].statusBarFrame.size.height
+ self.navigationController.navigationBar.frame.size.height
+ self.navigationController.toolbar.frame.size.height,
self.view.bounds.size.width,
self.view.bounds.size.height
- [UIApplication sharedApplication].statusBarFrame.size.height
- self.navigationController.navigationBar.frame.size.height
- self.navigationController.toolbar.frame.size.height
- self.tabBarController.tabBar.frame.size.height
)]; // x, y, width, height
[self.view addSubview:self.moviePlayerCrl.view];
[self.view bringSubviewToFront:self.moviePlayerCrl.view];
[self.moviePlayerCrl setFullscreen:NO animated:YES];
[self.moviePlayerCrl play];
[moviePlayerCrl setCurrentPlaybackTime:startPlaybackTime];
}
}
-(void)didselectVid:(VideoClipData *)vid
{
videoUrlStr = vid.evtUrlStr;
startTime = vid.evtStartStr;
endTime = vid.evtEndTimeStr;
gameNamesStr = vid.evtNameStr;
double startTimeInterval = [startTime doubleValue];
double endTimeInterval = [endTime doubleValue];
startPlaybackTime = startTimeInterval;
endPlaybackTime = endTimeInterval;
selectedBool = YES;
[self viewDidLoad];
}
The parent view frame and the MoviePlayerController view's frame have to be same before making MoviePlayerController.view a subview.
i.e Have one more view inside your master view say playerContainerView. Before adding the moviePlayerCrl.view as the subview of playerContainerView, set the playerContainerView and moviePlayerCrl.view to the same frame.
This should work.
I was able to fix this by calling didselectVid differently. With what I assume is proper split view delegation:
in master view .h :
#import "VideoClipData.h"
#protocol DetailDelegate <NSObject>
-(void)didselectEvtVid:(VideoClipData *) vid;
#end
#import <UIKit/UIKit.h>
#class DetailView;
#interface MasterView : UIViewController
#property (strong, nonatomic) DetailView *detailViewController;
#property (nonatomic, unsafe_unretained) id<DetailDelegate> delegate;
master view .m:
- (void)viewDidLoad {
[super viewDidLoad];
self.detailViewController = (DetailView *)[[self.splitViewController.viewControllers lastObject] topViewController];
}
-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[self.detailViewController didselectEvtVid:gameVideos];
}
And instead of calling viewDidLoad again I called [self configureView]; as given in apple's split view example.
I create a MPMoviePlayerController in detailView(UIVIew), now i want to force MPMoviePlayerController to landscape view when user click on FullScreen button. Can i do that? Please give me any suggestion. Thanks in advance.And this is my code to create :
NSURL *movieURL = [NSURL URLWithString:previewString];
movieController = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
[movieController.view setFrame:CGRectMake(10,130, 275 , 150)];
movieController.view.backgroundColor = [UIColor grayColor];
[detailview addSubview:movieController.view];
[movieController prepareToPlay];
movieController.shouldAutoplay = NO;
and willEnterFullscreen () function:
- (void)willEnterFullscreen:(NSNotification*)notification {
NSLog(#"willEnterFullscreen");
donepress = YES;
// nothing
}
I tried search but still do not have any good answer. Please help me. thanks so much
YES, you can do that with two notification observer to change the full orientation.
First, Add two notification observer to your AppDelegate didFinishLaunchingWithOptions method:
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerWillEnterFullscreenNotification:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerWillExitFullscreenNotification:) name:MPMoviePlayerWillExitFullscreenNotification object:nil];
Second, Add the method and property
- (void) moviePlayerWillEnterFullscreenNotification:(NSNotification*)notification {
self.allowRotation = YES;
}
- (void) moviePlayerWillExitFullscreenNotification:(NSNotification*)notification {
self.allowRotation = NO;
}
Third, override the supportedInterfaceOrientationsForWindow method, you can return whatever orientation you want
-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
if (self.allowRotation) {
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft | UIInterfaceOrientationMaskLandscapeRight;
}
return UIInterfaceOrientationMaskPortrait;
}
I have two view controllers.One view has button, when user click on the button he will redirect to another view where MPMoviePlayer Controller is present.I want to show MPMoviePlayer controller view to LandsapeRight mode by Default.
I write the below code in buttonAction
-(void)buttonAction
{
tLive = [[toneTvlive alloc]init];
[self.navigationController pushViewController:tLive animated:YES];
}
and in the 2nd view i write the below code
- (void)viewDidLoad
{
[super viewDidLoad];
printf("\n hii");
self.navigationController.navigationBar.hidden = YES;
[[UIApplication sharedApplication]setStatusBarHidden:NO];
NSURL *mediaURL = [NSURL URLWithString:#""];
mp = [[MPMoviePlayerController alloc] initWithContentURL:mediaURL];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
//[mp setControlStyle:MPMovieControlStyleFullscreen];
[mp setMovieSourceType:MPMovieSourceTypeStreaming];
[mp setFullscreen:YES animated:YES];
[mp.view setFrame: CGRectMake(0,0, 480,320)];
[self.view addSubview:mp.view];
[mp prepareToPlay];
[mp play];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations.
return (interfaceOrientation == UIInterfaceOrientationLandscapeRight);
}
while run the program first it shows the view in portrait mode only.It doesn't prompt the view to rotate in landscape,but after when i rotate the device once it works fine.Can anyone please help me to solve this.
If you're using iOS 6+ you can autorotate the view controller to landscape:
- (NSUInteger)supportedInterfaceOrientations {
return UIInterfaceOrientationMaskLandscape;
}
- (BOOL)shouldAutorotate {
return YES;
}
If you're targeting earlier iOS versions, here's a good SO answer about the same thing.
In MPMoviePlayerController, when ever the controls disappear, even the status bar is disappearing with it. Since i want the status bar to appear even when the control disappears, i placed the below code
[[UIApplication sharedApplication] setStatusBarHidden:NO];
But the above code is not making any difference, teh status bar is getting disappeared along with the player controls. How to solve this problem.
Please find the code below, and let me know how to rectify it.
- (void) readyPlayer {
mp = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
if ([mp respondsToSelector:#selector(loadState)])
{
// Set movie player layout
[mp setControlStyle:MPMovieControlStyleFullscreen];
[mp setFullscreen:YES];
// May help to reduce latency
[mp prepareToPlay];
// Register that the load state changed (movie is ready)
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerLoadStateChanged:) name:MPMoviePlayerLoadStateDidChangeNotification object:nil];
} else {
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePreloadDidFinish:) name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification
object:nil];
}
// Register to receive a notification when the movie has finished playing.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
}
- (void) moviePlayerLoadStateChanged:(NSNotification*)notification {
NSLog(#"moviePlayerLoadStateChanged");
// Unless state is unknown, start playback
if ([mp loadState] != MPMovieLoadStateUnknown)
{
// Remove observer
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerLoadStateDidChangeNotification
object:nil];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
// Rotate the view for landscape playback
[[self view] setBounds:CGRectMake(0, 0, 768, 1000)];
// Set frame of movieplayer
[[mp view] setFrame:CGRectMake(0, 0, 768, 1000)];
// Add movie player as subview
[[self view] addSubview:[mp view]];
// Play the movie
[mp play];
}
}
- (void) moviePreloadDidFinish:(NSNotification*)notification {
// Remove observer
NSLog(#"moviePreloadDidFinish");
[[NSNotificationCenter defaultCenter] removeObserver:nil
name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification
object:nil];
[[UIApplication sharedApplication] setStatusBarHidden:NO];
// Play the movie
[mp play];
}
- (void) moviePlayBackDidFinish:(NSNotification*)notification {
NSLog(#"moviePlayBackDidFinish");
[[UIApplication sharedApplication] setStatusBarHidden:NO];
// Remove observer
[[NSNotificationCenter defaultCenter] removeObserver:self name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
[self dismissModalViewControllerAnimated:YES];
}
This is a well-known issue of MPMovieControlStyleFullscreen. Simply use the MPMovieControlStyleEmbedded controlStyle and you are good to go.
And, by the way, that is the more adequate controlStyle for embedded usage anyways.
I am writing a simple method to start a streaming video full-screen and letting the user quit pressing the "Done" button. Problem is, I can't remove the MPMediaPlayerController view, or perhaps I am doing it the wrong way.
- (IBAction)playVideoButtonPressed:(id)sender {
NSURL *url = [NSURL URLWithString:#"http://mysite.com/video.mov"];
mp = [[MPMoviePlayerController alloc] initWithContentURL: url];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerPlaybackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];
if ([mp respondsToSelector:#selector(setFullscreen:animated:)]) {
mp.controlStyle = MPMovieControlStyleFullscreen;
mp.shouldAutoplay = YES;
[self.view addSubview:mp.view];
[mp.view setTag:3];
[mp setFullscreen:YES animated:YES];
}
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:mp];
[mp play];
}
- (void)moviePlayBackDidFinish:(id)sender {
NSLog(#"Quitting MoviePlayer");
[mp.view removeFromSuperview];
}
The idea is that the MPMediaPlayerController view is called clicking on a button in the app, and it is dismissed by clicking the "Done" video or when the video ends.
I should have used MPMoviePlayerViewController.