exoplayer 纯java,使用ExoPlayer 播放drm

google exoplayer 关于drm的使用,官方说明在这个地址:

(https://exoplayer.dev/drm.html)

关键概念:

DrmSessionManager

要播放Drm 受保护的内容,必须要在实例化播放器的时候,注入DrmSessionManager.

Exoplayer library 提供了默认的实现DefaultDrmSessionManager, 如何使用,可以参考Exoplayer main demo 里面的PlayerActivity.java, 该DefaultDrmSessionManager 适用于绝大部分情形。

Key rotation

个人理解为播放多个码流的时候对应的多个key, 需要作key 切换。这个时候实例化DefaultDrmSessionManager时需要将multiSession这个构造参数设置为true.

在发生key切换的时候有些bug如:

a.会发生轻微停顿的情况

b. api <=22时,画面会闪烁

Multi-key content

多key内容,它是由多种流组成, 其中某些流跟其他流的key是不同的。这种内容可以以2中方式播放,取决于licence server 如何配置:

a. License server 被配置为一次request 响应所有的key. 这是一种最高效的方式,推荐使用这种,exoplayer不需要特殊配置,不需要多次请求

b. License server 被配置为只响应request 中指定的key. multiSession需要被设置为true,如上面实例化DefaultDrmSessionManager所述。该方式不被推荐。

Offline keys

离线key集合, 可以在DefaultDrmSessionManager 在被实例化时传入offlineLicenseKeySetId参数时被加载。一个播放只能指定一个key集合,所以,多key内容的离线key集合,仅仅在上述情况一(License server 被配置为一次request 响应所有的key)的时候被支持。

关键使用:

MediaSource 的创建,media 内容url地址, 扩展参数, 根据这些得到type后,创建不同种类的source.

private MediaSource buildMediaSource(Uri uri, @Nullable String overrideExtension) {

DownloadRequest downloadRequest =

((DemoApplication) getApplication()).getDownloadTracker().getDownloadRequest(uri);

if (downloadRequest != null) {

return DownloadHelper.createMediaSource(downloadRequest, dataSourceFactory);

}

@ContentType int type = Util.inferContentType(uri, overrideExtension);

switch (type) {

case C.TYPE_DASH:

return new DashMediaSource.Factory(dataSourceFactory).createMediaSource(uri);

case C.TYPE_SS:

return new SsMediaSource.Factory(dataSourceFactory).createMediaSource(uri);

case C.TYPE_HLS:

return new HlsMediaSource.Factory(dataSourceFactory).createMediaSource(uri);

case C.TYPE_OTHER:

return new ProgressiveMediaSource.Factory(dataSourceFactory).createMediaSource(uri);

default:

throw new IllegalStateException("Unsupported type: " + type);

}

}

DrmSessionManager 的创建,注意需要准备的参数:uuid, licenseUrl, keyRequestPropertiesArray, multiSession:

private DefaultDrmSessionManager buildDrmSessionManagerV18(

UUID uuid, String licenseUrl, String[] keyRequestPropertiesArray, boolean multiSession)

throws UnsupportedDrmException {

HttpDataSource.Factory licenseDataSourceFactory =

((DemoApplication) getApplication()).buildHttpDataSourceFactory();

HttpMediaDrmCallback drmCallback =

new HttpMediaDrmCallback(licenseUrl, licenseDataSourceFactory);

if (keyRequestPropertiesArray != null) {

for (int i = 0; i < keyRequestPropertiesArray.length - 1; i += 2) {

drmCallback.setKeyRequestProperty(keyRequestPropertiesArray[i],

keyRequestPropertiesArray[i + 1]);

}

}

releaseMediaDrm();

mediaDrm = FrameworkMediaDrm.newInstance(uuid);

return new DefaultDrmSessionManager<>(uuid, mediaDrm, drmCallback, null, multiSession);

}

cookie 设置, 详细见PlayerActivity.java:

private static final CookieManager DEFAULT_COOKIE_MANAGER;

static {

DEFAULT_COOKIE_MANAGER = new CookieManager();

DEFAULT_COOKIE_MANAGER.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);

}

......

......

if (CookieHandler.getDefault() != DEFAULT_COOKIE_MANAGER) {

CookieHandler.setDefault(DEFAULT_COOKIE_MANAGER);

}

......

UUID 的获取:

UUID drmSchemeUuid = Util.getDrmUuid(intent.getStringExtra(drmSchemeExtra));

userAgent:

...

userAgent = Util.getUserAgent(this, "ExoPlayerDemo");

...

public HttpDataSource.Factory buildHttpDataSourceFactory() {

return new DefaultHttpDataSourceFactory(userAgent);

}

...

DrmSessionManager 事件监听

DefaultDrmSessionManager localDefaultDrmSessionManager = new DefaultDrmSessionManager(paramUUID,

FrameworkMediaDrm.newInstance(paramUUID),

localHttpMediaDrmCallback,

null,

mHandler,

new DefaultDrmSessionManager.EventListener() {

public void onDrmKeysLoaded()

{

}

public void onDrmKeysRemoved()

{

}

public void onDrmKeysRestored()

{

}

public void onDrmSessionManagerError(Exception paramException)

{

}

}

);

关键方法

setPlayClearSamplesWithoutKeys

public DefaultRenderersFactory setPlayClearSamplesWithoutKeys(boolean playClearSamplesWithoutKeys)

Sets whether renderers are permitted to play clear regions of encrypted media

prior to having obtained the keys necessary to decrypt encrypted regions of the media.For encrypted media that starts with a short clear region,this allows playback to begin in parallel with key acquisition, which can reduce startup latency.

The default value is false.

一般加密流的形式:clear data + secure data. 该方法可以提升起播速度

设置加密surface, setSecure

if (isDrm())

surfaceView.setSecure(true);

如果觉得有用,请记得点赞哟!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值