Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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,

  1. App is running a music or video (using MPMoviePlayerController) in background.
  2. User double clicks the home button and go to the first screen showing playback controls (fast rewind, play or pause, fast forward buttons)
  3. 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?

like image 365
alones Avatar asked Aug 29 '10 05:08

alones


2 Answers

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;
like image 167
alones Avatar answered Oct 16 '22 04:10

alones


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.

like image 28
Neeku Avatar answered Oct 16 '22 05:10

Neeku