是否有公共方法强制MPNowPlayingInfoCenter显示播客控件?

Des*_*erd 50 audio ios mpnowplayinginfocenter ios7 control-center

我希望控制中心(通过MPNowPlayingInfoCenter)显示Apple用播客显示的前进15秒/后15秒控制,如下所示:

播客控件

完全缺乏文档告诉我,没有明显的方法可以做到这一点,但有没有人发现任何非显而易见的方法来强制这个而不诉诸私有方法?

我已经处理了前进/后退按钮设置以适当推进,我只想使用更合适的UI.任何帮助将不胜感激.

Gar*_*eth 116

好的,所以我有一点时间在我的手上,所以我跟着面包屑.这就是我发现的.

包括MediaPlayer框架并获取RemoteCommandCenter:

MPRemoteCommandCenter *rcc = [MPRemoteCommandCenter sharedCommandCenter];
Run Code Online (Sandbox Code Playgroud)

然后,如果您想按照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:)];
Run Code Online (Sandbox Code Playgroud)

并且在事件中,处理程序执行您需要执行的操作以跳过间隔:

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

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

注意:preferredIntervals属性是NSArray,但我还没有想出指令中心如何使用额外的间隔,除非你自己做了一些事情.

值得注意的是,到目前为止我已经找到了.执行此操作时,您将控制所有控件,因此默认播放和暂停按钮将不会显示,除非您对它们执行相同的操作:

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:)];
Run Code Online (Sandbox Code Playgroud)

(还有一个togglePlayPauseCommand已定义,但我无法从命令中心触发它 - 虽然它确实从耳机发射.)

其他发现:按钮位于左/中/右的固定位置,因此您不能(例如)previousTrack和skipBackward,因为它们都占据左侧位置.

有seekForward/seekBackward命令需要触发prevTrack和nextTrack命令.当您同时设置两个时,单个触发器会触发下一个/上一个触发器,当您抬起手指时,按住该按钮会触发开始搜索和结束搜索.

    // 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");
    }
}
Run Code Online (Sandbox Code Playgroud)

还有一个我以前没见过的反馈机制(占据左侧位置)

    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");
}
Run Code Online (Sandbox Code Playgroud)

这将显示三个水平条并显示警告表 - 您可以通过设置活动属性来单独突出显示这些警告表.

还定义了一个评级命令 - 但是我无法在命令中心显示它

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

和播放速率更改命令 - 但再次无法在命令中心显示

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

如果您愿意,还有一个基于块的目标行动机制

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

最后要注意的一点是:如果您已通过[[UIApplication sharedApplication] beginReceivingRemoteControlEvents]注册接收远程事件; 然后其中一些命令也会触发 - (void)remoteControlReceivedWithEvent:(UIEvent*)receivedEvent处理程序中的事件.这些是UIEvents,但具有类型UIEventTypeRemoteControl和用于区分事件的子类型.您不能在此方法中将这些与MPRemoteCommandEvents混合使用.有一些提示,MPRemoteCommandEvents将在某些时候取代UIEvents.

所有这一切都基于反复试验,所以请随意纠正.

加雷思

反馈命令和skipforward的屏幕截图

  • 请注意,7.1中添加了"MPRemoteCommandCenter",这可能解释了为什么没有人使用它! (5认同)
  • 感谢您提供非常详细的答案! (2认同)

zom*_*bie 8

对于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
}
Run Code Online (Sandbox Code Playgroud)

其他命令类似,可以在这里查看