Как я могу узнать, что пользователи нажимают кнопки быстрой перемотки вперед и назад на элементах управления воспроизведением на iPhone

Я хочу реализовать следующие вещи,

  1. Приложение воспроизводит музыку или видео (используя MPMoviePlayerController) в фоновом режиме.
  2. Пользователь дважды нажимает кнопку «Домой» и переходит на первый экран, на котором отображаются элементы управления воспроизведением (быстрая перемотка назад, воспроизведение или пауза, кнопки быстрой перемотки вперед).
  3. Пользователь нажимает кнопку быстрой перемотки назад или вперед. Затем приложение воспроизводит предыдущую или следующую музыку или видео.

Для третьего шага я должен знать, какая кнопка нажата. (Как я, естественно, знаю, текущий воспроизводимый элемент приостанавливается, останавливается ... с помощью MPMoviePlayerPlaybackStateDidChangeNotification уведомления).

Какое уведомление мне нужно зарегистрировать? Или есть другие подходы?


person alones    schedule 29.08.2010    source источник
comment
как я могу воспроизводить звуки с помощью MPMoviePlayerController?   -  person Arthur Neves    schedule 09.05.2011


Ответы (2)


Я получил ответ сам.

Это использует beginReceivingRemoteControlEvents UIApplication.

В подходящем месте (например, viewWillAppear :) поместите следующий код

[[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
[self becomeFirstResponder];

И контроллер представления должен реализовать следующий метод, возвращающий YES

- (BOOL)canBecomeFirstResponder {
    return YES; 
}

И затем вы можете получить событие удаленного контроллера следующим способом.

- (void)remoteControlReceivedWithEvent:(UIEvent *)event {

    if( event.type == UIEventTypeRemoteControl ) {
        NSLog(@"sub type: %d", event.subtype);
    }
}

И event.subtype, как показано ниже,

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;
person alones    schedule 30.08.2010
comment
Кажется, это не работает в симуляторе под управлением устройства iPhone 4.1? Это так или я что-то не так делаю? - person Johan Carlsson; 20.11.2010
comment
Кажется, у меня точно такая же настройка, но я просто не могу получить никаких событий. - person JOM; 23.12.2010
comment
Пожалуйста, проверьте, действительно ли вы стали FirstResponder. И проверьте, вызывают ли другие классы команду beginFirstResponder после класса, который будет получать события с именем beginFirstResponder. - person alones; 22.01.2011
comment
Кажется, существует неоднозначный опыт независимо от того, работает ли захват событий удаленного управления или нет. Alones, не могли бы вы предоставить отдельный образец для своего решения, пожалуйста? - person DrMickeyLauer; 12.05.2011
comment
Я получил это, чтобы реагировать на нажатия кнопок через элементы управления наушников iPhone, но не на экранные кнопки. Кому-нибудь повезло с захватом экранных кнопок «следующая / предыдущая»? - person amrox; 18.10.2011
comment
@amrox Я надеюсь, что вы уже решили эту проблему, но я понял, как это сделать, и отправляю свой ответ ниже. - person Neeku; 04.12.2013
comment
похоже, это не работает на iPhone 6 с iOS 8.1, isFirstResponder верен, но события не принимаются. - person taber; 02.11.2014
comment
@alones Это не работает для iOS 8.1! Я пробовал и не могу заставить его работать. - person valbu17; 03.02.2015
comment
@taber вы нашли решение или обходной путь? - person valbu17; 03.02.2015
comment
@NorthBlast: нет, сдался и вместо этого использовал AVFoundation - person taber; 04.02.2015
comment
Кажется, это не срабатывает. - person NFerocious; 02.06.2015

Это может быть очень поздний ответ, но, как я заметил, не так много вопросов и ответов о воспроизведении звука и удаленном управлении, поэтому я надеюсь, что мой ответ поможет другим, у кого такая же проблема:

В настоящий момент я использую AVAudioPlayer, но метод удаленного управления - (void)remoteControlReceivedWithEvent:(UIEvent *)event не должен зависеть от типа плеера, который вы используете.

Чтобы кнопки перемотки вперед и назад на заблокированном экране работали, выполните следующие действия:

В методе viewDidLoad вашего контроллера представления добавьте следующий код:

//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];

Затем добавьте эти методы: viewDidAppear:: (если еще не реализовано)

- (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: (если еще не реализовано)

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    //End recieving events
    [[UIApplication sharedApplication] endReceivingRemoteControlEvents];
    [self resignFirstResponder];
}

И:

//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.
        }

    }
}

Это нормально работает в моем приложении, однако, если вы хотите иметь возможность получать события удаленного управления во всех контроллерах представления, вам следует установить его в AppDelegate.

ПРИМЕЧАНИЕ! В настоящий момент этот код работает нормально, но я вижу еще два подтипа, которые называются UIEventSubtypeRemoteControlEndSeekingBackward и UIEventSubtypeRemoteControlEndSeekingBackward. Я не уверен, нужно ли их внедрять или нет, если кто-то знает об этом, дайте нам знать.

person Neeku    schedule 04.12.2013
comment
Вы тестировали iOS 8? потому что, похоже, не работает @Neeku - person valbu17; 03.02.2015
comment
@NorthBlast нет, я был в этом больше года назад, но скоро нужно будет обновить и протестировать его на iOS 8 ... - person Neeku; 04.02.2015
comment
@NorthBlast Кстати, вы можете подумать, что это не работает, но вам действительно нужно долгое нажатие (нажатие и удерживание некоторое время), чтобы перемотать его назад. Это не так хорошо, как собственное приложение Apple Podcast, но с ограниченным доступом к библиотеке, этого достаточно. - person Neeku; 06.02.2015