iOS 将通过 AVPlayer 播放的音频添加到 OS 默认播放器?

iOS add audio playing via AVPlayer to OS default player?

所以想法是 - 当我们在 iPhone 的音乐应用程序中播放音频并按下主页按钮然后从屏幕底部滑动时,我们可以看到音频在默认 OS 播放器中播放play/pause 控件和音频继续播放。

现在我需要做的是,我在我的应用程序中使用 AVAudioPlayer 播放音频,如果用户按下主页按钮,音频需要像音乐应用程序一样继续播放。 但我不知道如何在 OS 默认播放器中添加音频?任何帮助或建议将不胜感激。

编辑: 我需要使用流播放音频所以我想我需要使用 AVPlayer 而不是 AVAudioPlayer

您可以使用 MPMovieplayerController,因为您很可能会使用 M3U8 播放列表。

这是文档http://developer.apple.com/library/ios/documentation/MediaPlayer/Reference/mpmovieplayercontroller_class/index.html

但基本上是这样的:

初始化 MPMoviePlayerController,分配文件类型(流),放入源 url,并将其呈现在视图堆栈中。

对于背景音频,您必须像此答案中那样使用 AudioSession iOS MPMoviePlayerController playing audio in background

您可以将此作为后台音频任务来执行,这样即使在用户按下主页按钮并且您的应用程序进入后台后音频仍会继续播放。首先你创建一个 AVAudioSession。然后在 viewDidLoad 方法中设置一个 AVPlayerObjects 数组和一个 AVQueuePlayer。 Ray Wenderlich 的一篇很棒的教程详细讨论了所有这些 http://www.raywenderlich.com/29948/backgrounding-for-ios。您可以设置一个回调方法(观察者方法),以便应用在流入 - (void)observeValueForKeyPath 时发送额外的音频数据。

代码如下(来自 Ray Wenderlich 的教程):

在 viewDidLoad 中:

// Set AVAudioSession
NSError *sessionError = nil;
[[AVAudioSession sharedInstance] setDelegate:self];
[[AVAudioSession sharedInstance]     setCategory:AVAudioSessionCategoryPlayAndRecord error:&sessionError];

// Change the default output audio route
UInt32 doChangeDefaultRoute = 1;
AudioSessionSetProperty(kAudioSessionProperty_OverrideCategoryDefaultToSpeaker,
  sizeof(doChangeDefaultRoute), &doChangeDefaultRoute);

NSArray *queue = @[
[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle]  URLForResource:@"IronBacon" withExtension:@"mp3"]],
[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"FeelinGood" withExtension:@"mp3"]],
[AVPlayerItem playerItemWithURL:[[NSBundle mainBundle] URLForResource:@"WhatYouWant" withExtension:@"mp3"]]];

self.player = [[AVQueuePlayer alloc] initWithItems:queue];
self.player.actionAtItemEnd = AVPlayerActionAtItemEndAdvance;

[self.player addObserver:self
              forKeyPath:@"currentItem"
                 options:NSKeyValueObservingOptionNew
                 context:nil];

在回调方法中:

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"currentItem"])
    {
        AVPlayerItem *item = ((AVPlayer *)object).currentItem;
        self.lblMusicName.text = ((AVURLAsset*)item.asset).URL.pathComponents.lastObject;
        NSLog(@"New music name: %@", self.lblMusicName.text);
    }
}

不要忘记在实现文件中添加视图控制器私有API中的成员变量:

@interface TBFirstViewController ()

@property (nonatomic, strong) AVQueuePlayer *player;
@property (nonatomic, strong) id timeObserver; 
@end