54

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

播客控件

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

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

4

5 回答 5

123

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

包含 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);
}

注意: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:)];

(还定义了一个 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");
    }
}

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

    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");
}

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

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

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

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

//    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。

所有这些都基于反复试验,因此请随时纠正。

加雷斯

反馈命令和跳转的截图

于 2014-07-18T06:14:51.423 回答
11

对于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
}

其他命令将是类似的,他们可以在这里检查

于 2017-02-27T11:30:40.473 回答
3

哦哦哦。Marco Arment 让这个在 Overcast 中工作,并且至少用这条推文为 Castro 的家伙留下了一条面包屑路径:

它是 MPRemoteCommandCenter。不过,祝文档好运。

这是为一直关注此问题的任何人提供的文档-我猜它与skipBackwardCommandand skipForwardCommand. 我现在没有时间研究它,所以我将把它留在这里,以防有人想戳它并给出更彻底的答案。

于 2014-07-17T00:32:51.557 回答
2

Apple 没有文档,因为无法更改。再一次,Apple 将最好的东西留给自己(Siri 也浮现在脑海中)。

越狱版支持更改控制中心按钮,我在这个网站上找到了。我有一种感觉,你想在实际的iOS 7 上使用这个应用程序,而不是越狱版本,所以这对你没有帮助。

这些私有 API 经常妨碍开发好的应用程序。除非 Apple 给予我们更多使用当前私有 API 的自由,否则您将不走运。

于 2014-03-09T23:49:02.970 回答
1

除了其他答案,我发现如果我没有在 MPNowPlayingInfoCenter 上设置 nowPlayingInfo,那么跳过按钮不会出现,但会出现默认的 nextTrack 和 PreviousTrack 按钮。(普通的快进和快退出现的按钮)请确保您正在设置 MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo,如下所示:

 var songInfo: NSMutableDictionary = [
        MPMediaItemPropertyTitle: "song title",
        MPMediaItemPropertyArtist: "artist ",
        MPNowPlayingInfoPropertyElapsedPlaybackTime: "0"
    ]
    MPNowPlayingInfoCenter.defaultCenter().nowPlayingInfo = songInfo as [NSObject : AnyObject]
于 2019-06-10T20:22:34.937 回答