【问题标题】:iOS audio controls not working with singletoniOS 音频控件不适用于单例
【发布时间】:2015-02-11 19:12:39
【问题描述】:

我正在尝试使用一个类来管理全局 AVAudioPlayer 实例,但我无法显示锁定屏幕控件。该类是 UIResponder 的子类,但无论我尝试什么,锁屏控件都不会出现。

客户端类使用- (void)setUrl:(NSURL *)url withTitle:(NSString *)title 加载音频并使用playAudio 播放。我在这里做错了什么?

我已将后台执行权限设置为音频和汽车播放,但即使在模拟器 > 重置内容和设置之后也失败了。

- (void)playAudio {
    [self.audioPlayer play];
    [self updateNowPlayingInfo];
}

- (void)stopAudio {
    [self.audioPlayer stop];
    [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:nil];
}

- (void)pauseAudio {
    [self.audioPlayer pause];
    [self updateNowPlayingInfo];
}

- (void)setupAudioSession {
    AVAudioSession *audioSession = [AVAudioSession sharedInstance];
    NSError *setCategoryError = nil;
    [audioSession setCategory:AVAudioSessionCategoryPlayback error:&setCategoryError];
    NSError *activationError = nil;
    [audioSession setActive:YES error:&activationError];
}

- (void)setupAudioControls {
    [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
    [self becomeFirstResponder];
    [self updateNowPlayingInfo];
}

- (BOOL)canBecomeFirstResponder {
    return YES;
}

- (void)remoteControlReceivedWithEvent:(UIEvent *)receivedEvent {
    if (receivedEvent.type == UIEventTypeRemoteControl) {
        switch (receivedEvent.subtype) {
            case UIEventSubtypeRemoteControlTogglePlayPause:
                NSLog(@"Play pause");
                if (self.audioPlayer.isPlaying) {
                    [self.audioPlayer pause];
                }
                else {
                    [self.audioPlayer play];
                }
                break;

            case UIEventSubtypeRemoteControlPreviousTrack:
                break;

            case UIEventSubtypeRemoteControlNextTrack:
                break;

            default:
                break;
        }

        [self updateNowPlayingInfo];
    }
}

- (void)updateNowPlayingInfo {
    NSMutableDictionary *albumInfo = [[NSMutableDictionary alloc] init];
    albumInfo[MPMediaItemPropertyTitle] = self.title;
    albumInfo[MPMediaItemPropertyArtist] = @"Fidelity";
    albumInfo[MPMediaItemPropertyAlbumTitle] = self.title;
    albumInfo[MPMediaItemPropertyPlaybackDuration] = @(self.audioPlayer.duration);
    albumInfo[MPNowPlayingInfoPropertyElapsedPlaybackTime] = @(self.audioPlayer.currentTime);
    [[MPNowPlayingInfoCenter defaultCenter] setNowPlayingInfo:albumInfo];
}

- (void)setUrl:(NSURL *)url withTitle:(NSString *)title {
    self.title = title;
    self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:url error:nil];
    [self setupAudioSession];
    [self setupAudioControls];
}

【问题讨论】:

  • 如果我不得不猜测,在你 setupAudioControls 之后还有别的 becomeFirstResponders。我觉得如果这个UIResponder 不是应用程序被发送到后台时的第一响应者,这将行不通。
  • 出于好奇,即使您不播放音频,您是否希望此代码正常工作?我的理解是,只有在您真正开始播放音频时才能拦截远程控制事件,但我不清楚这应该如何与锁定屏幕远程控制进行交互。
  • @Palpatim 你可能是对的。我假设如果音乐还没有开始,锁屏播放按钮可以开始音乐。那可能是错误的。

标签: ios objective-c avaudioplayer mpnowplayinginfocenter


【解决方案1】:

您的-(void)setupAudioControls 应该在进入后台后立即调用。在我的应用中:

...
  [[NSNotificationCenter defaultCenter] addObserver:self
                                           selector:@selector(appDidEnterBackground:)
                                               name:UIApplicationDidEnterBackgroundNotification
                                             object:nil];
...

- (void)appDidEnterBackground:(NSNotification *)notification {
  [[UIApplication sharedApplication] beginReceivingRemoteControlEvents];
  [self becomeFirstResponder];

  [self updateMediaInfo];
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-14
    • 1970-01-01
    • 1970-01-01
    • 2018-02-07
    相关资源
    最近更新 更多