Integração com o ExoPlayer

Este documento apresenta uma visão geral do suporte à integração de DRM e enfileiramento.

Melhorias de DRM

A demonstração de transmissão do ExoPlayer foi atualizada para utilizar uma maneira estruturada de transmitir a configuração de DRM usando o MediaInfo do ExoPlayer para um app receptor. O exemplo do Cast também usa um receptor de demonstração que inclui o mesmo código nesta visão geral, permitindo que você teste o suporte ao DRM. No entanto, se você quiser transmitir conteúdo protegido por DRM, crie e hospede seu próprio Receptor da Web.

Antes de começar, conheça a documentação sobre suporte a DRM no Google Cast e no ExoPlayer. Esta visão geral mostrará como conectar a configuração de DRM do ExoPlayer a um receptor da Web. Para saber mais sobre como utilizar o DRM no ExoPlayer, consulte o site oficial do ExoPlayer (em inglês).

Fornecer a configuração de DRM

O app de demonstração do ExoPlayer contém um exemplo de código que mostra como fornecer a configuração de DRM como parte de um MediaItem. As quatro opções que podem ser configuradas são:

  • Headers: um dicionário de cabeçalhos aplicados à solicitação HTTPS para recuperar a licença de DRM.
  • URL da licença: é o URL usado para adquirir a licença.
  • Protection System: o esquema de proteção DRM usado para proteger o conteúdo, por exemplo, Widevine.

A configuração de DRM fornecida ao ExoPlayer é enviada ao aplicativo receptor como uma propriedade em customData no objeto MediaInformation como parte de uma solicitação de carregamento. Por padrão, essa propriedade é chamada exoPlayerConfig, que corresponde à definição a seguir.

/**
 * Extended configuration settings for ExoPlayer.
 */
ExoPlayerConfig class {
   constructor() {
    /**
     * Dictionary of headers to apply to the license request.
     * @type {!Object|undefined}
     */
    this.headers;

    /**
     * The URL for your DRM server.
     * @type {string|undefined}
     */
    this.licenseUrl;

    /**
     * Preferred protection system to use for decrypting content.
     * @type {!cast.framework.ContentProtection|undefined}
     */
    this.protectionSystem;

    /**
     * Indicates whether CORS Access-Control requests should be made using
     * credentials such as cookies or authorization headers.
     *
     * If withCredentials is set to true then Access-Control-Allow-Origin cannot
     * be set to '*'.
     * @type {boolean|undefined}
     */
    this.withCredentials;
  }
}

Configuração inicial

Dependendo da solução de DRM que você usa, pode ser necessário configurar uma licenseRequestHandler e uma mediaPlaybackInfoHandler. O licenseRequestHandler permite personalizar como o CAF solicita uma licença do servidor de chaves de licença. O mediaPlaybackInfoHandler permite modificar o PlaybackConfig por item de mídia se, por exemplo, cada conteúdo precisar usar um URL do servidor de licença diferente.

Para capturar uma cópia do ExoPlayerConfig de cada objeto de solicitação de carregamento, crie um interceptador de solicitações de carregamento no aplicativo do SDK do receptor da Web.

A primeira etapa é registrar os gerenciadores antes de iniciar o aplicativo Google Cast.

const context = cast.framework.CastReceiverContext.getInstance();
const playbackConfig = new cast.framework.PlaybackConfig();

playbackConfig.licenseRequestHandler =
    licenseRequestHandler;
context.getPlayerManager().setMediaPlaybackInfoHandler(
    mediaPlaybackInfoHandler);
context.getPlayerManager().setMessageInterceptor(
    cast.framework.messages.MessageType.LOAD,
    loadInterceptor);

// starts the Cast application
context.start({playbackConfig: playbackConfig});

Interceptador de solicitação de carga

O interceptador de solicitação de carregamento é um callback que permite visualizar e modificar uma solicitação de carga de transmissão antes que o CAF tente carregar um item de mídia. É importante ressaltar que ele é chamado antes do gerenciador da solicitação de licença e do gerenciador de informações de reprodução de mídia.

O interceptador de solicitação de carregamento recebe um objeto LoadRequestData que contém a configuração do Exo Player que foi enviada pelo app. É possível salvar esse objeto como uma variável global para uso no gerenciador de solicitações de licença e no gerenciador de informações de reprodução de mídia.

loadInterceptor(loadRequestData) {
    // not every load request will have a customData object
    if (loadRequestData.media && loadRequestData.media.customData &&
            loadRequestData.media.customData['exoPlayerConfig']) {
        // exoPlayerConfig is a global variable here
        exoPlayerConfig =
                loadRequestData.media.customData['exoPlayerConfig'];
    }

    // you must return the loadRequestData object
    return loadRequestData;
}

Gerenciador de solicitações de licença

O gerenciador de solicitações de licença permite personalizar a solicitação HTTPS que o Web Receiver faz para seu servidor de licença. O gerenciador recebe um objeto NetworkRequestInfo, que pode ser usado para adicionar cabeçalhos HTTP, incluir cookies ou até mesmo modificar o URL. O manipulador deve retornar esse objeto.

Se, por exemplo, você precisar adicionar cabeçalhos personalizados à sua solicitação de licença, crie um gerenciador de solicitações de licença semelhante a este:

licenseRequestHandler(networkRequestInfo) {
    if (!exoPlayerConfig) {
        return networkRequestInfo;
    }

    networkRequestInfo.headers =
            exoPlayerConfig.headers ? exoPlayerConfig.headers : undefined;

    return networkRequestInfo;
}

Gerenciador de informações de reprodução de mídia

O gerenciador de informações de reprodução de mídia permite mudar a configuração de reprodução para cada item de mídia. O gerenciador recebe um LoadRequestData e um PlaybackConfig. Você precisa retornar uma configuração de reprodução. O gerenciador de informações de reprodução de mídia será chamado antes de cada item transmitido ser carregado. Se você tinha URLs de licença por conteúdo, é possível alterá-los e o sistema de proteção antes do carregamento.

mediaPlaybackInfoHandler(loadRequest, playbackConfig) {
    if (!exoPlayerConfig) {
        return;
    }

    playbackConfig.licenseUrl = exoPlayerConfig.licenseUrl ?
            exoPlayerConfig.licenseUrl :
            undefined;
    playbackConfig.protectionSystem = exoPlayerConfig.protectionSystem ?
            exoPlayerConfig.protectionSystem :
            undefined;

    return playbackConfig;
}

Outros recursos

Cada implementação de DRM é personalizada, e esse código é fornecido apenas como demonstração. Consulte seu provedor de DRM para verificar se ele foi implementado corretamente nos apps ExoPlayer e Cast.

O site do ExoPlayer apresenta documentação e anúncios atualizados. Os problemas com o ExoPlayer e a integração do Google Cast podem ser informados no repositório GitHub do ExoPlayer (em inglês).