当设备被蓝牙耳机锁定时,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 然后我们打开蓝牙 & 应用程序被杀死