使用本機 SDK 回退 HDCP

在本主題中,您將了解如何將受 HDCP 保護的內容與 Brightcove Native SDK 結合使用來阻止在未經授權的設備上進行流式傳輸,並為不支持 HDCP 的設備提供標清回退。

簡介

高帶寬數字內容保護 (HDCP) 是一種數字複製保護形式,用於防止高清 (HD) 視頻和音頻信號在未經授權的設備上被複製。發送設備首先檢查接收器是否被授權接收數據。如果是,則發射器發送加密數據以防止竊聽。

接收設置必須符合 HDCP 標準,包括設備、電纜、適配器和軟件驅動程序。如果接收器不兼容 HDCP,則視頻將僅以標準清晰度 (SD) 播放。一般來說,較新的 HDTV 和 HDMI 或 DVI 電纜應該符合 HDCP 標準。

有關詳細信息,請參閱 回退 HDCP 文檔。

需求

支持此功能需要滿足以下要求:

Brightcove SDK版本

  • 適用於 Android 6.17.1 及更新版本的本機 SDK
  • 適用於 iOS 6.10.1 及更新版本的本機 SDK

安卓實作

播放混合了 SD 和 HD 格式的視頻時,您需要執行以下操作:

  • 在可以同時支持高清和標清播放的設備上,您希望確保播放器可以在需要時切換到適當的再現,例如當網絡帶寬發生變化時。此再現開關可能要求播放器選擇 SD 再現,而在播放 HD 之前。

  • 在不支持 HDCP 的設備上,例如具有較舊操作系統級別的較舊 Android 移動設備,您希望確保在 SD 再現中進行適當的再現切換,並確保播放器不會嘗試加載受 HDCP 保護的再現,此時許可證請求將失敗,並顯示如下錯誤消息:

    錯誤信息</>

    2021-11-01 19:01:36.943 30131-30131/com.brightcove.player.samples.exoplayer.basic E/VideoDisplayComponent: onPlayerError
      com.google.android.exoplayer2.ExoPlaybackException: MediaCodecVideoRenderer error, index=0, format=Format(bf310894-59b5-4f1b-9a37-e110a3d6121d, null, null, video/avc, avc1.4D401F, 1712000, null, [1280, 720, 30.0], [-1, -1]), format_supported=YES
          at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:555)
          at android.os.Handler.dispatchMessage(Handler.java:98)
          at android.os.Looper.loop(Looper.java:148)
          at android.os.HandlerThread.run(HandlerThread.java:61)
        Caused by: android.media.MediaCodec$CryptoException: Unknown Error
          at android.media.MediaCodec.native_queueSecureInputBuffer(Native Method)
          at android.media.MediaCodec.queueSecureInputBuffer(MediaCodec.java:2292)
          at com.google.android.exoplayer2.mediacodec.SynchronousMediaCodecAdapter.queueSecureInputBuffer(SynchronousMediaCodecAdapter.java:143)
          at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.feedInputBuffer(MediaCodecRenderer.java:1380)
          at com.google.android.exoplayer2.mediacodec.MediaCodecRenderer.render(MediaCodecRenderer.java:845)
          at com.google.android.exoplayer2.ExoPlayerImplInternal.doSomeWork(ExoPlayerImplInternal.java:945)
          at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:478)
          at android.os.Handler.dispatchMessage(Handler.java:98) 
          at android.os.Looper.loop(Looper.java:148) 
          at android.os.HandlerThread.run(HandlerThread.java:61) 
    

此問題的解決方案涉及添加代碼以允許跨版本切換AdaptationSets在 DASH 中,並過濾掉不希望在當前設備上播放的再現。

在以下示例中,高清再現受到當前設備不支持的更嚴格的 HDCP 要求的保護。為此,您可以使用EventListenerSET_SOURCE事件,因為您需要在創建之前添加這些支持ExoPlayer實例。

像這樣的示例將添加到您的播放器中Activity類,在onCreate方法:

eventEmitter.on(EventType.SET_SOURCE, event -> {
  try {
      // Get an instance of the MediaDrm from the device
      MediaDrm mediaDrm = new MediaDrm(Constants.WIDEVINE_UUID);

      // Create a new DefaultTrackSelector.ParamsBuilder object
      DefaultTrackSelector.ParametersBuilder builder = new DefaultTrackSelector.ParametersBuilder(this);

  // Call this method to enable rendition switching across DASH AdaptationSets
      builder.setAllowMultipleAdaptiveSelections(true);

      // Get the values for hdcpLevel and maxHdcpLevel
      String connectedHdcpLevel = mediaDrm.getPropertyString("hdcpLevel");
      String maxHdcpLevel = mediaDrm.getPropertyString("maxHdcpLevel");
      Log.v(TAG, "HDCP Level: " + connectedHdcpLevel + " Max HDCP Level: " + maxHdcpLevel);

      // If either level is null or an empty String or reads "Unprotected"
      if ((TextUtils.isEmpty(connectedHdcpLevel) || TextUtils.isEmpty(maxHdcpLevel)) ||
              ("Unprotected".equals(connectedHdcpLevel) || "Unprotected".equals(maxHdcpLevel))) {
          Log.v(TAG, "Restricting rendition selection to SD");

          // Set the max video size to SD
          builder.setMaxVideoSizeSd();
      }

  // Create a new DefaultTrackSelector object, and set the Parameters object created above
      DefaultTrackSelector defaultTrackSelector = new DefaultTrackSelector(this);
      defaultTrackSelector.setParameters(builder.build());
      // Set this DefaultTrackSelector object on the ExoPlayerVideoDisplayComponent
      videoDisplayComponent.setTrackSelector(defaultTrackSelector);
  }
  catch (Exception exception) {
      if (exception instanceof UnsupportedSchemeException) {
          Log.e(TAG, "UnsupportedSchemeException: " + exception.getLocalizedMessage());
      }
      else {
          Log.e(TAG, "An unexpected error occurred: " + exception.getLocalizedMessage());
      }
  }
});             
    

iOS 實作

iOS/tvOS 的 Native SDK 支持回退 HDCP,但僅對使用 FairPlay 保護的內容強制執行。

您可以通過使用檢測設備的不合規性KVC檢測值的變化isOutputObscuredDueToInsufficientExternalProtection在 AVPlayer 上。

AVPlayer.isOutputObscuredDueToInsufficientExternalProtection == true

上述屬性的值更改為true原因如下:

  • 當前項目需要外部保護
  • 設備不符合防護等級
  • 用戶觀察到視頻丟失

由於並非所有用戶都有 HDCP 兼容設置,Apple 建議在視頻清單中包含一個不需要 HDCP 保護的變體(再現)。當您的帳戶啟用回退 HDCP 時,Brightcove 會為您處理此問題。