I have a weird issue with the MPMoviePlayerController in iOS.
I have a MPMoviePlayerController with control style none.
Added my own UISlider to seek forward/backward in the movie.
Set up notifications to see a change in the playback state.
After setting player.currentPlaybackTime to a new value the playbackstate goes to MPMoviePlaybackStateSeekingForward or MPMoviePlaybackStateSeekingBackward and stays in that state.
I would expect that when the seeking stops (new position found), and the player continues to play normally the playbackstate would go back to MPMoviePlaybachStatePlaying but it doesn't.
Is this normal behaviour or am I missing something?
The problem is with UISlider's property continuous. Set it to no and you will be notified when the state will change from Forward/Backward to Playing.
self.playerControlsView.slider.continuous = NO;
The issue i guess is that when the continuous property is set to YES. The slider will continue the action of sliding the user is providing it and not trigger the state change. And hence the state remains forward/backward. I am not very sure about this but the answer is somewhere on these lines.
Hope this helps someone :)
Related
here is my problem:
I've got an app playing audio files, updating the lockscreen info via MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo, and this part is working fine.
But in an other view, i'm playing a video with AVPlayerViewController and AVPlayer, and when the video starts playing, it's updating the lock screen automatically, with nothing except the video duration.
I didn't find anything about this behaviour in Apple's documentation, I can't find a way to disable it.
So far, I've tried calling UIApplication.sharedApplication().endReceivingRemoteControlEvents() before the video starts playing, and beginReceivingRemoteControlEvents() after. It doesn't work.
Does anyone know a way to prevent this?
Starting with iOS 10 there is a BOOL property in AVPlayerViewController called updatesNowPlayingInfoCenter, that has the default value: YES. Just change it to NO:
//playerController is an instance of AVPlayerViewController
if ([self.playerController respondsToSelector:#selector(setUpdatesNowPlayingInfoCenter:)])
{
self.playerController.updatesNowPlayingInfoCenter = NO;
}
it is since a lot of time that I´m experiencing a weird seek slider behavior when seeking forward or backwards on streamed movies using MPMoviePlayerController.
The symptoms are:
. You begin the seek gesture on slider and the slider button follows the finger.
. When slider is released, it jumps back to the gesture starting point and slingers to the point where the gesture was finished.
. Then playback continues from the selected movie time.
This is of course visually annoying, although the functionality is OK.
This is even worst on iOS 7.
Thanks for the welcome help.
Perhaps a bit late to answer this, but since I stumbled upon this on a Google search, maybe this will be of help to someone else.
I ran into this behavior with AVPlayer and found the reason to be because of a time observer that kept running during scrubbing. The time observer was in charge of updating the scrubber position based on what the current playback time was. So, once the gesture finished moving the slider, the time observer would move the slider knob back to where it thought playback was before the scrubbing action updated the play clock.
My solution was to temporarily remove this time observer right when scrubbing began, and recreate it once scrubbing ended.
When scrubbing begins:
if (scrubberTimeObserver) {
[player removeTimeObserver:scrubberTimeObserver];
scrubberTimeObserver = nil;
}
Note the you will want to know the name of your time observer so you make sure you're removing the correct one.
When scrubbing ends:
scrubberTimeObserver = [player addPeriodicTimeObserverForInterval:CMTimeMakeWithSeconds(interval, NSEC_PER_SEC)
queue:dispatch_get_main_queue()
usingBlock:^(CMTime time) {
[weakSelf syncScrubber];
}
];
I have a bit of a strange problem. I have a music app that uses the [MPMusicPlayerController iPodMusicPlayer]. Everything is fine, notifications are fired for track changes and changes in playback state.
I have one screen where the user needs to review one single song, I don't want him to go on to the next song in his queue. Since there is no delegate method for when a track WILL change (only DID change), to prevent the music player from continuing to the next track I use a new [MPMusicPlayerController applicationMusicPlayer], give it iPodMusicPlayer's currently playing song and all is well. No new tracks to continue to, and I'm not touching the original iPodMusicPlayer queue so in theory, when I close this screen and use the iPodMusicPlayer again, all should be perfectly fine.
However, when the user is done on this screen and closes it, iPodMusicPlayer is now suddenly broken, notifications are not called and when I put the app to the background, music stops playing, causing me to believe that iPodMusicPlayer is now actually applicationMusicPlayer.
Okay so my question is basically: I need a way to prevent the music player to continue on to the next track in the queue. Switching to applicationMusicPlayer with one track seems to break stuff, as explained above. What's the best solution?
EDIT: because this might be a bit difficult to understand, I created a small project to show the problem: https://github.com/kevinrenskers/MPMusicPlayerControllerTest. Open the app while music is playing, see that the play button behaves correctly. Now open the popup, close it again and the play button is broken.
I found a solution to my problem: set the repeatMode to MPMusicRepeatModeOne and then catch the MPMusicPlayerControllerNowPlayingItemDidChangeNotification notification. You can stop the playback and you never continue to the next track. Once I'm done with the second screen I reset the repeatMode to the original value.
I have a MPMoviePlayer whose controls have been hidden.
I have custom sliders to move the video, back and forth and controls to control the speed as well.
Now whenever it reaches the end I can see a white screen.
app does not crash but I can't see the video.
I tried debugging and realized that moviPlayer instance is still there, but naturalSize is reported to be zero.
rest everything is there, including the contentURL property.
has the player released the video ?
UPDATE:
The bug onbly appears on iOS4 and not on iOS5.
Anyone any idea on what changes have come to movieplayer in the two versions which we might have missed.
I've written custom control which allows the user to change the currentPlaybackTime of a MPMoviePlayerController by clicking or dragging on a custom UIButton that displays an image of some musical notation. The code uses the x position of the touch event to update currentPlaybackTime and it all works fine. I also have a CALayer (a vertical red line) that shows the user where they have touched on the control.
What I'd like to do now is have the red line's (CALayer object) position update if the user changes the currentPlaybackTime property of the movie player using the scrubber (slider) control.
Obviously currentPlaybackTime is always updating as the movie plays, but is there a way to detect if the user interferes with this by skipping forward or backwards?
Many thanks.
You could use Key-Value-Observing to track changes of currentPlaybackTime in your MPMoviePlayerController, but that might generate a lot of events and thus negatively affect your performance. Maybe you can also use KVO with the playbackState property of your MPMoviePlayerController, I believe it changes when the user starts seeking.
Another alternative is that you just setup a repeating timer that updates quite frequently, and everytime it fires you check the new value of currentPlaybackTime. But that might look choppy and it could also affect performance.