Fallback HDCP avec les SDK natifs

Dans cette rubrique, vous apprendrez à utiliser le contenu protégé par le HDCP avec les SDK natifs de Brightcove pour bloquer la diffusion sur les périphériques non autorisés et fournir une définition standard de repli pour les périphériques qui ne prennent pas en charge le HDCP.

Introduction

La protection du contenu numérique à large bande passante (HDCP) est une forme de protection contre la copie numérique utilisée pour protéger les signaux vidéo et audio haute définition (HD) contre la copie sur des appareils non autorisés. Le dispositif d'émission vérifie d'abord si le récepteur est autorisé à recevoir des données. Dans l'affirmative, l'émetteur envoie des données cryptées pour éviter les écoutes clandestines.

La configuration de réception doit être conforme à la norme HDCP, y compris les appareils, les câbles, les adaptateurs et les pilotes de logiciels. Si le récepteur n'est pas compatible HDCP, la vidéo sera lue en définition standard (SD) uniquement. En général, les nouveaux téléviseurs HD et les câbles HDMI ou DVI doivent être conformes à la norme HDCP.

Pour plus de détails, consultez le HDCP de secours document.

Exigences

Les exigences suivantes sont nécessaires pour prendre en charge cette fonctionnalité :

Version du SDK Brightcove

  • SDK natif pour Android 6.17.1 et plus récent
  • SDK natif pour iOS 6.10.1 et plus récent

Implémentation Android

Lorsque vous visionnez une vidéo présentant à la fois des versions SD et HD, procédez comme suit :

  • Sur les appareils pouvant prendre en charge la lecture HD et SD, vous devez vous assurer que le lecteur peut basculer vers un rendu approprié en cas de besoin, par exemple lorsque la bande passante du réseau change. Ce changement de rendu peut obliger le lecteur à sélectionner un rendu SD, alors qu'il jouait auparavant en HD.

  • Sur les appareils ne prenant pas en charge le format HDCP, par exemple les anciens appareils mobiles Android dotés d'un système d'exploitation plus ancien, vous devez vous assurer que le changement de rendu est approprié entre les rendus SD et que le lecteur n'essaie pas de charger un rendu protégé par le HDCP, auquel cas la demande de licence échouera, avec un message d'erreur tel que celui-ci :

    Message d'erreur</>

    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) 
    

Une solution à ce problème consiste à ajouter du code pour permettre le changement de rendu AdaptationSets dans DASH et pour filtrer les rendus qui ne devraient pas être lus sur l'appareil actuel.

Dans l'exemple suivant, les rendus HD sont protégés par des exigences HDCP plus strictes que l'appareil actuel ne prend pas en charge. Pour ce faire, vous pouvez utiliser un événement EventListener sur l' SET_SOURCE événement, car vous devez ajouter ces supports avant de créer l' ExoPlayer instance.

Un exemple comme celui-ci serait ajouté à la Activity classe de votre joueur, dans la onCreate méthode :

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

Implémentation iOS

Le Fallback HDCP est pris en charge par le SDK natif pour iOS/tvOS, mais il n'est appliqué que pour les contenus protégés par FairPlay.

Vous pouvez détecter la non-conformité de l'appareil en utilisant KVC pour détecter les modifications de la valeur isOutputObscuredDueToInsufficientExternalProtection sur l'AVPlayer.

AVPlayer.isOutputObscuredDueToInsufficientExternalProtection == true

La valeur de la propriété ci-dessus passe à true pour les raisons suivantes :

  • Le poste actuel nécessite une protection externe
  • L'appareil n'est pas conforme au niveau de protection
  • L'utilisateur observe une perte de vidéo

Étant donné que tous les utilisateurs ne disposent pas d'une installation compatible HDCP, Apple recommande d'inclure une variante (rendu) dans le manifeste vidéo qui ne nécessite pas de protection HDCP. Brightcove s'en charge lorsque votre compte est activé pour le Fallback HDCP.