ios6 moviePlayer first frame not appearing upon creation - ios

I have methods inside my open class controller that instantiates a moviePlayer, which is set to 'autoPlay = NO';
I have added the movieplayer.view as a subview of the controllers view, configured it and created a full screen button on top for starting the video. Since iOS4.3, this has been working fine. The button is transparent and the first frame of the video showed through ( which was a picture of a custom Automoble Auto-Start button).
Since iOS6, I only get a black screen.
Clicking the image-button does start the video as it should; calls [moviePlayer play]
Has something changed that I have not taken into consideration?
I have provided the two sections of code I think are necessary.
#define INTRO_MOVIE #"Intro.mov"
-(void)viewDidLoad
{
if(SHOULD_PLAY_INTRO_VIDEO)//Debug switch to ignore the intro video
{
// Prepare the movie and player
[self configureIntroMoviePlayer];
[self.view addSubview:moviePlayer.view];
[self.view bringSubviewToFront:moviePlayer.view];
// Add and Show the Start Button to start the App
[self configureStartButton];
[self.view addSubview:startButton];
}
}
-(void)configureIntroMoviePlayer
{
LOGINFO
// Prepare the Intro Video
NSString *pathToIntroVideo = [ mainFilePath_ stringByAppendingPathComponent: INTRO_MOVIE];
NSURL *URLToIntroVideo = [NSURL fileURLWithPath:pathToIntroVideo];
moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:URLToIntroVideo];
[moviePlayer setShouldAutoplay:NO];
moviePlayer.view.frame = CGRectMake(0, -20, 1024, 768);
[moviePlayer setControlStyle:MPMovieControlStyleNone];
//fixing video brightness Difference with iPad2
if(isIpad2)
{
moviePlayer.backgroundView.backgroundColor = [UIColor blackColor];
moviePlayer.view.alpha = .99;
}
// Create the sKip button for cancelling the Intro Video
skipIntro = [UIButton buttonWithType:UIButtonTypeCustom];
[skipIntro showsTouchWhenHighlighted];
skipIntro.frame = CGRectMake(900, 20, 111, 57);
[skipIntro addTarget:self action:#selector(skipIntroWasPressed) forControlEvents:UIControlEventTouchUpInside];
}

I am not sure why I got a -1 rating for this question for lack of research or clarity?
Maybe I do not know the proper usage of this forum.
I apologize.
I did find that adding [moviePlayer prepareToPlay] solved the problem. Like I said, it was odd that the first frame always showed up prior to iOS 6.

Have you tried:
[moviePlayer.view addSubView:startButton];

Related

MPMoviePlayerController setFullScreen animated bug on iOS 8.0 but not on iOS 8.1

I have and MPMoviePlayerController in my project. I tried to run it on iOS 8.0. When I play the video for the first time, It works fine and I have the progress bar of the video. Then I quit and try to play the video for the second time. It still works except than I don't have the progress bar of the video. I said in the title "setFullScreen:animated" because I also had the error "CGImageCreate : invalid image size 0x0" so I guess It can come frome here.
Also, it appears to work without any problem on iOS 8.1, so I think it's bug corrected by Apple. Maybe someone have heard something about it.
Here is some code when the Controller is created and setted :
_moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:
[NSURL fileURLWithPath:self.model.filePath]];
_moviePlayer.controlStyle = MPMovieControlStyleFullscreen;
_moviePlayer.view.backgroundColor = [UIColor blackColor];
_moviePlayer.view.frame = self.imageButton.frame;
[self.view addSubview:_moviePlayer.view];
[_moviePlayer setFullscreen:YES animated:YES];
[_moviePlayer prepareToPlay];
Any guess ?

Why isn't the scalingMode of my MPMoviePlayerController being respected when coming back from Full Screen?

I have an instance of MPMoviePlayerController that is correctly displaying a HLS video stream on Portrait mode and also on Full Screen when I rotate my iPhone to the Landscape mode for the first time. The issue happens when I come back from Full Screen: the scalingMode property of my MPMoviePlayerController is still set to MPMovieScalingModeAspectFill but the video is displayed as it is set to MPMovieScalingModeAspectFit.
Before adding its view as a Subview (self.moviePlayer.view) of my View (self.movieView) I set its scalingMode to MPMovieScalingModeAspectFill and everything works fine untill I exit Full Screen.
- (void) play
{
self.moviePlayer = [[MPMoviePlayerController alloc] init];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayBackDidStart:) name:MPMoviePlayerLoadStateDidChangeNotification object:self.moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:self.moviePlayer];
self.moviePlayer.movieSourceType = MPMovieSourceTypeStreaming;
self.moviePlayer.contentURL = videoURL;
self.moviePlayer.controlStyle = MPMovieControlStyleNone;
self.moviePlayer.shouldAutoplay = YES;
self.moviePlayer.scalingMode = MPMovieScalingModeAspectFill;
NSLog(#"%ld", (long) self.moviePlayer.scalingMode);
self.moviePlayer.view.frame = CGRectMake(0, 0, 320, 180);
[self.movieView addSubview:self.moviePlayer.view];
[self.moviePlayer setFullscreen:NO animated:NO];
}
When I return from Full Screen it is set to the default value (MPMovieScalingModeAspectFit) and I can't change it back to MPMovieScalingModeAspectFill even if I explicity try to when I receive the MPMoviePlayerScalingModeDidChangeNotification.
- (void)movieScalingModeDidChange:(NSNotification *)notification
{
self.moviePlayer.scalingMode = MPMovieScalingModeAspectFill;
NSLog(#"%ld", (long) self.moviePlayer.scalingMode);
}
The weird thing is that that this NSLog gives me:
-[CameraViewController play]:2
Which according to the Documentation is the enum for MPMovieScalinModeAspectFill, but the video is not it this aspect mode.
typedef enum {
MPMovieScalingModeNone,
MPMovieScalingModeAspectFit,
MPMovieScalingModeAspectFill,
MPMovieScalingModeFill
} MPMovieScalingMode;
Has anyone experienced this same issue? Thanks in advance!
You need change scalingMode to any value other than MPMovieScalingModeAspectFill and set aspect fit again on receiving MPMoviePlayerScalingModeDidChangeNotification
- (void)playerDidExitFullscreen:(NSNotification *)notification
{
self.moviePlayer.scalingMode = MPMovieScalingModeNone;
self.moviePlayer.scalingMode = MPMovieScalingModeAspectFill;
}
It works with tiny animation issue.
From what I have seen in a couple of other questions here and here it really seems that MPMoviePlayerController gets screwed when it comes back from full screen and the workaround is to remove its element from the view and add it back again using the desired scalingMode. Well, I don't want my stream to be reloaded since buffering might take too long sometimes and this really kills the user experience.
So here is what I did. I set the scalingMode to its default value when the view is loaded and added a "resize" button that changes this property when the user clicks it (I remembered some users saying that we were "leaving out" important parts of the image on the mobile). Now when the user rotates its iPhone it will remaing with the desired scalingMode and when it returns to the Portrait mode, it will be set as the default.
I hope this may be of help to anyone facing the same issue.

"Done" button in MPMoviePlayerController doesn't work when full screen mode

Well, I could find many questions about the same or similar questions and answers... However, nothing could help me. Only when I don't use the property "controlStyle" as "MPMovieControlStyleFullscreen", "done" button works. I tried this way..
MPMoviePlayerController *mpMoviePlayerController = [[MPMoviePlayerController alloc] initWithContentURL:[NSURL URLWithString:#"https://dl.dropbox.com/u/14218997/thxq.mp4"]];
mpMoviePlayerController.controlStyle = MPMovieControlStyleNone;
[mpMoviePlayerController setUseApplicationAudioSession:NO];
[mpMoviePlayerController setScalingMode:MPMovieScalingModeAspectFit];
[mpMoviePlayerController setFullscreen:YES animated:YES];
[mpMoviePlayerController.view setFrame:CGRectMake(0, 0, 1024, 768)];
[[globalSingleton paintingView] addSubview:mpMoviePlayerController.view];
[mpMoviePlayerController prepareToPlay];
[mpMoviePlayerController play];
mpMoviePlayerController.controlStyle = MPMovieControlStyleFullscreen;
or this way..
MPMoviePlayerController *mp;
MPMoviePlayerViewController *mpVC = [[MPMoviePlayerViewController alloc] initWithContentURL:[NSURL URLWithString:#"https://dl.dropbox.com/u/14218997/thxq.mp4"]];
mp = [mpVC moviePlayer];
mp.controlStyle = MPMovieControlStyleFullscreen;
mp.fullscreen = NO;
mp.useApplicationAudioSession = NO;
mp.view.frame = CGRectMake(0, 0, 1024, 768);
[[globalSingleton paintingView] addSubview:mp.view];
([globalSingleton paintingView] is just for representing main view. I already checked there's no problem on it.)
Please share what u know about this problem. Thx in advance!
Based on your code, It looks to me that your intention is to just have a fullscreen movie player take over the screen. In that case, you're probably better off using the MPMoviePlayerViewController, but you need to present it as a modal view controller using your current view controller like this:
MPMoviePlayerViewController *movieViewController = [[MPMoviePlayerViewController alloc] initWithContentURL:someVideoURL];
movieViewController.moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
// Self is the UIViewController you are presenting the movie player from.
[self presentMoviePlayerViewControllerAnimated:movieViewController];
The "Done" button should work properly in this case, and dismiss the modal MPMoviePlayerViewController
On the other hand, If you're more interested in animating the movie from where you've added it in the current view hierarchy, here is an example of what I have done to achieve this:
I also found that setting the MPMoviePlayerController's controlStyle property to MPMovieControlStyleFullscreen had the same result–the "Done" button did not close the MPMoviePlayerController. When I changed it to MPMovieControlStyleDefault, it worked as expected. However, in my case, I'm adding the MPMoviePlayerController's view as a thumbnail-sized subview to the currently displayed UIViewController's view. I initially have the MPMoviePlayerController's controlStyle set to MPMovieControlStyleNone. I have a custom UIButton on top of the thumbnail-sized movie player view, and in the button's action method, I'm changing the controlStyle of the MPMoviePlayerController to MPMovieControlStyleDefault, then calling setFullscreen:animated: which animates the movie player view into fullscreen mode. Then, tapping the "done" button properly animates the player back into place in the thumbnail-sized subview of my UIViewController's view. Here is an example:
Initial instantiation of my MPMoviePlayerController:
// My moviePlayerController is a property
self.moviePlayer = [[MPMoviePlayerController alloc] initWithURL:videoURL];
moviePlayer.controlStyle = MPMovieControlStyleNone;
moviePlayer.scalingMode = MPMovieScalingModeAspectFit;
moviePlayer.shouldAutoplay = NO;
// Add the moviePlayer's view as a subview of a my UIViewController's view.
moviePlayer.view.frame = CGRectMake(20, 20, 160, 90);
[self.view addSubview:moviePlayer.view];
Note: I also added a custom UIButton (to invoke fullscreen playback) on top of my moviePlayer's view and set it's action to call the following method:
- (void)buttonAction:(UIButton *)sender
{
self.moviePlayer.controlStyle = MPMovieControlStyleDefault;
[self.moviePlayer setFullscreen:YES animated:YES];
[self.moviePlayer play];
}
Note: I also observe and handle the MPMoviePlayerWillExitFullscreenNotification where I set the controlStyle back to MPMovieControlStyleNone.

MPMoviePlayerController stops and resets the movie when user tries to play fullscreen [iOS]

I embedded a MPMoviePlayerController on my mail view. I can play/pause the movie and seek forward/backward. But when I touch the "fullscreen button" the movie stops and the playback state is set to MPMoviePlaybackStateStopped... Should the movie be played in full screen?
Here is my code:
MPMoviePlayerController *player = [[MPMoviePlayerController alloc] initWithContentURL:videoUrl];
player.shouldAutoplay = NO;
player.movieSourceType = MPMovieSourceTypeFile;
player.controlStyle = MPMovieControlStyleEmbedded;
player.allowsAirPlay = YES;
player.view.frame = CGRectMake(xPos, yPos, width, height);
[self.view addSubview:player.view];
I found my bug: when pressing the full screen toggle button in MPMoviePlayerController's view, the method "viewWillLayoutSubviews" is invoked. I could never imagine this behavior...
I hope my experience can be useful to other developers.
Remember that any containing ViewController will have its viewWillDisappear, viewDidDisappear methods invoked when the MPMoviePlayerController goes full screen. Also, viewWillAppear and viewWillDisappear get called when it comes back from full screen.
If you have any logic in there that affects video playback behavior, it'll get called unless you use some conditional logic to see if the video is still playing.

Fast switching between videos using AVFoundation

I'm writing an application where the user can record up to 6 video clips each with a duration of 2 seconds. When the video clips are recorded the user can play with them using 6 buttons - one for each clip. The user can then record a movie by switching between the 6 clips. The problem is that I need near instantaneous switching between the 6 clips when the user presses a button - otherwise the illusion of playing with the clips is lost - the functionality is somewhat similar to the app called CamBox in the App Store.
I first tried initializing every clip with and AVAsset in an AvPlayerItem in an AVPlayer every time the user pressed a button. The output of the player was directed at a an AVPlayerLayer in my main view. The problem is that the time it takes to load and start playing is quite long, meaning the the video lags when the user presses the buttons in rapid succession.
I the decided to try to preload all the clips using 5 AVPlayers and 5 AVPlayerLayers. The 5 PlayerLayers are inserted into my main view and when the user presses a button the currently playing AVPlayer is paused and rewound and the the currently visible AVPlayerLayer is hidden. The new AVPlayer is started and the corresponding AVPlayerLayer is shown. It works pretty ok being much faster than my first solution although not instantaneous but the problem is that I can only preload 4 clips meaning than when the user presses the button that play the last two the it lags big time. Below is my code to preload the clips
-(void)loadVideos
{
layers = [[NSMutableArray alloc] initWithCapacity:6];
players = [[NSMutableArray alloc] initWithCapacity:6];
for(int i = 1; i < 7; i++)
{
NSURL* fileURL = [NSURL fileURLWithPath:[self getFileName:i]];
AVPlayerItem* avPlayerItem = [[[AVPlayerItem alloc] initWithURL:fileURL] autorelease];
[avPlayerItem addObserver:self forKeyPath:#"status" options:0 context:nil];
AVPlayer *avPlayer = [[[AVPlayer alloc] initWithPlayerItem:avPlayerItem] autorelease];
[avPlayer addObserver:self forKeyPath:#"status" options:0 context:nil];
[avPlayer addObserver:self forKeyPath:#"currentItem" options:0 context:nil];
AVPlayerLayer* layer = [AVPlayerLayer playerLayerWithPlayer:avPlayer];
layer.frame = self.playerView.bounds;
[playerView.layer addSublayer:layer];
[layers addObject:layer];
[players addObject:avPlayer];
layer.hidden = YES;
}
}
The event handler for the 6 buttons looks like this:
- (IBAction)takeBtnClicked:(id)sender {
int tag = ((UIButton*)sender).tag;
AVPlayer* player;
AVPlayerLayer* layer;
if (layerIndex > -1) {
player = [players objectAtIndex:layerIndex];
layer = [layers objectAtIndex:layerIndex];
[player pause];
layer.hidden = YES;
[player seekToTime:kCMTimeZero];
}
layerIndex = tag-1;
player = [players objectAtIndex:layerIndex];
layer = [layers objectAtIndex:layerIndex];
[player play];
layer.hidden = NO;
}
I'm prette sure that the limitation of 4 preloaded video clips is a hardware limitation, but what is the alternative. Does anybody have any ideas?
Thanks in advance.
See my answer for iphone-smooth-transition-from-one-video-to-another, it shows a library you can use to implement this logic and an example app with 3 buttons that kick off animated clips. Each clip also has an associated sound effect.

Resources