Подтвердить что ты не робот

Существует ли общедоступный способ заставить MPNowPlayingInfoCenter отображать элементы управления подкастом?

Я бы хотел, чтобы Control Center (через MPNowPlayingInfoCenter) показывал 15 секундные/15-секундные элементы управления, которые Apple показывает с подкастами, например:

podcast controls

Полная нехватка документации говорит мне, что нет очевидного способа сделать это, но кто-нибудь там нашел какой-либо неочевидный способ заставить это, не прибегая к частному методу?

У меня уже есть настройка для кнопки "вперед/назад", настроенной так, чтобы продвигаться соответствующим образом, я просто хотел бы использовать более подходящий интерфейс. Любая помощь будет принята с благодарностью.

4b9b3361

Ответ 1

ОК, поэтому у меня было немного времени на моих руках, и поэтому я последовал за панировкой... Это то, что я нашел.

Включите среду MediaPlayer и получите RemoteCommandCenter:

MPRemoteCommandCenter *rcc = [MPRemoteCommandCenter sharedCommandCenter];

то, если вы хотите установить элементы управления пропусками в соответствии с Overcast, вы можете сделать следующее:

MPSkipIntervalCommand *skipBackwardIntervalCommand = [rcc skipBackwardCommand];
[skipBackwardIntervalCommand setEnabled:YES];
[skipBackwardIntervalCommand addTarget:self action:@selector(skipBackwardEvent:)];
skipBackwardIntervalCommand.preferredIntervals = @[@(42)];  // Set your own interval

MPSkipIntervalCommand *skipForwardIntervalCommand = [rcc skipForwardCommand];
skipForwardIntervalCommand.preferredIntervals = @[@(42)];  // Max 99
[skipForwardIntervalCommand setEnabled:YES];
[skipForwardIntervalCommand addTarget:self action:@selector(skipForwardEvent:)];

а в обработчиках событий сделайте то, что вам нужно сделать, чтобы пропустить интервал:

-(void)skipBackwardEvent: (MPSkipIntervalCommandEvent *)skipEvent
{
    NSLog(@"Skip backward by %f", skipEvent.interval);
}

-(void)skipForwardEvent: (MPSkipIntervalCommandEvent *)skipEvent
{
    NSLog(@"Skip forward by %f", skipEvent.interval);
}

Примечание. Предпочтительным свойствомIntervals является NSArray, но я не понял, как дополнительные интервалы могут использоваться командным центром, если вы не сделаете что-то с этим сами.

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

MPRemoteCommand *pauseCommand = [rcc pauseCommand];
[pauseCommand setEnabled:YES];
[pauseCommand addTarget:self action:@selector(playOrPauseEvent:)];
//    
MPRemoteCommand *playCommand = [rcc playCommand];
[playCommand setEnabled:YES];
[playCommand addTarget:self action:@selector(playOrPauseEvent:)];

(есть также параметр togglePlayPauseCommand, но я не мог заставить его стрелять из Command Center - он работает только от наушников.)

Другие открытия: Кнопки находятся в фиксированных положениях влево/вправо/вправо, поэтому у вас нет (например) предыдущегоTrack и skipBackward, поскольку оба они занимают левую позицию.

Существуют команды seekForward/seekBackward, для которых требуется команда prevTrack и nextTrack. Когда вы настраиваете оба, один раз нажмите триггеры next/previous и нажмите и удерживайте триггеры, чтобы начать поиск и конец, когда вы поднимаете палец.

    // Doesn’t show unless prevTrack is enabled
    MPRemoteCommand *seekBackwardCommand = [rcc seekBackwardCommand];
    [seekBackwardCommand setEnabled:YES];
    [seekBackwardCommand addTarget:self action:@selector(seekEvent:)];

    // Doesn’t show unless nextTrack is enabled
    MPRemoteCommand *seekForwardCommand = [rcc seekForwardCommand];
    [seekForwardCommand setEnabled:YES];
    [seekForwardCommand addTarget:self action:@selector(seekEvent:)];

-(void) seekEvent: (MPSeekCommandEvent *) seekEvent
{
    if (seekEvent.type == MPSeekCommandEventTypeBeginSeeking) {
        NSLog(@"Begin Seeking");
    }
    if (seekEvent.type == MPSeekCommandEventTypeEndSeeking) {
        NSLog(@"End Seeking");
    }
}

Существует также механизм обратной связи, который я ранее не видел (занимает левую позицию)

    MPFeedbackCommand *likeCommand = [rcc likeCommand];
    [likeCommand setEnabled:YES];
    [likeCommand setLocalizedTitle:@"I love it"];  // can leave this out for default
    [likeCommand addTarget:self action:@selector(likeEvent:)];

    MPFeedbackCommand *dislikeCommand = [rcc dislikeCommand];
    [dislikeCommand setEnabled:YES];
    [dislikeCommand setActive:YES];
    [dislikeCommand setLocalizedTitle:@"I hate it"]; // can leave this out for default
    [dislikeCommand addTarget:self action:@selector(dislikeEvent:)];

    BOOL userPreviouslyIndicatedThatTheyDislikedThisItemAndIStoredThat = YES;

    if (userPreviouslyIndicatedThatTheyDislikedThisItemAndIStoredThat) {
        [dislikeCommand setActive:YES];
    }

    MPFeedbackCommand *bookmarkCommand = [rcc bookmarkCommand];
    [bookmarkCommand setEnabled:YES];
    [bookmarkCommand addTarget:self action:@selector(bookmarkEvent:)];

// Feedback events also have a "negative" property but Command Center always returns not negative
-(void)dislikeEvent: (MPFeedbackCommandEvent *)feedbackEvent
{
    NSLog(@"Mark the item disliked");
}

-(void)likeEvent: (MPFeedbackCommandEvent *)feedbackEvent
{
    NSLog(@"Mark the item liked");
}

-(void)bookmarkEvent: (MPFeedbackCommandEvent *)feedbackEvent
{
    NSLog(@"Bookmark the item or playback position");
}

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

Существует также определенная команда рейтинга, но я не мог ее отобразить в командном центре

//    MPRatingCommand *ratingCommand = [rcc ratingCommand];
//    [ratingCommand setEnabled:YES];
//    [ratingCommand setMinimumRating:0.0];
//    [ratingCommand setMaximumRating:5.0];
//    [ratingCommand addTarget:self action:@selector(ratingEvent:)];

и команду изменения скорости воспроизведения - но опять-таки не удалось получить это в Command Center

//    MPChangePlaybackRateCommand *playBackRateCommand = [rcc changePlaybackRateCommand];
//    [playBackRateCommand setEnabled:YES];
//    [playBackRateCommand setSupportedPlaybackRates:@[@(1),@(1.5),@(2)]];
//    [playBackRateCommand addTarget:self action:@selector(remoteControlReceivedWithEvent:)];

Существует также блок-механизм целевых действий, если вы предпочитаете

// @property (strong, nonatomic) id likeHandler;
    self.likeHandler = [likeCommand addTargetWithHandler:^MPRemoteCommandHandlerStatus(MPRemoteCommandEvent *event) {
        NSLog(@"They like it");
        return MPRemoteCommandHandlerStatusSuccess;  // or fail or no such content
    }];

Один последний момент, о котором нужно знать: если вы зарегистрировались для получения удаленных событий через [[UIApplication sharedApplication] beginReceivingRemoteControlEvents]; то некоторые из этих команд также запускают события в обработчике получаемого обработчика - (void) remoteControlReceivedWithEvent: (UIEvent *) receivedEvent. Это UIEvents, но с типом UIEventTypeRemoteControl и подтипом, чтобы отличать событие. Вы не можете смешивать и сопоставлять их с MPRemoteCommandEvents в этом методе. Есть подсказки, что MPRemoteCommandEvents в какой-то момент заменит UIEvents.

Все это на основе проб и ошибок, поэтому не стесняйтесь исправить.

Гарет

Screenshot of feedback command and skipforward

Ответ 2

Для разработчиков Swift

import MediaPlayer

let rcc = MPRemoteCommandCenter.shared()

let skipBackwardCommand = rcc.skipBackwardCommand
skipBackwardCommand.isEnabled = true
skipBackwardCommand.addTarget(handler: skipBackward)
skipBackwardCommand.preferredIntervals = [42]

let skipForwardCommand = rcc.skipForwardCommand
skipForwardCommand.isEnabled = true
skipForwardCommand.addTarget(handler: skipForward)
skipForwardCommand.preferredIntervals = [42]

func skipBackward(_ event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
    guard let command = event.command as? MPSkipIntervalCommand else {
        return .noSuchContent
    }

    let interval = command.preferredIntervals[0]

    print(interval) //Output: 42

    return .success
}

func skipForward(_ event: MPRemoteCommandEvent) -> MPRemoteCommandHandlerStatus {
    guard let command = event.command as? MPSkipIntervalCommand else {
        return .noSuchContent
    }

    let interval = command.preferredIntervals[0]

    print(interval) //Output: 42

    return .success
}

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

Ответ 3

Oooooooh. Марко Армент получил это, чтобы работать в Overcast, и, по крайней мере, оставил тропу для парней Кастро с этот твит:

Свой MPRemoteCommandCenter. Удачи вам в документации.

Здесь указанная документация для тех, кто следит за этим вопросом - я предполагаю, что это связано с skipBackwardCommand и skipForwardCommand. У меня нет времени, чтобы заглянуть в нее на эту секунду, поэтому я оставлю это здесь, если кто-то захочет совать ее и дать более подробный ответ.

Ответ 4

У Apple нет документации, потому что нет возможности изменить это. Опять же, Apple держит лучшие вещи для себя (Сири тоже приходит на ум).

Jailbroken version поддерживает изменение кнопок Control Center, которые я нашел на этом сайте. У меня такое ощущение, что вы хотите использовать это приложение на самом iOS 7, а не на взломанной версии, так что это вам совсем не поможет.

Эти частные API мешают слишком быстро разрабатывать хорошие приложения. Если Apple не предоставит нам больше свободы использования API-интерфейсов в настоящее время, вам не повезло.

Ответ 5

В дополнение к другим ответам я обнаружил, что если я не установил nowPlayingInfo в MPNowPlayingInfoCenter, то кнопки пропуска не появляются, но появляются кнопки по умолчанию nextTrack и PreviousTrack. (простые кнопки перемотки вперед и назад) Убедитесь, что вы устанавливаете MPNowPlayingInfoCenter.defaultCenter(). nowPlayingInfo в некоторый момент, как показано ниже:

 var songInfo: NSMutableDictionary = [
        MPMediaItemPropertyTitle: "song title",
        MPMediaItemPropertyArtist: "artist ",
        MPNowPlayingInfoPropertyElapsedPlaybackTime: "0"
    ]
    MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo = songInfo as [NSObject : AnyObject]