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[main demo app]: {{ site.release_v2 }}/demos/main 103*30877f79SAndroid Build Coastguard Worker[`MediaDrm`]: {{ site.android_sdk }}/android/media/MediaDrm.html 104*30877f79SAndroid Build Coastguard Worker[used when building the player]: {{ site.baseurl }}/media-sources.html#customizing-media-source-creation 105