MPMoviePlayerController automatic pause at second X - ios

I have to automatic stop the player at second X and I don't know which kind of notification I have to used.
After, when user taps anywhere on the screen the player continue to run the video.
- (IBAction)playMovie:(id)sender {
NSString *filepath = [[NSBundle mainBundle] pathForResource:#"movie" ofType:#"m4v"];
NSURL *fileURL = [NSURL fileURLWithPath:filepath];
_moviePlayer = [[MPMoviePlayerController alloc] initWithContentURL:fileURL];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:_moviePlayer];
//here I don't know which notification I have to used
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayBackPause:) name:MPMoviePlayerPlaybackStateDidChangeNotification object:_moviePlayer];
_moviePlayer.controlStyle = MPMovieControlStyleDefault;
_moviePlayer.initialPlaybackTime = 2.5;
_moviePlayer.shouldAutoplay = YES;
[self.view addSubview:_moviePlayer.view];
[_moviePlayer setFullscreen:YES animated:NO];
[_moviePlayer play];
}
I tried to catch the movie frame and analyzed it to see if is time to pause the video.
- (void) moviePlayBackPause:(NSNotification*)notification{
// check if it's time to pause the video
if([_moviePlayer currentPlaybackTime] == 6.0){
[_moviePlayer pause];
}
}
Which type of notification I have to use to catch the current time of the video?
Thanks in advance for all your responses!
Kind regards!

You can use a NSTimer to stop your video.
Should exist a better way to do it, but with timer you can do it as well.
[_moviePlayer play];
[NSTimer scheduledTimerWithTimeInterval:6 //Time in seconds
target:self
selector:#selector(moviePlayBackPause) //Method called when the timer is completed.
userInfo:nil
repeats:NO];
}
}
- (void) moviePlayBackPause {
[_moviePlayer pause];
}

Related

AVPlayer does not play video Instantly on iOS 10, while audio playing only

I am creating video with AVAssetExportSession and playing video when it finishes.
But Visual Part not showing instantly but only audio is playing instantly.
Visual part comes after some delay about of 20 - 30 seconds. Here is my code to play video
-(void)playUrl:(NSURL *)vUrl{
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:AVPlayerItemDidPlayToEndTimeNotification object:[_avPlayer currentItem]];
_avAsset=nil;
_avPlayerItem=nil;
_avPlayer =nil;
[_avPlayerLayer removeFromSuperlayer];
_avPlayerLayer=nil;
_avAsset=[AVAsset assetWithURL:vUrl];
_avPlayerItem =[[AVPlayerItem alloc]initWithAsset:_avAsset];
_avPlayer = [[AVPlayer alloc]init]; //WithPlayerItem:_avPlayerItem];
[_avPlayer replaceCurrentItemWithPlayerItem:_avPlayerItem];
_avPlayerLayer =[AVPlayerLayer playerLayerWithPlayer:_avPlayer];
[_avPlayerLayer setFrame:CGRectMake(0, 0, viewAVPlayer.frame.size.width, viewAVPlayer.frame.size.height)];
[viewAVPlayer.layer addSublayer:_avPlayerLayer];
[_avPlayer seekToTime:kCMTimeZero];
[_avPlayer play];
_avPlayer.actionAtItemEnd = AVPlayerActionAtItemEndNone;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(repeatPlayer:) name:AVPlayerItemDidPlayToEndTimeNotification object:[_avPlayer currentItem]];
}
please let me know if anybody know its answer. this code is working perfectly in iOS 9 but not iOS 10. Thanks in advance.
Try to set automaticallyWaitsToMinimizeStalling property of AVPlayer to NO in order to start playback immediately.
_avPlayer = [[AVPlayer alloc]init]; //WithPlayerItem:_avPlayerItem];
_avPlayer.automaticallyWaitsToMinimizeStalling = NO;
But if sufficient content is not available for playing then player might stall.
Apple documentation: https://developer.apple.com/reference/avfoundation/avplayer/1643482-automaticallywaitstominimizestal.
Hope this helps.
I do next:
First
I add watcher
- (void)attachWatcherBlock {
[self removeWatcherBlock];
if (self.videoPlayer) {
__weak typeof(self) wSelf = self;
self.timeObserver = [self.videoPlayer addPeriodicTimeObserverForInterval:CMTimeMake(1, NSEC_PER_SEC) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
if (wSelf.playerBlock && wSelf.videoPlayer) {
CGFloat playTime = CMTimeGetSeconds(wSelf.videoPlayer.currentTime);
CGFloat duration = CMTimeGetSeconds(wSelf.videoPlayer.currentItem.duration);
if (playTime > 0.0f) {
[wSelf replaceCoverToVideo];
}
wSelf.playerBlock(wSelf, playTime, duration);
}
}];
}
[self.videoPlayer play];
}
And then if in block playTime equals duration call replay
- (void)replay {
__weak typeof(self) wSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{
__strong typeof(wSelf) self = wSelf;
if (self.videoPlayer) {
[self.videoPlayer seekToTime:kCMTimeZero];
}
});
}
All this in my UIView subclass called NDVideoPlayerView
Im facing the same problem and my solution is take old code into main thread:
-(void)ExporterManager:(DoCoExporterManager *)manager DidSuccessComplementWithOutputUrl:(NSURL *)outputUrl{
//...
dispatch_async(dispatch_get_main_queue(), ^{
[_playView setContentUrl:outputUrl.path];
});
//...
}
Im using exportAsynchronouslyWithCompletionHandler to process my video.someone thinks that AVVideoCompositionCoreAnimationTool is the cause of the issuehttps://forums.developer.apple.com/thread/62521.
I'm not sure,but i do use it.
Just try it!
Hope this helps!
The AVVideoCompositionCoreAnimationTool when used in AVAssetExportSession interferes with AVPlayer in iOS 10.0 - 10.1.1. iOS 10.2 fixes this bug and your code should work normally.

MPMoviePlayerViewController Dismiss Without playing

The problem video can be seen in :
http://app.bowerchat.com/images/118_1435046739658.mp4
MPMoviePlayerViewController Dismissing immediately without play.
What can be reason?Some videos are loaded nicely and playing.
How can i check the video can be played or not?
I tried
NSLog(#"%lu",(unsigned long)self.mpController.moviePlayer.loadState);
NSLog(#"%d",self.mpController.moviePlayer == nil);
Results always 0 - 0
MY Code to play video
self.mpController = [[MPMoviePlayerViewController alloc] initWithContentURL:moveUrl];
[self.mpController.moviePlayer prepareToPlay];
NSLog(#"%lu",(unsigned long)self.mpController.moviePlayer.loadState);
NSLog(#"%d",self.mpController.moviePlayer == nil);
[parent presentMoviePlayerViewControllerAnimated:self.mpController];
The reason could be that movie that has extention *.mp4 is actually of different type.
Also try to add the following:
self.mpController.moviePlayer.shouldAutoplay = YES;
[self.mpController.moviePlayer play];
Try this snippet :
-(void)setupMovie
{
NSURL *movieURL = [NSURL fileURLWithPath:movieURL];
self.mpController = [[MPMoviePlayerController alloc] initWithContentURL:movieURL];
self. mpController.scalingMode = MPMovieScalingModeAspectFill;
self. mpController.controlStyle = MPMovieControlStyleNone;
self.mpController.view.frame = self.view.frame;
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayBackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayerPlaybackStateDidChange:) name:MPMediaPlaybackIsPreparedToPlayDidChangeNotification object:nil];
[self.view addSubview:self.mpController.view];
[self.mpController prepareToPlay];
}
- (void)moviePlayBackDidFinish:(MPMoviePlayerController *)player
{
[self.mpController.view removeFromSuperview];
}
- (void)moviePlayerPlaybackStateDidChange:(NSNotification*)notification
{
if (self. mpController.isPreparedToPlay) {
[self. mpController play];
}
}
And make sure movieURL is correct and video exist by this provided url

Play video from url in objective c with buffering

Hi everyone I am working on an application in which I have a url of video and I have to play a video from that url. I have done this job from this code
- (IBAction)btnPlayVideo:(id)sender
{
NSString *fileName = #"Server Address/Vdieo.flv";
NSURL *streamURL = [NSURL URLWithString:fileName];
mPlayerVC = [[MPMoviePlayerViewController alloc] initWithContentURL:streamURL];
[self.view addSubview:mPlayerVC.view];
//play movie
MPMoviePlayerController *player = [mPlayerVC moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(willEnterFullscreen:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playbackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
player.view.frame = self.view.frame;
[player setFullscreen:YES animated:YES];
[self.view addSubview:player.view];
[player prepareToPlay];
[player play];
}
//============Other Methods====================
- (void)willEnterFullscreen:(NSNotification*)notification {
NSLog(#"willEnterFullscreen");
}
- (void)enteredFullscreen:(NSNotification*)notification {
NSLog(#"enteredFullscreen");
}
- (void)willExitFullscreen:(NSNotification*)notification {
NSLog(#"willExitFullscreen");
}
- (void)exitedFullscreen:(NSNotification*)notification {
NSLog(#"exitedFullscreen");
[mPlayerVC.view removeFromSuperview];
mPlayerVC = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)playbackFinished:(NSNotification*)notification {
NSNumber* reason = [[notification userInfo] objectForKey:MPMoviePlayerPlaybackDidFinishReasonUserInfoKey];
switch ([reason intValue]) {
case MPMovieFinishReasonPlaybackEnded:
NSLog(#"playbackFinished. Reason: Playback Ended");
break;
case MPMovieFinishReasonPlaybackError:
NSLog(#"playbackFinished. Reason: Playback Error");
break;
case MPMovieFinishReasonUserExited:
NSLog(#"playbackFinished. Reason: User Exited");
NSLog(#"exitedFullscreen");
[[NSNotificationCenter defaultCenter] removeObserver:self];
break;
default:
break;
}
[mPlayerVC.view removeFromSuperview];
mPlayerVC = nil;
}
My problem is that when this code run video player open and start loading and it takes too much time to run a video. Can anybody guide me how to run video in fast way from internet?
There's nothing in the code that suggests that lag is anything other than the time it takes to make the request and sufficiently buffer. The most common technique to improve UE is to start loading as early as possible, even before the user requests playback.
If this is possible, the code should be reorganized as follows:
// hang on to the movie player
#property(nonatomic,retain) MPMoviePlayerController *mp;
// call this as soon as its possible to know the user might want to see the video
- (void)primeVideo {
NSString *fileName = #"Server Address/Vdieo.flv";
NSURL *streamURL = [NSURL URLWithString:fileName];
MPMoviePlayerController *mp = [[MPMoviePlayerViewController alloc] initWithContentURL:streamURL];
// do this also in dealloc
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(willEnterFullscreen:) name:MPMoviePlayerWillEnterFullscreenNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(playbackFinished:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
mp.shouldAutoplay = NO;
[mp prepareToPlay];
self.mp = mp;
}
That does as much prep as possible without changing the UI. The rest of your code from the button action is left, tweaked a little...
- (IBAction)btnPlayVideo:(id)sender {
// if there's any way that the user can request playback before
// you've called primeVideo, check for that here. But hopefully you
// can call primeVideo before user even sees the play button
if (!self.mp) [self primeVideo];
self.mp.view.frame = self.view.frame;
[self.mp setFullscreen:YES animated:YES];
[self.view addSubview:self.mp.view];
MPMovieLoadState state = [self.mp loadState];
if (state & MPMovieLoadStatePlaythroughOK) [self.mp play];
else self.mp.shouldAutoplay = YES;
}

AVQueuePlayer AVPlayerItemDidPlayToEndTimeNotification fails to call

Im using AVQueuePlayer to loop through an array of AVPlayerItems.
The way I'm looping it, I listen to the AVPlayerItemDidPlayToEndTimeNotification and every time its called, I add the current object to the end of the queue.
heres the code:
viewWillAppear
{
...
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[_queuePlayer currentItem]];
[_queuePlayer play];
}
- (void)playerItemDidReachEnd:(NSNotification *)notification {
AVPlayerItem *p = [notification object];
AVPlayerItem *fakeNew = [[AVPlayerItem alloc] initWithAsset:p.asset];
if (_queuePlayer.items.count == 1)
{
[p seekToTime:kCMTimeZero];
[_queuePlayer play];
}
else
{
[_queuePlayer insertItem:fakeNew afterItem:[_queuePlayer.items lastObject]];
}
NSLog(#"array of items to play:%lu", (unsigned long)_queuePlayer.items.count);
}
The problem is, that the method is called only for the first video that plays, after that, the method stops getting called, so if for example i have 2 movies in the array, it would play them both+the first one again, any idea why is this happening?
More Info:
also tried to make a new player every time and set it to layer. failed to send the notification more than once just the same
- (void)playerItemDidReachEnd:(NSNotification *)notification {
AVPlayerItem *p = [notification object];
[self.playList removeObjectAtIndex:0];
[self.playList addObject:p];
AVPlayer *newPlayer = [[AVPlayer alloc] initWithPlayerItem:[self.playList objectAtIndex:0]];
_player = newPlayer;
self.AVPlayerLayerView.layer.player = self.player;
[_player play];
}
After a lot of messing around, apparently for whatever reason, the view unregistered as observer every time, I just removed and added observer after every notification:
- (void)playerItemDidReachEnd:(NSNotification *)notification {
AVPlayerItem *p = [notification object];
AVPlayerItem *fakeNewItem = [[AVPlayerItem alloc] initWithAsset:p.asset];
[self.playList removeObjectAtIndex:0];
[self.playList addObject:fakeNewItem];
AVPlayer *newPlayer = [[AVPlayer alloc] initWithPlayerItem:[self.playList objectAtIndex:0]];
_player = newPlayer;
self.AVPlayerLayerView.layer.player = self.player;
[[NSNotificationCenter defaultCenter] removeObserver:self];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(playerItemDidReachEnd:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:[_player currentItem]];
[_player play];
}
For a clean approach to resolve this issue. I approached with the next piece of code instead
The first is you have to add the code necessary to receive a feedback from the AVPlayer when the reproduction time changes.
- (void)addPeriodicTimeObserverForReproductionChanges {
#weakify(self);
[self.player
addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(kBQDefaultTimeIntervalReproductionChanges, NSEC_PER_SEC)
queue:self.eventsQueue
usingBlock:^(CMTime time) {
#strongify(self);
[self dispatchBlockOnMainQueue:^{
if ([self.delegate respondsToSelector:#selector(playerItemController:didChangeReproductionTime:)])
[self.delegate playerItemController:self
didChangeReproductionTime:time];
[self checkForItemPlayToEnd];
}];
}];
}
- (void)checkForItemPlayToEnd
{
CMTime durationScaled = CMTimeConvertScale(self.duration,self.player.currentTime.timescale, kCMTimeRoundingMethod_Default);
if (CMTIME_COMPARE_INLINE(durationScaled, ==, self.player.currentTime)) {
[self playerDidFinishReproducingItem];
}
}

Can't stop animation occurring in MPMoviePlayerController when done is pressed

I'm trying to prevent the transition animation that occurs when you exit a video in MPMoviePLayerController when the user presses done. I can stop it fine when the movie finishes on its own using the moviePlayBackDidFinish: notification but for some reason when I try it in the exact same way with the exitedFullscreen: notification (which responds to a done press) it doesn't work, as in, the animation occurs.
Here is the complete code, any help would be much appreciated.
-(void) playvideo
{
NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]
pathForResource:#"test" ofType:#"MOV"]];
moviePlayer = [[MPMoviePlayerController alloc]
initWithContentURL:url];
self.navigationController.navigationBar.frame = CGRectMake(0, 0, self.navigationController.navigationBar.frame.size.width, self.navigationController.navigationBar.frame.size.height);
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(moviePlayBackDidFinish:) name:MPMoviePlayerPlaybackDidFinishNotification object:moviePlayer];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(exitedFullscreen:) name:MPMoviePlayerDidExitFullscreenNotification object:moviePlayer];
moviePlayer.controlStyle = MPMovieControlStyleEmbedded;
moviePlayer.shouldAutoplay = YES;
[self.view addSubview:moviePlayer.view];
moviePlayer.fullscreen = YES;
}
-(void)moviePlayBackDidFinish: (NSNotification*)notification
{
moviePlayer.fullscreen = NO;
[moviePlayer.view removeFromSuperview];
}
- (void)exitedFullscreen:(NSNotification*)notification {
moviePlayer.fullscreen = NO;
[moviePlayer.view removeFromSuperview];
}
you can to remove animation using this code .
-(void)moviePlayBackDidFinish: (NSNotification*)notification
{
[moviePlayer stop];
[moviePlayerController.view removeFromSuperview];
moviePlayer = nil;
}
- (void)exitedFullscreen:(NSNotification*)notification {
[moviePlayer stop];
[moviePlayerController.view removeFromSuperview];
moviePlayer = nil;
}

Resources