AVPlayer 不在后台转发流媒体轨道

Posted

技术标签:

【中文标题】AVPlayer 不在后台转发流媒体轨道【英文标题】:AVPlayer not forwarding streaming track in background 【发布时间】:2012-02-22 21:15:36 【问题描述】:

我遇到了一个问题,AVPlayer 没有在后台播放

详情如下:

我有一个 AVPlayer 对象和一个 AVPlayerItem 作为我的视图控制器的实例变量,用于从存储在 NSMutableArray 中的链接中流式传输音乐,linkArray。当用户在 UITableView 中点击一个轨道时,两个对象都被实例化,如下所示:

musicPlayerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:[linkArray objectAtIndex:indexPath.row]]];
player = [[AVPlayer alloc] initWithPlayerItem:musicPlayerItem];

...而且播放完美。每当应用程序活动时曲目完成时,它都会很好地跳过,或者当我手动触发应用程序跳过曲目时(无论它是活动的还是后台的)。但是,当应用处于后台时(包括设备锁定时),它不会在跳过时播放下一首曲目。

因此,它会自行跳到下一首曲目,但不播放。我要么必须再次激活应用程序,要么调用播放(通过耳机控件或系统范围的音乐控件)。

这里是 skipTrack 方法的代码,在手动调用时或在歌曲到达曲目结尾时由系统调用:

        if (nowPlaying == [linkArray count]-1) 
            nowPlaying = 0;
            musicPlayerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:[linkArray objectAtIndex:0]]];
            player = [[AVPlayer alloc] initWithPlayerItem:musicPlayerItem];
         else 
            NSLog(@"NowPlaying (before increment: %i", nowPlaying);
            //If not, increment nowPlaying by one and play
            nowPlaying++;
            NSLog(@"NowPlaying (after increment: %i", nowPlaying);
            musicPlayerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:[linkArray objectAtIndex:nowPlaying]]];
            player = [[AVPlayer alloc] initWithPlayerItem:musicPlayerItem];
     

真的希望有人可以帮助我

【问题讨论】:

【参考方案1】:

所以问题在于,因为您已启用应用在后台播放音频,所以它会在播放音乐时保持活动状态。一旦音乐停止,它将被暂停。所以你需要歌曲一停止就在后台请求时间执行任务(大多数播放器都有一个歌曲播放完毕的回调函数,把这段代码放在开头)。所以你的代码看起来像这样......

UIBackgroundTaskIdentifier newTaskID = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^
    // Clean up any unfinished task business by marking where you.
    // stopped or ending the task outright.
    [application endBackgroundTask:newTaskID];
    newTaskID = UIBackgroundTaskInvalid;
];];

if (nowPlaying == [linkArray count]-1) 
        nowPlaying = 0;
        musicPlayerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:[linkArray objectAtIndex:0]]];
        player = [[AVPlayer alloc] initWithPlayerItem:musicPlayerItem];
     else 
        NSLog(@"NowPlaying (before increment: %i", nowPlaying);
        //If not, increment nowPlaying by one and play
        nowPlaying++;
        NSLog(@"NowPlaying (after increment: %i", nowPlaying);
        musicPlayerItem = [[AVPlayerItem alloc] initWithURL:[NSURL URLWithString:[linkArray objectAtIndex:nowPlaying]]];
        player = [[AVPlayer alloc] initWithPlayerItem:musicPlayerItem];
 

[[UIApplication sharedApplication] endBackgroundTask:newTaskID];
newTaskID = UIBackgroundTaskInvalid;'

“beginBackgroundTaskWithExpirationHandler:”方法将给你一些时间在后台做事。如果您的时间用完,则执行发送到该方法的代码块。您需要包含该内容,以防出现问题并且您需要清理任务。在开发库中阅读有关它的更多信息:here

【讨论】:

感谢您的回复。 n00b 问题但是,newTaskID 是什么数据类型?我阅读了您附上的 ios 编程指南,它的描述有点令人困惑。谢谢 糟糕,我应该包括它,它是一个 UIBackgroundTaskIdentifier。所以只需将其声明为“UIBackgroundTaskIdentifier newTaskID” 好的,完成了。我在视图控制器的 applicationDidEnterBackground: 方法中调用它?再次感谢。 不,我相信您可以将其包含在正常的“播放完成”或曲目跳过方法中。无需为它制作特殊情况。 搞定了!我删除了中间部分(实际上是在其中进行曲目跳过)并将其添加到我的 AppDelegate.m 中的 applicationDidEnterBackground 方法中。 非常非常感谢您的帮助! :D

以上是关于AVPlayer 不在后台转发流媒体轨道的主要内容,如果未能解决你的问题,请参考以下文章

iOS swift流媒体应用程序不在后台模式下播放音乐

ios avplayer 触发流媒体缓冲区不足

如何创建一个简单的AVPlayer流媒体应用程序? [关闭]

AVPlayer 视频播放

分块解密媒体文件并通过 AVPlayer 播放

iOS 媒体播放控件通知