当设备被蓝牙耳机锁定时,AVAsset 无法播放

Posted

技术标签:

【中文标题】当设备被蓝牙耳机锁定时,AVAsset 无法播放【英文标题】:AVAsset not playable when device locked with Bluetooth headset 【发布时间】:2014-05-05 12:44:10 【问题描述】:

我有一个适用于 ios6 及更高版本的音乐播放器应用程序。我的音乐播放器运行良好,它可以在线(流媒体)和离线(本地 mp3 文件)播放音乐。

当我将蓝牙耳机连接到我的设备(iPad 或 iPhone)时,问题出现了,如果设备已解锁,它工作正常,但当设备锁定时,音乐会继续播放,直到歌曲结束,然后当它尝试播放下一首歌曲时歌曲没有播放。 经过一些调试后,我意识到问题出在本地文件上,而且文件似乎不是“可播放”的,但这确实是因为设备解锁后它可以正常工作。

我的代码:

    NSURL *URL = [[NSURL alloc] initFileURLWithPath:path];
    AVAsset *asset = [AVURLAsset URLAssetWithURL:URL options:nil];
    if(asset.isPlayable) 
        AVPlayerItem *anItem = [AVPlayerItem playerItemWithAsset:asset];
        _player = [AVPlayer playerWithPlayerItem:anItem];
        if(![self isPlaying]) 
            [self play];
        
    

“if(asset.isPlayable) ”中的代码永远不会执行。

更新:

我已使用@MDB983 建议更改了我的代码,但它仍然不起作用。

        NSURL *URL = [[NSURL alloc] initFileURLWithPath:path];
        AVPlayerItem *anItem = [AVPlayerItem playerItemWithURL:URL];
        if(_player == nil) 
            _player = [AVPlayer playerWithPlayerItem:anItem];
         else 
            [_player replaceCurrentItemWithPlayerItem:anItem];
        
        if(![self isPlaying]) 
            [self play];
        

有什么想法吗?

【问题讨论】:

【参考方案1】:

您是否正在设置“MPNowPlayingInfoCenter 的 nowPlayingInfo”?

我在通过 AVPlayer 播放流媒体文件时发现了同样的问题。文件完成后,在显示锁定屏幕时永远不会播放下一个文件。解决方案是填充 MPNowPlayingInfoCenter 的 nowPlayingInfo;在播放新曲目之前尝试添加类似这样的设置;

   UIImage *artworkImage = [UIImage imageWithName:@"artworkImage.jpg"];
   MPMediaItemArtwork *artwork = [[MPMediaItemArtwork alloc]initWithImage:artworkImage];
   [MPNowPlayingInfoCenter defaultCenter].nowPlayingInfo = [NSDictionary dictionaryWithObjectsAndKeys:@"My Song Title", MPMediaItemPropertyTitle,
                                                            @"Artist Name", MPMediaItemPropertyArtist,
                                                            artwork, MPMediaItemPropertyArtwork, 
                                                            1.0f, MPNowPlayingInfoPropertyPlaybackRate, nil];

我遇到的另一个问题,AVPlayer 必须在显示锁定屏幕之前实例化,因此您应该修改您的方法并将 AVPlayer 创建为属性并在每首歌曲更改时设置一个新的 AVPlayerItem,如下所示;

     AVPlayerItem *anItem = [AVPlayerItem playerItemWithAsset:asset];
     [self.player replaceCurrentItemWithPlayerItem:anItem];

【讨论】:

非常感谢您的回答,但我的问题是在创建 AVPlayerItem 之前。当我创建 AVAsset 并检查它是否可播放时,它说它不是。是的,我正在使用 MPNowPlayingInfoCenter。 为什么要创建 AVAsset?只需创建带有 URL 的 AVPlayerItem 没必要,反正它不适用:AVPlayerItem *anItem = [AVPlayerItem playerItemWithURL:URL]; 这是一个有效的 API,而且我已经广泛使用,所以你一定在某个地方遇到了问题,你遇到了什么错误?如果你的意思是歌曲结束后它仍然停止,你是在替换 AVPlayerItem 而不是创建一个新的 AVPlayer? 不幸的是我没有收到任何错误,所以我不知道为什么没有复制下一首曲目。我已将代码更改为使用“replaceCurrentItemWithPlayerItem”,但它仍然不起作用。【参考方案2】:

我终于解决了我的问题。

重点不在于 AVPlayer,而在于文件存储。在本地存储我的文件之前,我加密了文件,然后为了播放它我解密它。

问题是我保存的文件是这样的:

BOOL success = [encryptedResult writeToFile:path options:NSDataWritingFileProtectionComplete error:&error];

所以当设备被锁定时我无法正确读取文件,正如Apple's documentation 中所说的那样。

我到处都改成:

BOOL success = [encryptedResult writeToFile:path options:NSDataWritingFileProtectionNone error:&error];

它就像一个魅力。

【讨论】:

以上是关于当设备被蓝牙耳机锁定时,AVAsset 无法播放的主要内容,如果未能解决你的问题,请参考以下文章

当设备已经在 Beacon 范围内时无法检测到 Beacon 然后我们打开蓝牙 & 应用程序被杀死

当应用程序处于后台或设备锁定时,Airplay 停止播放视频流

设备自动锁定时,AVPlayer 无法在 iPad 上运行

当活动方向被锁定时检测设备方向

在设备锁定时播放 iPod 库中的音频

苹果MacBook Air怎样连接iPhone手机用蓝牙音响播放音乐?