HDCP alternativo con los SDK nativos

En este tema, obtendrá información sobre el uso de contenido protegido por HDCP con los SDK nativos de Brightcove para bloquear la transmisión en dispositivos no autorizados y proporcionar un respaldo de definición estándar para dispositivos que no admiten HDCP.

Introducción

La protección de contenido digital de alto ancho de banda (HDCP) es una forma de protección de copia digital que se utiliza para proteger las señales de audio y video de alta definición (HD) para que no se copien en dispositivos no autorizados. El dispositivo transmisor primero verifica si el receptor está autorizado para recibir datos. En caso afirmativo, el transmisor envía datos encriptados para evitar escuchas.

La configuración de recepción debe ser compatible con HDCP, incluidos los dispositivos, cables, adaptadores y controladores de software. Si el receptor no es compatible con HDCP, el video se reproducirá solo en definición estándar (SD). En general, los HDTV más nuevos y los cables HDMI o DVI deben ser compatibles con HDCP.

Para obtener más información, consulte el documento Fallback HDCP .

Requisitos

Se necesitan los siguientes requisitos para admitir esta función:

Versión de Brightcove SDK

  • SDK nativo para Android 6.17.1 y más reciente
  • SDK nativo para iOS 6.10.1 y más reciente

Implementación de Android

Cuando reproduzca un video con una combinación de representaciones SD y HD, querrá hacer lo siguiente:

  • En los dispositivos que admiten la reproducción tanto en HD como en SD, debe asegurarse de que el reproductor pueda cambiar a una reproducción adecuada cuando sea necesario, por ejemplo, cuando cambie el ancho de banda de la red. Este cambio de reproducción puede requerir que el jugador seleccione una reproducción SD, donde antes se reproducía HD.

  • En dispositivos sin compatibilidad con HDCP, por ejemplo, dispositivos móviles Android más antiguos con niveles de SO más antiguos, desea asegurarse de que el cambio de representación sea adecuado dentro de las representaciones SD, así como también asegurarse de que el reproductor no intente cargar una representación protegida con HDCP, momento en el cual el la solicitud de licencia fallará, con un mensaje de error como este:

    Mensaje de error< />

    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) 
    

Una solución a este problema consiste en agregar código para permitir el cambio de representación entre AdaptationSets en DASH y para filtrar las representaciones que no se espera que se reproduzcan en el dispositivo actual.

En el siguiente ejemplo, las representaciones HD están protegidas por requisitos HDCP más estrictos que el dispositivo actual no admite. Para lograr esto, puede utilizar un EventListener sobre el SET_SOURCE evento, ya que necesita agregar estos soportes antes de crear el ExoPlayer instancia.

Un ejemplo como este se agregaría a su reproductor Activity clase, en el onCreate método:

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

Implementación de iOS

Fallback HDCP es compatible con el SDK nativo para iOS/tvOS, pero solo se aplica para el contenido protegido mediante FairPlay.

Puede detectar la no conformidad del dispositivo, utilizando KVC para detectar cambios en el valor isOutputObscuredDueToInsufficientExternalProtection en el AVPlayer.

AVPlayer.isOutputObscuredDueToInsufficientExternalProtection == true

El valor de la propiedad anterior cambia a true por las siguientes razones:

  • El elemento actual requiere protección externa
  • El dispositivo no cumple con el nivel de protección.
  • El usuario observa pérdida de video

Dado que no todos los usuarios tienen una configuración compatible con HDCP, Apple recomienda incluir una variante (interpretación) en el archivo de manifiesto del video que no requiera protección HDCP. Brightcove se encarga de esto por usted cuando su cuenta está habilitada para Fallback HDCP.