MPMoviePlayerController - detect pressing Next/Prev buttons - ios

I'm using MPMoviePlayerController and I need to detect pressing Next/Prev buttons. I tried several things, none of which seem to works.
Here is what I tried:
remote control events
-(void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear: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 *)receivedEvent
{
// stuff
}
The problem is remoteControlReceivedWithEvent method is never called. I've read that this will not work in iOS version higher than 6 - I'm working on iOS 7
notifications
I tried using MPMoviePlayerPlaybackStateDidChangeNotification and check against MPMoviePlaybackStateSeekingForward or MPMoviePlaybackStateSeekingBackward - unfortunatelly, these playback state are set when dragging the playback bar, not when pressing Next/Prev buttons.
Any ideas?

Sorry I don´t understand your problem very well, but if you want use the controls out your App in the Control Center, you can use:
// You need cath the singleton
MPRemoteCommandCenter *myRemote = [MPRemoteCommandCenter sharedCommandCenter];
//And add the selector you can fire depends on the button, a couple of examples:
[myRemote.playCommand addTarget:self action:#selector(myPlayMethods)];
[myRemote.nextTrackCommand addTarget:self action:#selector(myNextTrackMethods)];

try registering for event in :
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
// Turn on remote control event delivery
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
// Set itself as the first responder
[self becomeFirstResponder];
}
Also Don't set kAudioSessionProperty_OverrideCategoryMixWithOthers property

Have you tried MPMoviePlayerNowPlayingMovieDidChangeNotification?
If this does not work then i would suggest moving to a lower level API i.e. AVPlayer. It provides fine grained control over all the actions while video playing and otherwise.

You need to register to handle a notification for moviePlayerLoadStateChanged. When you press the next/prev buttons moviePlayerLoadStateChanged will be called and the loadState will be MPMovieLoadStateUnknown
-(void)registerMyStuff {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerLoadStateChanged:)
name:MPMoviePlayerLoadStateDidChangeNotification
object:self.mpc];
}
- (void)moviePlayerLoadStateChanged:(NSNotification *)notification
{
MPMoviePlayerController *moviePlayer = notification.object;
MPMovieLoadState loadState = moviePlayer.loadState;
if(loadState == MPMovieLoadStateUnknown)
{
// this is where the next/prev buttons notify
// there is no video in this state so load one
// just reload the default movie
NSLog(#"MPMovieLoadStateUnknown");
self.mpc.contentURL = self.fileURL;
[self.mpc prepareToPlay];
return;
}
else if(loadState & MPMovieLoadStatePlayable)
{
NSLog(#"MPMovieLoadStatePlayable");
}
else if(loadState & MPMovieLoadStatePlaythroughOK)
{
NSLog(#"MPMovieLoadStatePlaythroughOK");
} else if(loadState & MPMovieLoadStateStalled)
{
NSLog(#"MPMovieLoadStateStalled");
}
}

You change MPMoviePlayerController overlayView just like change UIImagePickerController overlayView to implement the function you need.
MPMoviePlayerController *moviePlayer = [[MPMoviePlayerController alloc]
initWithContentURL:someUrl];
moviePlayer.movieControlMode = MPMovieControlModeHidden;
[moviePlayer play];
NSArray *windows = [[UIApplication sharedApplication] windows];
if ([windows count] > 1) {
UIWindow *moviePlayerWindow = [[UIApplication sharedApplication] keyWindow];
[moviePlayerWindow addSubview:yourCustomOverlayView];
}

Related

How to add rewind buttons to lock screen?

I have realized representation of my AVPlayer on iPhone lock screen via MPNowPlayingInfoCenter. But I can't found how to add ±15 seconds rewind buttons like in standard Music app.
So the question is How to add this buttons on lock screen?
I'm using AVAudioPlayer at the moment, but the remote controlling method which is - (void)remoteControlReceivedWithEvent:(UIEvent *)event must not be involved with the type of the player you're using.
Follow this:
In your view controller's viewDidLoad method add the following code:
//Make sure the system follows our playback status - to support the playback when the app enters the background mode.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
Then add these methods:
viewDidAppear:: (if not implemented already)
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
//Once the view has loaded then we can register to begin recieving controls and we can become the first responder
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
viewWillDisappear: (if not implemented already)
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
//End recieving events
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
}
And:
//Make sure we can recieve remote control events
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
//if it is a remote control event handle it correctly
if (event.type == UIEventTypeRemoteControl)
{
if (event.subtype == UIEventSubtypeRemoteControlPlay)
{
[self playAudio];
}
else if (event.subtype == UIEventSubtypeRemoteControlPause)
{
[self pauseAudio];
}
else if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause)
{
[self togglePlayPause];
}
else if (event.subtype == UIEventSubtypeRemoteControlBeginSeekingBackward)
{
[self rewindTheAudio]; //You must implement 15" rewinding in this method.
}
else if (event.subtype == UIEventSubtypeRemoteControlBeginSeekingForward)
{
[self fastForwardTheAudio]; //You must implement 15" fast-forwarding in this method.
}
}
}
This is working fine in my app, however if you want to be able to receive remote control events in all view controllers, then you should set it in the AppDelegate.

iOS 7 MPMoviePlayerController seek forward button brings the video to the End and displays Black screen

I am facing an issue with MPMoviePlayerController in iOS 7. I enter the fullscreen and then click (just a single tap) on seek forward button (>>|) , and the video playback ends and gives a black screen with a text "Loading" on the header.
I registered notification for "MPMoviePlayerPlaybackStateDidChangeNotification".
**[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerPlaybackStateDidChange:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:self.player];**
It does not get fired on a single click of seek forward button.
Also on registration of "MPMoviePlayerPlaybackDidFinishNotification"
**[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerPlaybackDidFinish:)
name:MPMoviePlayerPlaybackDidFinishNotification
object:nil];**
I get "MPMovieFinishReasonPlaybackEnded" event fired on that single click of seek forward button.
Any one knows the reason why? Is this a bug in apple?
I need to either stop this behavior of showing a black screen on single click , or just disable single click of seek forward button so that nothing happens.
Any one knows how to achieve this?
I fixed this by removing the MPMoviePlayer object completely, setting it to nil, removing it from it's superview and re-adding it using the original video Url. Code below:
- (void)addPlayerForUrl:(NSURL *)url {
self.player = [[MPMoviePlayerController alloc] initWithContentURL:url];
self.player.view.frame = self.videoView.bounds;
self.player.view.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
self.player.controlStyle = MPMovieControlStyleDefault;
[self.videoView insertSubview:self.player.view atIndex:0];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerLoadStateDidChangedNotification:)
name:MPMoviePlayerReadyForDisplayDidChangeNotification
object:self.player];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(moviePlayerPlaybackStateDidChangeNotification:)
name:MPMoviePlayerPlaybackStateDidChangeNotification
object:self.player];
}
#pragma mark - Notifications
- (void)moviePlayerLoadStateDidChangedNotification:(NSNotification *)notification {
self.isVideoPreloaded = YES;
self.videoPlayButton.hidden = YES;
self.photoImageView.hidden = YES;
self.videoLoadingImageView.hidden = YES;
}
- (void)moviePlayerPlaybackStateDidChangeNotification:(NSNotification *)notification {
NSURL *url = self.player.contentURL;
switch (self.player.playbackState) {
case MPMoviePlaybackStateSeekingBackward:
case MPMoviePlaybackStateSeekingForward:
break;
case MPMoviePlaybackStatePlaying:
self.videoPlayButton.hidden = YES;
if (!self.isVideoPreloaded) {
self.videoLoadingImageView.hidden = NO;
[self.videoLoadingImageView startAnimating];
} else {
self.videoLoadingImageView.hidden = YES;
}
break;
case MPMoviePlaybackStatePaused:
case MPMoviePlaybackStateStopped:
self.videoPlayButton.hidden = NO;
self.videoLoadingImageView.hidden = YES;
[self.player endSeeking];
[self.player.view removeFromSuperview];
[self.player setFullscreen:NO];
self.player = nil;
[self addPlayerForUrl:url];
break;
default:
break;
}
}
Notice how I keep the NSURL, right before the switch statement in the moviePlayerPlaybackStateDidChangeNotification. That way, I can re-initialize and re-add the MPMoviePlayer object.
Btw, my mpmovieplayer is on a tableviewCell if you're wondering. Hope this helps and let me know if you have questions. Good luck!
MPMoviePlayerLoadStateDidChangeNotification will be called when you single tap on the fast-forward or rewind button. You should check the loadState and just give it the path to your video and prepareToPlay again.
- (void)moviePlayerLoadStateChanged:(NSNotification *)notification {
MPMoviePlayerController *moviePlayer = notification.object;
MPMovieLoadState loadState = moviePlayer.loadState;
if(loadState == MPMovieLoadStateUnknown) {
moviePlayer.contentURL = [NSURL fileURLWithPath:videoPath]
[moviePlayer prepareToPlay];
}
.....
}
The reason you're getting MPMovieFinishReasonPlaybackEnded is because playback reached the end of the video (sorry if this is obvious). So it seem's your seek forward actions are seeking all the way to the end of the video. You can check the playback state with MPMoviePlaybackStateSeekingForward.
A quick solution could be to create your own forward button that seek's ahead by a specified time (ie. 5 seconds). But perhaps this isn't the functionality you're looking for.

Unable to handle remote control events for backgronud audio

In the view controller for my audio player I've added this:
- (void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
- (void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
This switches the icon in the player controls from the iPod icon to my own app, it also puts the little playback icon in the status bar.
Next I added this to my view controller to handle the remote events:
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
NSLog(#"REMOTE EVENT!");
switch (event.subtype) {
case UIEventSubtypeRemoteControlTogglePlayPause:
[streamer pause];
break;
case UIEventSubtypeRemoteControlPlay:
[streamer start];
break;
case UIEventSubtypeRemoteControlPause:
[streamer pause];
break;
case UIEventSubtypeRemoteControlStop:
[streamer stop];
break;
default:
break;
}
}
However, this is never called. I tried bringing up the playback controls while the app was running, I tried going back to my home screen and tapping some playback controls, and I tried my earbuds' controls. All had no luck.
Does anyone have any pointers as to where I can be going wrong?
Thanks.
You have implemented the wrong method: instead of - (void) viewWillAppear:(BOOL)animated it should have been - (void)viewDidAppear:(BOOL)animated.
I ran into this problem before and discovered that in my problem it was because my view was a subview and the parent was catching the remote events. I would start in the AppDelegate and implement the method and see if anything is being sent to the AppDelegate and then trace it down from there. Chances are there is a view or viewController that is catching the event and not passing it along.
Have you made sure to set your audio session? Use AVAudioSession and set the category to AVAudioSessionCategoryPlayback before becoming first responder.

iPad MPMoviePlayerController - Disable Fullscreen

Is there a way to disable the fullscreen button of the MPMoviePlayerController ?
Just did it:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieEventFullscreenHandler:)
name:MPMoviePlayerWillEnterFullscreenNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(movieEventFullscreenHandler:)
name:MPMoviePlayerDidEnterFullscreenNotification
object:nil];
self.moviePlayer.controlStyle = MPMovieControlStyleEmbedded;
}
- (void)movieEventFullscreenHandler:(NSNotification*)notification {
[self.moviePlayer setFullscreen:NO animated:NO];
[self.moviePlayer setControlStyle:MPMovieControlStyleEmbedded];
}
Depending on your needs, you can also simply disable all user interactions on the player view.
player.view.userInteractionEnabled = NO;
You can set controlStyle to Fullscreen. these controls are somewhat different, but it doesn't feature a Fullscreen button!
[_moviePlayerController setControlStyle:MPMovieControlStyleFullscreen];
You could hide the playback controls and add your own custom ones, this will prevent the default buttons being rendered at all
I.e with
[player setMovieControlMode:MPMovieControlModeNone];
Unfortunately none of above worked for me properly, so picking the above I implemented the following (and worked fine):
Hide the full screen button.
Add this code in the method where you initialise the movie player.
....
//Because we have to wait until controllers are shown
[self performSelector:#selector(hideFullscreenButton) withObject:self afterDelay:0.5];
...
Add the methods:
-(void) hideFullscreenButton{
//Hide full screen mode button
[self hideFullscreenSubview:movieClip.view.subviews];
}
-(void) hideFullscreenSubview:(NSArray*)arr{
for(UIView *v in arr){
if([v.subviews count]>0)
[self hideFullscreenSubview:v.subviews];
else
NSLog(#"%#",v);
if(v.frame.origin.x==975 ){
v.hidden=TRUE;
}
}
}
The problem relies that there is no tag to identify which view you have to hide. In my case I figure it out by the view coordinates.
Overwrite tap gestures for do not allowing fullscreen zoom.
movieClip.controlStyle = MPMovieControlStyleEmbedded;
//Disable tap for not allowing that video control set on a full screen mode.
UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget: self action:#selector(doSingleTap)];
singleTap.numberOfTapsRequired = 1;
[movieClip.view addGestureRecognizer:singleTap];
UITapGestureRecognizer *doubleTap = [[UITapGestureRecognizer alloc] initWithTarget: self action:#selector(doDoubleTap)];
doubleTap.numberOfTapsRequired = 2;
[movieClip.view addGestureRecognizer:doubleTap];
[singleTap requireGestureRecognizerToFail:doubleTap];
And add the selector methods:
-(void) doSingleTap{
//DO NOTHING!!!
}
-(void) doDoubleTap{
//DO NOTHING!!!
}
There's a cheat:
MPMoviePlayerController *mpc = (...some instance...)
UIView *fsbutton = [[mpc view] viewWithTag:512];
[fsbutton setHidden:YES];
The main catch is, you have to do it in viewDidAppear: or similar, because the MoviePlayer view sets itself up somewhere inside didMoveToWindow or didMoveToSuperview, which happen after viewWillAppear:. So you get a brief flash of the fullscreen button. Other obvious catches include: brittle vs. Apple changing that 512 tag value (although it works in 3.2 - 4.2); and of course Apple would rather you not do this.
The endorsed solution is to set the control style to MPMovieControlStyleNone and roll your own transport controls, which is more work.
No, there is no way. Hopefully with the next update.
in order to disable switch to full screen mode, either form button or pinch gesture, you can use this:
moviePlayer.controlStyle = MPMovieControlStyleNone;
moviePlayer.view.userInteractionEnabled =NO;
Wired does this. For the videos that start in fullscreen, they have the standard MPMoviePlayerController controls, but are missing the fullscreen buttons. And they're using the standard built-in ones, since they suddenly got an AirPlay button with 4.2.
Simple block to remove pinch zoom here
Hope it help
it work with me on iOS6
for (UIView *view in moviePlayer.view.subviews) {
for(UIPinchGestureRecognizer *pinch in view.gestureRecognizers){
if([pinch isKindOfClass:[UIPinchGestureRecognizer class]])
[view removeGestureRecognizer:pinch];
}
}
This worked on iOS 7, iPhone 5s.
Add Notification:
MPMoviePlayerDidEnterFullscreenNotification : #"moviePlayFullscreenNote:"
- (void)moviePlayFullscreenNote:(NSNotification*)notification
{
if (notification.object == self.videoPlayer)
{
[self.videoPlayer setFullscreen:NO animated:YES];
self.videoPlayer.controlStyle = MPMovieControlStyleEmbedded;
}
}
Notice that I only listen for "DID" and not the "WILL" notification as well as running it animated. I think this works as it gives the system time to react. When I used the "WILL" and "DID" as noted in answers above it led to a black screen with no controls. There is a slight glitch that is visible when the transition occurs, but I need the play/scrub buttons from embedded.
Fullscreen button along with pause button can be removed.
[self.videoPlayer setControlStyle:MPMovieControlStyleNone];
If the only thing you want to do is disable pinch to go full screen (i.e. keep interaction enabled and whatever control style you want), you can use this:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
NSSet *set = [event allTouches];
NSArray *arr = [set allObjects];
for (int i = 0; i < arr.count; i++) {
UITouch *touch = (UITouch *) [arr objectAtIndex:i];
NSArray *recognisers = touch.gestureRecognizers;
for (UIGestureRecognizer *recogniser in recognisers) {
if (recogniser.enabled && [recogniser isMemberOfClass:[UIPinchGestureRecognizer class]]) {
recogniser.enabled = NO;
}
}
}
}
This is the Swift version of the first solution of Javier Calatrava Llavería:
func hideFullScreenButton() {
self.hideFullScreenSubview((self.moviePlayerController?.view.subviews)!)
}
func hideFullScreenSubview(subviews: [UIView]) {
for view: UIView in subviews {
if view.subviews.count > 0 {
self.hideFullScreenSubview(view.subviews)
}
if view.frame.origin.x == 631 {
view.hidden = true
}
}
}
And when the user taps on Play:
self.performSelector(#selector(VideoViewController.hideFullScreenButton), withObject: self, afterDelay: 0.5)
(VideoViewController is the view controller in which I have the MPMoviePlayerController)
I know, it's a little outdated, but anyway. I did some research in that direction, and looks like a found an answer. I do not know, why it's working, but it is.
-(void) playMovieAtURL: (NSURL*) theURL {
MPMoviePlayerController* theMovie =
[[MPMoviePlayerController alloc] initWithContentURL: theURL];
//That line is for ARC. Without it, it may not work.
self.moviePlayer = theMovie;
theMovie.scalingMode = MPMovieScalingModeAspectFill;
theMovie.controlStyle = MPMovieControlStyleFullscreen;
theMovie.repeatMode = MPMovieRepeatModeOne;
//Here you'd better use your custom ViewController subclass, if you want autorotating and all that stuff.
UIViewController * vc = [UIViewController new];
[vc.view addSubview:theMovie.view];
theMovie.fullscreen = YES;
theMovie.view.frame = vc.view.bounds;
vc.view = theMovie.view;
[self presentModalViewController:vc animated:YES];
theMovie.fullscreen = YES;
[theMovie prepareToPlay];
[theMovie play];
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(myMovieFinishedCallback:) name:MPMoviePlayerPlaybackDidFinishNotification object:nil];
}
// When the movie is done, release the controller.
-(void) myMovieFinishedCallback: (NSNotification*) aNotification
{
[self dismissModalViewControllerAnimated:YES];
MPMoviePlayerController* theMovie = [aNotification object];
[[NSNotificationCenter defaultCenter]
removeObserver: self
name: MPMoviePlayerPlaybackDidFinishNotification
object: theMovie];
[self.moviePlayer.view removeFromSuperview];
self.moviePlayer = nil;
// Release the movie instance created in playMovieAtURL:
}
Put a UIView or UIButton with transparent background on top of the view that shows the video, so that the user won't be able to tap on the view that contains the video.

How can I know users click fast forward and fast rewind buttons on the playback controls in iPhone

I want to implement the following things,
App is running a music or video (using MPMoviePlayerController) in background.
User double clicks the home button and go to the first screen showing playback controls (fast rewind, play or pause, fast forward buttons)
User click fast rewind or fast forward button.
Then app play previous or next music or video.
For the 3rd step, I should know which button is clicked.
(As I naturally know, the currently playing item is paused, stopped.. using MPMoviePlayerPlaybackStateDidChangeNotification notification).
Which notification should I register? Or are there any other approaches?
I got the answer by myself.
That is using UIApplication's beginReceivingRemoteControlEvents.
In an appropriate place (like viewWillAppear:) put the following code
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
And the view controller should implement the following method returning YES
- (BOOL)canBecomeFirstResponder {
return YES;
}
And then you can receive remote controller event in the following method.
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
if( event.type == UIEventTypeRemoteControl ) {
NSLog(#"sub type: %d", event.subtype);
}
}
And event.subtype is as below,
typedef enum {
// available in iPhone OS 3.0
UIEventSubtypeNone = 0,
// for UIEventTypeMotion, available in iPhone OS 3.0
UIEventSubtypeMotionShake = 1,
// for UIEventTypeRemoteControl, available in iPhone OS 4.0
UIEventSubtypeRemoteControlPlay = 100,
UIEventSubtypeRemoteControlPause = 101,
UIEventSubtypeRemoteControlStop = 102,
UIEventSubtypeRemoteControlTogglePlayPause = 103,
UIEventSubtypeRemoteControlNextTrack = 104,
UIEventSubtypeRemoteControlPreviousTrack = 105,
UIEventSubtypeRemoteControlBeginSeekingBackward = 106,
UIEventSubtypeRemoteControlEndSeekingBackward = 107,
UIEventSubtypeRemoteControlBeginSeekingForward = 108,
UIEventSubtypeRemoteControlEndSeekingForward = 109,
} UIEventSubtype;
This might be a very late answer, but as I notice, there aren't many Q/As about audio playing and remote controls, so I hope my answer helps the others who have the same problem:
I'm using AVAudioPlayer at the moment, but the remote controlling method which is - (void)remoteControlReceivedWithEvent:(UIEvent *)event must not be involved with the type of the player you're using.
To get the forward and rewind buttons on lock screen work, follow this:
In your view controller's viewDidLoad method add the following code:
//Make sure the system follows our playback status - to support the playback when the app enters the background mode.
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryPlayback error:nil];
[[AVAudioSession sharedInstance] setActive: YES error: nil];
Then add these methods:
viewDidAppear:: (if not implemented already)
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
//Once the view has loaded then we can register to begin recieving controls and we can become the first responder
[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];
}
viewWillDisappear: (if not implemented already)
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
//End recieving events
[[UIApplication sharedApplication] endReceivingRemoteControlEvents];
[self resignFirstResponder];
}
And:
//Make sure we can recieve remote control events
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)remoteControlReceivedWithEvent:(UIEvent *)event {
//if it is a remote control event handle it correctly
if (event.type == UIEventTypeRemoteControl)
{
if (event.subtype == UIEventSubtypeRemoteControlPlay)
{
[self playAudio];
}
else if (event.subtype == UIEventSubtypeRemoteControlPause)
{
[self pauseAudio];
}
else if (event.subtype == UIEventSubtypeRemoteControlTogglePlayPause)
{
[self togglePlayPause];
}
else if (event.subtype == UIEventSubtypeRemoteControlBeginSeekingBackward)
{
[self rewindTheAudio]; //You must implement 15" rewinding in this method.
}
else if (event.subtype == UIEventSubtypeRemoteControlBeginSeekingForward)
{
[self fastForwardTheAudio]; //You must implement 15" fastforwarding in this method.
}
}
}
This is working fine in my app, however if you want to be able to receive remote control events in all view controllers, then you should set it in the AppDelegate.
NOTE! This code is working fine at the moment, but I see two more subtypes called UIEventSubtypeRemoteControlEndSeekingBackward and UIEventSubtypeRemoteControlEndSeekingBackward. I'm not sure if they have to be implemented or not, if someone knows about it, let us know.

Resources