我想知道代表音乐曲目的 MPMediaItem 是否适用于受 Fairplay/DRM 保护的项目。有什么办法可以做到这一点?
7 回答
这是我的做法:
MPMediaItem* item;
NSURL* assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
NSString *title=[item valueForProperty:MPMediaItemPropertyTitle];
if (!assetURL) {
/*
* !!!: When MPMediaItemPropertyAssetURL is nil, it typically means the file
* in question is protected by DRM. (old m4p files)
*/
NSLog(@"%@ has DRM",title);
}
从 iOS 4.2 开始就有了办法。可能有比这里的示例更有效的方法(但对于我的应用程序,我仍然需要创建 AVPlayerItems)。
MPMediaItem item;
NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
AVPlayerItem *avItem = [[AVPlayerItem alloc] initWithURL:assetURL];
BOOL fairplayed = avItem.asset.hasProtectedContent;
从 iOS 4.2开始,AVAsset
该类具有一个属性hasProtectedContent
,因此您可以检查:
NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
AVAsset *asset = [AVAsset assetWithURL:assetURL];
if ([asset hasProtectedContent] == NO) {..do your stuff..}
MPMediaItemPropertyAssetURL
对于通过Apple Music离线保存的歌曲,在运行iOS 11的 iPhone X上不是 nil ,但由于受DRM保护而无法播放。同一首歌曲在iOS 9上返回nil。AVPlayer
MPMediaItemPropertyAssetURL
MPMediaItemPropertyAssetURL
对于通过Apple Music添加到库但不能离线使用的歌曲返回nil - 在iOS 9 和 11上。
因此,@voidStern 的答案(而不是 Justin Kent 的)是测试受 DRM 保护的资产的正确方法。
Swift 4版本的 voidStern 答案(在iOS 9 到 11上非常适合我):
let itemUrl = targetMPMediaItem?.value(forProperty: MPMediaItemPropertyAssetURL) as? URL
if itemUrl != nil {
let theAsset = AVAsset(url: itemUrl!)
if theAsset.hasProtectedContent {
//Asset is protected
//Must be played only via MPPlayer
} else {
//Asset is not protected
//Can be played both via AVPlayer & MPPlayer\
}
} else {
//probably the asset is not avilable offline
//Must be played only via MPPlayer
}
检查受 DRM 保护的资产的另一种正确方法是利用protectedAsset
@weirdyuMPMediaItem
的回答。但是,此属性仅适用于iOS 9.2及更高版本。
此方法的Swift 4解决方案(在iOS 9.2及更高版本上非常适合我):
if #available(iOS 9.2, *) {
if (targetMPMediaItem?.hasProtectedAsset)! {
//asset is protected
//Must be played only via MPMusicPlayer
} else {
//asset is not protected
//Can be played both via AVPlayer & MPMusicPlayer
}
} else {
//Fallback on earlier versions
//Probably use the method explained earlier
}
iOS9.2+:请使用 MPMediaItem "protectedAsset" 属性
iOS9.2-:判断MPMediaItem"assetURL"属性是否为nil
Justin Kents 的解决方案效果很好。我建议使用块,否则如果你处理一堆歌曲,用户体验会受到影响:
-(void)checkDRMprotectionForItem:(MPMediaItem*)item OnCompletion:(void (^)(BOOL drmProtected))completionBlock
{
dispatch_async(_drmCheckQueue, ^{
BOOL drmStatus;
NSURL* assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
if (!assetURL) {
drmStatus = YES;
}
dispatch_async(dispatch_get_main_queue(), ^{
if (completionBlock) {
completionBlock(drmStatus);
}
});
});
}
现在我正在为 ios 9 构建 swift 2,我发现我的代码使用 hasProtectedContent 或使用 nil url 测试被破坏。我发现以下代码有效:
let playerItem = AVPlayerItem(URL: mpMediaItem.assetURL!)
playableByAVPlayer = (playerItem.status == .ReadyToPlay) ? true : false
如果 AV Player 无法播放该项目,则它是 DRM 项目,应由 iPod Player(现在称为 SystemMusicPlayer)播放。