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.