【发布时间】:2011-07-31 01:44:51
【问题描述】:
我想知道表示音乐曲目的 MPMediaItem 是否适用于受 Fairplay/DRM 保护的项目。有什么办法吗?
【问题讨论】:
标签: iphone drm mpmediaitem
我想知道表示音乐曲目的 MPMediaItem 是否适用于受 Fairplay/DRM 保护的项目。有什么办法吗?
【问题讨论】:
标签: iphone drm mpmediaitem
我是这样做的:
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);
}
【讨论】:
MPMediaItemPropertyAssetURL 至少对于通过 离线保存的歌曲而言 not nil Apple Music 但它们绝对受 DRM 保护 并且AVPlayer 也无法播放它们。请在下面查看我的答案以获取详细信息。
从 iOS 4.2 开始就有了办法。可能有比这里的示例更有效的方法(但对于我的应用,我仍然需要创建 AVPlayerItems)。
MPMediaItem item;
NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
AVPlayerItem *avItem = [[AVPlayerItem alloc] initWithURL:assetURL];
BOOL fairplayed = avItem.asset.hasProtectedContent;
【讨论】:
MPMediaItemPropertyAssetURL 在 iOS 11 上not nil 至少对于通过 Apple Music 离线保存的歌曲但AVPlayer 无法播放它们因为它们受到DRM 保护。请在下面查看我的答案以获取有关此内容的详细信息。
从 iOS 4.2 开始,AVAsset 类有一个属性 hasProtectedContent,因此您可以检查:
NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
AVAsset *asset = [AVAsset assetWithURL:assetURL];
if ([asset hasProtectedContent] == NO) {..do your stuff..}
【讨论】:
MPMediaItemPropertyAssetURL 在运行 iOS 11 的 iPhone X 上not nil 用于通过Apple Music离线保存的歌曲但AVPlayer 无法播放它们,因为它们受 DRM 保护。同一首歌曲在 iOS 9 上返回 MPMediaItemPropertyAssetURLnil。
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 保护的资产的另一种正确方法是利用 MPMediaItem 的 protectedAsset 属性 - @weirdyu 的回答。但是,此属性仅适用于 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)播放。
【讨论】: