使用加密密钥在exoplayer中播放加密的hls [英] Play encrypted hls in exoplayer using encrypted keys

查看:1098
本文介绍了使用加密密钥在exoplayer中播放加密的hls的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用.m3u8文件播放加密的视频.我将视频存储在AWS中,并创建了.ts文件和主播放列表. Aws为我提供了该加密视频文件的一些密钥.现在,我必须在exoplayer中使用这些键.我尝试使用Aes128DataSourceDrmSessionManager,但是没有运气.

I am trying to play the encrypted video using .m3u8 file. I stored my video in AWS and created the .ts files and a master playlist. Aws provided me some keys for that encrypted video file. Now I have to use those keys in exoplayer. I have tried to use Aes128DataSource and DrmSessionManager but no luck.

关键类型为:

Encryption Key: ####################################################################
Encryption Key MD5: ################
Encryption Initialization Vector : #############

使用下面的代码播放hls视频.它可以流畅地播放视频,没有任何问题.我只需要知道在哪里以及如何使用密钥来播放加密的视频即可.

Bellow the code I am using to play the hls video. Its plays the video smoothly without any problem. I just need to know where and how to use the keys to play the encrypted video.

            String VIDEO_URL = "https://s3.amazonaws.com/######.###.##/videos/mobiletest/mobilemaster.m3u8";

            //Create a default TrackSelector
            BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
            TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
            TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);

            // Create a default LoadControl
            LoadControl loadControl = new DefaultLoadControl();
            //Bis. Create a RenderFactory
            RenderersFactory renderersFactory = new DefaultRenderersFactory(this);


            //Create the player
            player = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector, loadControl);
            simpleExoPlayerView = new SimpleExoPlayerView(this);
            simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);


            //Set media controller
            simpleExoPlayerView.setUseController(true);
            simpleExoPlayerView.requestFocus();

            // Bind the player to the view.
            simpleExoPlayerView.setPlayer(player);

            // Set the media source
            Uri mp4VideoUri = Uri.parse(VIDEO_URL);

            //Measures bandwidth during playback. Can be null if not required.
            DefaultBandwidthMeter bandwidthMeterA = new DefaultBandwidthMeter();

            //Produces DataSource instances through which media data is loaded.
            DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "PiwikVideoApp"), bandwidthMeterA);

            //Produces Extractor instances for parsing the media data.
            ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

            //FOR LIVE STREAM LINK:
            MediaSource videoSource = new HlsMediaSource(mp4VideoUri, dataSourceFactory, 1, null, null);
            final MediaSource mediaSource = videoSource;


            player.prepare(videoSource);

我已经使用AWS Elastic Transcoder和exoplayer版本:2.6.0

I have encrypted the video using AWS Elastic Transcoder, and using exoplayer version: 2.6.0

推荐答案

我找到了一个解决方案.您需要做的技巧是创建自己的自定义数据源.您需要创建一个扩展HttpDataSource.BaseFactory的类,并从DefaultHttpDataSourceFactory添加一些代码.我知道这听起来很疯狂,但是我已经通过这种方式解决了.不用担心,我在这里粘贴了该自定义类的全部代码.

I have found a solution. The trick you need to do is to create your own custom data sources. You need to create a class that extends HttpDataSource.BaseFactory and add some code from DefaultHttpDataSourceFactory. I know it sounds crazy, but I have solved it this way. Don't worry, I am pasting here the whole code of that custom class.

import android.support.annotation.Nullable;

import com.google.android.exoplayer2.upstream.DefaultHttpDataSource;
import com.google.android.exoplayer2.upstream.HttpDataSource;
import com.google.android.exoplayer2.upstream.TransferListener;

public class CustomDataSourcesFactory extends HttpDataSource.BaseFactory{
    private final String userAgent;
    private final @Nullable
    TransferListener listener;
    private final int connectTimeoutMillis;
    private final int readTimeoutMillis;
    private final boolean allowCrossProtocolRedirects;

    /**
     * Constructs a DefaultHttpDataSourceFactory. Sets {@link
     * DefaultHttpDataSource#DEFAULT_CONNECT_TIMEOUT_MILLIS} as the connection timeout, {@link
     * DefaultHttpDataSource#DEFAULT_READ_TIMEOUT_MILLIS} as the read timeout and disables
     * cross-protocol redirects.
     *
     * @param userAgent The User-Agent string that should be used.
     */
    public CustomDataSourcesFactory(String userAgent) {
        this(userAgent, null);
    }

    /**
     * Constructs a DefaultHttpDataSourceFactory. Sets {@link
     * DefaultHttpDataSource#DEFAULT_CONNECT_TIMEOUT_MILLIS} as the connection timeout, {@link
     * DefaultHttpDataSource#DEFAULT_READ_TIMEOUT_MILLIS} as the read timeout and disables
     * cross-protocol redirects.
     *
     * @param userAgent The User-Agent string that should be used.
     * @param listener An optional listener.
     */
    public CustomDataSourcesFactory(String userAgent, @Nullable TransferListener listener) {
        this(userAgent, listener, DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
                DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, false);
    }

    /**
     * @param userAgent The User-Agent string that should be used.
     * @param connectTimeoutMillis The connection timeout that should be used when requesting remote
     *     data, in milliseconds. A timeout of zero is interpreted as an infinite timeout.
     * @param readTimeoutMillis The read timeout that should be used when requesting remote data, in
     *     milliseconds. A timeout of zero is interpreted as an infinite timeout.
     * @param allowCrossProtocolRedirects Whether cross-protocol redirects (i.e. redirects from HTTP
     *     to HTTPS and vice versa) are enabled.
     */
    public CustomDataSourcesFactory(
            String userAgent,
            int connectTimeoutMillis,
            int readTimeoutMillis,
            boolean allowCrossProtocolRedirects) {
        this(
                userAgent,
                /* listener= */ null,
                connectTimeoutMillis,
                readTimeoutMillis,
                allowCrossProtocolRedirects);
    }

    /**
     * @param userAgent The User-Agent string that should be used.
     * @param listener An optional listener.
     * @param connectTimeoutMillis The connection timeout that should be used when requesting remote
     *     data, in milliseconds. A timeout of zero is interpreted as an infinite timeout.
     * @param readTimeoutMillis The read timeout that should be used when requesting remote data, in
     *     milliseconds. A timeout of zero is interpreted as an infinite timeout.
     * @param allowCrossProtocolRedirects Whether cross-protocol redirects (i.e. redirects from HTTP
     *     to HTTPS and vice versa) are enabled.
     */
    public CustomDataSourcesFactory(
            String userAgent,
            @Nullable TransferListener listener,
            int connectTimeoutMillis,
            int readTimeoutMillis,
            boolean allowCrossProtocolRedirects) {
        this.userAgent = userAgent;
        this.listener = listener;
        this.connectTimeoutMillis = connectTimeoutMillis;
        this.readTimeoutMillis = readTimeoutMillis;
        this.allowCrossProtocolRedirects = allowCrossProtocolRedirects;
    }

    @Override
    protected HttpDataSource createDataSourceInternal(
            HttpDataSource.RequestProperties defaultRequestProperties) {
        DefaultHttpDataSource defaultHttpDataSource = new DefaultHttpDataSource(userAgent, null, listener, connectTimeoutMillis,
                readTimeoutMillis, allowCrossProtocolRedirects, defaultRequestProperties);
        defaultHttpDataSource.setRequestProperty("your header", "your token");
        return defaultHttpDataSource;
    }}

您看到方法createDataSourceInternal吗?我返回一个DefaultHttpDataSource对象,该对象用标头键和令牌defaultHttpDataSource.setRequestProperty("your header","your token");初始化.因此,现在,您的exoplayer将使用此标头密钥和令牌值来命中指控URL,您的服务器端将对其进行检查以验证有效请求.您的hls播放列表(.m3u8)包含指控网址. Exoplayer自动使用此URL.您需要做的就是告诉玩家使用验证码.

Do you see the method createDataSourceInternal? I am returning a DefaultHttpDataSource object initialised with a header key and a token defaultHttpDataSource.setRequestProperty("your header", "your token");. So now your exoplayer will hit the accusation URL with this header key and token value which will be checked by your server side in order to verify the valid request. Your hls playlist(.m3u8) contains the accusation URL. Exoplayer uses this URL automatically. All you need to do is to tell the player to use the validation keys.

这又是您的自定义数据源的用法代码:

So again here is the usage code of Your custom data sources:

//ExoPlayer implementation
    //Create a default TrackSelector
    BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
    TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
    TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);

    // Create a default LoadControl
    LoadControl loadControl = new DefaultLoadControl();
    //Bis. Create a RenderFactory
    RenderersFactory renderersFactory = new DefaultRenderersFactory(this);


    //Create the player
    player = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector, loadControl);
    simpleExoPlayerView = new SimpleExoPlayerView(this);
    simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);


    //Set media controller
    simpleExoPlayerView.setUseController(true);
    simpleExoPlayerView.requestFocus();

    // Bind the player to the view.
    simpleExoPlayerView.setPlayer(player);

    // Set the media source
    Uri mp4VideoUri = Uri.parse(VIDEO_URL);

    //DefaultHttpDataSource source = new DefaultHttpDataSource(Util.getUserAgent(this, "appAgent"), null);
    //source.setRequestProperty("header", "user token");

    //Measures bandwidth during playback. Can be null if not required.
    DefaultBandwidthMeter bandwidthMeterA = new DefaultBandwidthMeter();

    //DefaultDataSourceFactory o = new DefaultDataSourceFactory(this, null, new DefaultHttpDataSourceFactory(Util.getUserAgent(this, "appAgent"), bandwidthMeterA));
    CustomDataSourcesFactory o = new CustomDataSourcesFactory("Exoplayer");

    //Produces DataSource instances through which media data is loaded.
    DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(this, Util.getUserAgent(this, "PiwikVideoApp"), bandwidthMeterA);

    //Produces Extractor instances for parsing the media data.
    ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory();

    //FOR LIVE STREAM LINK:
    MediaSource videoSource = new HlsMediaSource(mp4VideoUri, o, 1, null, null);
    final MediaSource mediaSource = videoSource;


    player.prepare(videoSource);

这个问题对我来说太重要了,因为我找不到解决该问题的任何教程,资源或想法.我写这封信是因为我不希望其他像我这样的菜鸟人受此苦.

This problem was too much critical for me because I could not found any tutorial, resources or idea to solve this. I am writing this because I don't want other noob people like me to suffer from this.

如果您不清楚,请随时在此处提问.我会进一步协助您.我还具有服务器端代码,以便从AWS加密密钥生成解密密钥.

If you are not clear enough, feel free to ask here. I will assist you further. I have also the server side code in order to generate the decryption key from AWS encrypted key.

这篇关于使用加密密钥在exoplayer中播放加密的hls的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆