xref: /aosp_15_r20/external/exoplayer/tree_8e57d3715f9092d5ec54ebe2e538f34bfcc34479/docs/drm.md (revision 30877f796caf59d855b10b687a5d6b3918d765cb)
1*30877f79SAndroid Build Coastguard Worker---
2*30877f79SAndroid Build Coastguard Workertitle: Digital rights management
3*30877f79SAndroid Build Coastguard Worker---
4*30877f79SAndroid Build Coastguard Worker
5*30877f79SAndroid Build Coastguard WorkerExoPlayer uses Android's [`MediaDrm`][] API to support DRM protected playbacks.
6*30877f79SAndroid Build Coastguard WorkerThe minimum Android versions required for different supported DRM schemes, along
7*30877f79SAndroid Build Coastguard Workerwith the streaming formats for which they're supported, are:
8*30877f79SAndroid Build Coastguard Worker
9*30877f79SAndroid Build Coastguard Worker| DRM scheme | Android version number | Android API level | Supported formats |
10*30877f79SAndroid Build Coastguard Worker|---------|:------------:|:------------:|:---------------------|
11*30877f79SAndroid Build Coastguard Worker| Widevine "cenc" | 4.4 | 19 | DASH, HLS (FMP4 only) |
12*30877f79SAndroid Build Coastguard Worker| Widevine "cbcs" | 7.1 | 25 | DASH, HLS (FMP4 only) |
13*30877f79SAndroid Build Coastguard Worker| ClearKey "cenc" | 5.0 | 21 | DASH |
14*30877f79SAndroid Build Coastguard Worker| PlayReady SL2000 "cenc" | AndroidTV | AndroidTV | DASH, SmoothStreaming, HLS (FMP4 only) |
15*30877f79SAndroid Build Coastguard Worker
16*30877f79SAndroid Build Coastguard WorkerIn order to play DRM protected content with ExoPlayer, the UUID of the DRM
17*30877f79SAndroid Build Coastguard Workersystem and the license server URI should be specified
18*30877f79SAndroid Build Coastguard Worker[when building a media item]({{ site.baseurl }}/media-items.html#protected-content).
19*30877f79SAndroid Build Coastguard WorkerThe player will then use these properties to build a default implementation of
20*30877f79SAndroid Build Coastguard Worker`DrmSessionManager`, called `DefaultDrmSessionManager`, that's suitable for most
21*30877f79SAndroid Build Coastguard Workeruse cases. For some use cases additional DRM properties may be necessary, as
22*30877f79SAndroid Build Coastguard Workeroutlined in the sections below.
23*30877f79SAndroid Build Coastguard Worker
24*30877f79SAndroid Build Coastguard Worker### Key rotation ###
25*30877f79SAndroid Build Coastguard Worker
26*30877f79SAndroid Build Coastguard WorkerTo play streams with rotating keys, pass `true` to
27*30877f79SAndroid Build Coastguard Worker`MediaItem.DrmConfiguration.Builder.setMultiSession` when building the media
28*30877f79SAndroid Build Coastguard Workeritem.
29*30877f79SAndroid Build Coastguard Worker
30*30877f79SAndroid Build Coastguard Worker### Multi-key content ###
31*30877f79SAndroid Build Coastguard Worker
32*30877f79SAndroid Build Coastguard WorkerMulti-key content consists of multiple streams, where some streams use different
33*30877f79SAndroid Build Coastguard Workerkeys than others. Multi-key content can be played in one of two ways, depending
34*30877f79SAndroid Build Coastguard Workeron how the license server is configured.
35*30877f79SAndroid Build Coastguard Worker
36*30877f79SAndroid Build Coastguard Worker##### Case 1: License server responds with all keys for the content #####
37*30877f79SAndroid Build Coastguard Worker
38*30877f79SAndroid Build Coastguard WorkerIn this case, the license server is configured so that when it receives a
39*30877f79SAndroid Build Coastguard Workerrequest for one key, it responds with all keys for the content. This case is
40*30877f79SAndroid Build Coastguard Workerhandled by ExoPlayer without the need for any special configuration. Adaptation
41*30877f79SAndroid Build Coastguard Workerbetween streams (e.g. SD and HD video) is seamless even if they use different
42*30877f79SAndroid Build Coastguard Workerkeys.
43*30877f79SAndroid Build Coastguard Worker
44*30877f79SAndroid Build Coastguard WorkerWhere possible, we recommend configuring your license server to behave in this
45*30877f79SAndroid Build Coastguard Workerway. It's the most efficient and robust way to support playback of multikey
46*30877f79SAndroid Build Coastguard Workercontent, because it doesn't require the client to make multiple license requests
47*30877f79SAndroid Build Coastguard Workerto access the different streams.
48*30877f79SAndroid Build Coastguard Worker
49*30877f79SAndroid Build Coastguard Worker##### Case 2: License server responds with requested key only #####
50*30877f79SAndroid Build Coastguard Worker
51*30877f79SAndroid Build Coastguard WorkerIn this case, the license server is configured to respond with only the key
52*30877f79SAndroid Build Coastguard Workerspecified in the request. Multi-key content can be played with this license
53*30877f79SAndroid Build Coastguard Workerserver configuration by passing `true` to
54*30877f79SAndroid Build Coastguard Worker`MediaItem.DrmConfiguration.Builder.setMultiSession` when building the media
55*30877f79SAndroid Build Coastguard Workeritem.
56*30877f79SAndroid Build Coastguard Worker
57*30877f79SAndroid Build Coastguard WorkerWe do not recommend configuring your license server to behave in this way. It
58*30877f79SAndroid Build Coastguard Workerrequires extra license requests to play multi-key content, which is less
59*30877f79SAndroid Build Coastguard Workerefficient and robust than the alternative described above.
60*30877f79SAndroid Build Coastguard Worker
61*30877f79SAndroid Build Coastguard Worker### Offline keys ###
62*30877f79SAndroid Build Coastguard Worker
63*30877f79SAndroid Build Coastguard WorkerAn offline key set can be loaded by passing the key set ID to
64*30877f79SAndroid Build Coastguard Worker`MediaItem.DrmConfiguration.Builder.setKeySetId` when building the media item.
65*30877f79SAndroid Build Coastguard WorkerThis allows playback using the keys stored in the offline key set with the
66*30877f79SAndroid Build Coastguard Workerspecified ID.
67*30877f79SAndroid Build Coastguard Worker
68*30877f79SAndroid Build Coastguard Worker{% include known-issue-box.html issue-id="3872" description="Only one offline
69*30877f79SAndroid Build Coastguard Workerkey set can be specified per playback. As a result, offline playback of
70*30877f79SAndroid Build Coastguard Workermulti-key content is currently supported only when the license server is
71*30877f79SAndroid Build Coastguard Workerconfigured as described in Case 1 above." %}
72*30877f79SAndroid Build Coastguard Worker
73*30877f79SAndroid Build Coastguard Worker### DRM sessions for clear content ###
74*30877f79SAndroid Build Coastguard Worker
75*30877f79SAndroid Build Coastguard WorkerUse of placeholder `DrmSessions` allows `ExoPlayer` to use the same decoders for
76*30877f79SAndroid Build Coastguard Workerclear content as are used when playing encrypted content. When media contains
77*30877f79SAndroid Build Coastguard Workerboth clear and encrypted sections, you may want to use placeholder `DrmSessions`
78*30877f79SAndroid Build Coastguard Workerto avoid re-creation of decoders when transitions between clear and encrypted
79*30877f79SAndroid Build Coastguard Workersections occur. Use of placeholder `DrmSessions` for audio and video tracks can
80*30877f79SAndroid Build Coastguard Workerbe enabled by passing `true` to
81*30877f79SAndroid Build Coastguard Worker`MediaItem.DrmConfiguration.Builder.forceSessionsForAudioAndVideoTracks` when
82*30877f79SAndroid Build Coastguard Workerbuilding the media item.
83*30877f79SAndroid Build Coastguard Worker
84*30877f79SAndroid Build Coastguard Worker### Using a custom DrmSessionManager ###
85*30877f79SAndroid Build Coastguard Worker
86*30877f79SAndroid Build Coastguard WorkerIf an app wants to customise the `DrmSessionManager` used for playback, they can
87*30877f79SAndroid Build Coastguard Workerimplement a `DrmSessionManagerProvider` and pass this to the
88*30877f79SAndroid Build Coastguard Worker`MediaSource.Factory` which is [used when building the player]. The provider can
89*30877f79SAndroid Build Coastguard Workerchoose whether to instantiate a new manager instance each time or not. To always
90*30877f79SAndroid Build Coastguard Workeruse the same instance:
91*30877f79SAndroid Build Coastguard Worker
92*30877f79SAndroid Build Coastguard Worker~~~
93*30877f79SAndroid Build Coastguard WorkerDrmSessionManager customDrmSessionManager =
94*30877f79SAndroid Build Coastguard Worker    new CustomDrmSessionManager(/* ... */);
95*30877f79SAndroid Build Coastguard Worker// Pass a drm session manager provider to the media source factory.
96*30877f79SAndroid Build Coastguard WorkerMediaSource.Factory mediaSourceFactory =
97*30877f79SAndroid Build Coastguard Worker    new DefaultMediaSourceFactory(dataSourceFactory)
98*30877f79SAndroid Build Coastguard Worker        .setDrmSessionManagerProvider(mediaItem -> customDrmSessionManager);
99*30877f79SAndroid Build Coastguard Worker~~~
100*30877f79SAndroid Build Coastguard Worker{: .language-java}
101*30877f79SAndroid Build Coastguard Worker
102*30877f79SAndroid Build Coastguard Worker### Improving playback performance ###
103*30877f79SAndroid Build Coastguard Worker
104*30877f79SAndroid Build Coastguard WorkerIf you're experiencing video stuttering on a device running Android 6 to 11 when
105*30877f79SAndroid Build Coastguard Workerplaying DRM protected content, you can try [enabling asynchronous buffer
106*30877f79SAndroid Build Coastguard Workerqueueing].
107*30877f79SAndroid Build Coastguard Worker
108*30877f79SAndroid Build Coastguard Worker[main demo app]: {{ site.release_v2 }}/demos/main
109*30877f79SAndroid Build Coastguard Worker[`MediaDrm`]: {{ site.android_sdk }}/android/media/MediaDrm.html
110*30877f79SAndroid Build Coastguard Worker[used when building the player]: {{ site.baseurl }}/media-sources.html#customizing-media-source-creation
111*30877f79SAndroid Build Coastguard Worker[enabling asynchronous buffer queueing]: {{ site.baseurl }}/customization.html#enabling-asynchronous-buffer-queueing
112