【问题标题】:How to detect if an MPMediaItem represents a DRM-protected audio track on iOS如何检测 MPMediaItem 是否代表 iOS 上受 DRM 保护的音轨
【发布时间】:2011-07-31 01:44:51
【问题描述】:

我想知道表示音乐曲目的 MPMediaItem 是否适用于受 Fairplay/DRM 保护的项目。有什么办法吗?

【问题讨论】:

    标签: iphone drm mpmediaitem


    【解决方案1】:

    我是这样做的:

    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);
    }
    

    【讨论】:

    • 大家好,您能否建议我们如何使用 AVPlayer 播放这些受 DRM 保护的文件?
    • AVPlayer 无法播放旧的 DRM。您需要让用户使用 iTunes Plus 升级音频文件,以将曲目转换为打开 DRM,这就是现在所有歌曲的销售方式。
    • 我检查了我去年从 iTunes 购买的几首歌曲,它们表现出同样的问题 - MPMediaItemPropertyAssetURL 返回 (null)。这些文件在 iTunes 中显示为“购买的 AAC 音频文件”,扩展名为 .m4a。所以看起来这个问题仍然存在,或者自从上面的cmets之后又消失了又回来了......?
    • 对于您对 DRM 的评论,我还看到 MPMediaItemPropertyAssetURL 对于未完全从 iTunes/iCloud 下载的曲目返回 nil。通过在 Apple Music 应用程序中强制下载来修复它。
    • 这不是正确的检查方法,因为在 iOS 11 上,MPMediaItemPropertyAssetURL 至少对于通过 离线保存的歌曲而言 not nil Apple Music 但它们绝对受 DRM 保护 并且AVPlayer 也无法播放它们。请在下面查看我的答案以获取详细信息。
    【解决方案2】:

    从 iOS 4.2 开始就有了办法。可能有比这里的示例更有效的方法(但对于我的应用,我仍然需要创建 AVPlayerItems)。

    MPMediaItem item;
    NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
    AVPlayerItem *avItem = [[AVPlayerItem alloc] initWithURL:assetURL];
    BOOL fairplayed = avItem.asset.hasProtectedContent;
    

    【讨论】:

    • 由于 [item valueForProperty:MPMediaItemPropertyAssetURL] 为 DRM 返回 nil,您的 AVPlayerItem 将使用 nil 创建?
    • 可能。对于受保护的内容,返回的资产 url 总是 nil 是安全的假设吗?
    • 我没有检查assetURL是否为nil,并且使用iOS > 4.2(确切地说是4.3.4)的设备遇到了这个问题
    • 当前不可播放的不受保护的项目也将返回 nil。 iTunes Match 中最常见的项目不是设备本地的。
    • 这是正确的检查方法。此外,MPMediaItemPropertyAssetURLiOS 11not nil 至少对于通过 Apple Music 离线保存的歌曲但AVPlayer 无法播放它们因为它们受到DRM 保护。请在下面查看我的答案以获取有关此内容的详细信息。
    【解决方案3】:

    从 iOS 4.2 开始,AVAsset 类有一个属性 hasProtectedContent,因此您可以检查:

    NSURL *assetURL = [item valueForProperty:MPMediaItemPropertyAssetURL];
    AVAsset *asset = [AVAsset assetWithURL:assetURL];
    
    if ([asset hasProtectedContent] == NO) {..do your stuff..}
    

    【讨论】:

    • 请注意,这个 hasProtectedContent 调用比较慢;在 iphone 4S 上调用大约 100 首非 DRMed 歌曲大约需要 4 秒。
    • 当然,但这只是让它发挥作用的方法。在后台队列中添加该代码可以解决问题,您可以显示进度条,以便用户知道该操作将比其他操作持续更长时间。
    【解决方案4】:

    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 保护的资产的另一种正确方法是利用 MPMediaItemprotectedAsset 属性 - @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
    }
    

    【讨论】:

      【解决方案5】:

      iOS9.2+: 请使用 MPMediaItem "protectedAsset" 属性

      iOS9.2-: 判断 MPMediaItem"assetURL" 属性是否为 nil

      【讨论】:

      • 此属性仅适用于 iOS 9.2 及更高版本
      • @Mohit Singh 感谢您的评论,我添加了一些内容。
      【解决方案6】:

      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);
                  }
          });
          });
      }
      

      【讨论】:

        【解决方案7】:

        现在我正在为 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)播放。

        【讨论】:

          猜你喜欢
          • 2012-07-18
          • 2019-10-06
          • 2013-01-04
          • 2010-11-14
          • 2012-08-26
          • 2020-01-13
          • 1970-01-01
          • 2014-12-13
          • 2019-09-27
          相关资源
          最近更新 更多