Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
SDK
/
exoplayer
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit
33143919
authored
May 23, 2019
by
aquilescanta
Committed by
Toni
May 30, 2019
Browse files
Options
_('Browse Files')
Download
Email Patches
Plain Diff
Add basic DRM support to CastPlayer's demo app
PiperOrigin-RevId: 249624829
parent
8d329fb4
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
108 additions
and
34 deletions
RELEASENOTES.md
demos/cast/src/main/java/com/google/android/exoplayer2/castdemo/DefaultReceiverPlayerManager.java
demos/cast/src/main/java/com/google/android/exoplayer2/castdemo/DemoUtil.java
demos/cast/src/main/java/com/google/android/exoplayer2/castdemo/MainActivity.java
extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/DefaultCastOptionsProvider.java
RELEASENOTES.md
View file @
33143919
...
...
@@ -2,6 +2,7 @@
### dev-v2 (not yet released) ###
*
Add basic DRM support to the Cast demo app.
*
Add
`ResolvingDataSource`
for just-in-time resolution of
`DataSpec`
s
(
[
#5779
](
https://github.com/google/ExoPlayer/issues/5779
)
).
*
Assume that encrypted content requires secure decoders in renderer support
...
...
demos/cast/src/main/java/com/google/android/exoplayer2/castdemo/DefaultReceiverPlayerManager.java
View file @
33143919
...
...
@@ -44,11 +44,14 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import
com.google.android.exoplayer2.ui.PlayerControlView
;
import
com.google.android.exoplayer2.ui.PlayerView
;
import
com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory
;
import
com.google.android.exoplayer2.util.Assertions
;
import
com.google.android.gms.cast.MediaInfo
;
import
com.google.android.gms.cast.MediaMetadata
;
import
com.google.android.gms.cast.MediaQueueItem
;
import
com.google.android.gms.cast.framework.CastContext
;
import
java.util.ArrayList
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
/** Manages players and an internal media queue for the ExoPlayer/Cast demo app. */
/* package */
class
DefaultReceiverPlayerManager
...
...
@@ -394,12 +397,47 @@ import java.util.ArrayList;
private
static
MediaQueueItem
buildMediaQueueItem
(
MediaItem
item
)
{
MediaMetadata
movieMetadata
=
new
MediaMetadata
(
MediaMetadata
.
MEDIA_TYPE_MOVIE
);
movieMetadata
.
putString
(
MediaMetadata
.
KEY_TITLE
,
item
.
title
);
MediaInfo
mediaInfo
=
MediaInfo
.
Builder
mediaInfoBuilder
=
new
MediaInfo
.
Builder
(
item
.
media
.
uri
.
toString
())
.
setStreamType
(
MediaInfo
.
STREAM_TYPE_BUFFERED
)
.
setContentType
(
item
.
mimeType
)
.
setMetadata
(
movieMetadata
)
.
build
();
return
new
MediaQueueItem
.
Builder
(
mediaInfo
).
build
();
.
setMetadata
(
movieMetadata
);
if
(!
item
.
drmSchemes
.
isEmpty
())
{
MediaItem
.
DrmScheme
scheme
=
item
.
drmSchemes
.
get
(
0
);
try
{
// This configuration is only intended for testing and should *not* be used in production
// environments. See comment in the Cast Demo app's options provider.
JSONObject
drmConfiguration
=
getDrmConfigurationJson
(
scheme
);
if
(
drmConfiguration
!=
null
)
{
mediaInfoBuilder
.
setCustomData
(
drmConfiguration
);
}
}
catch
(
JSONException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
return
new
MediaQueueItem
.
Builder
(
mediaInfoBuilder
.
build
()).
build
();
}
@Nullable
private
static
JSONObject
getDrmConfigurationJson
(
MediaItem
.
DrmScheme
scheme
)
throws
JSONException
{
String
drmScheme
;
if
(
C
.
WIDEVINE_UUID
.
equals
(
scheme
.
uuid
))
{
drmScheme
=
"widevine"
;
}
else
if
(
C
.
PLAYREADY_UUID
.
equals
(
scheme
.
uuid
))
{
drmScheme
=
"playready"
;
}
else
{
return
null
;
}
MediaItem
.
UriBundle
licenseServer
=
Assertions
.
checkNotNull
(
scheme
.
licenseServer
);
JSONObject
exoplayerConfig
=
new
JSONObject
().
put
(
"withCredentials"
,
false
).
put
(
"protectionSystem"
,
drmScheme
);
if
(!
licenseServer
.
uri
.
equals
(
Uri
.
EMPTY
))
{
exoplayerConfig
.
put
(
"licenseUrl"
,
licenseServer
.
uri
.
toString
());
}
if
(!
licenseServer
.
requestHeaders
.
isEmpty
())
{
exoplayerConfig
.
put
(
"headers"
,
new
JSONObject
(
licenseServer
.
requestHeaders
));
}
return
new
JSONObject
().
put
(
"exoPlayerConfig"
,
exoplayerConfig
);
}
}
demos/cast/src/main/java/com/google/android/exoplayer2/castdemo/DemoUtil.java
View file @
33143919
...
...
@@ -15,13 +15,13 @@
*/
package
com
.
google
.
android
.
exoplayer2
.
castdemo
;
import
android.net.Uri
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.UUID
;
/** Utility methods and constants for the Cast demo application. */
...
...
@@ -30,44 +30,25 @@ import java.util.UUID;
/** Represents a media sample. */
public
static
final
class
Sample
{
/** The
uri
of the media content. */
/** The
URI
of the media content. */
public
final
String
uri
;
/** The name of the sample. */
public
final
String
name
;
/** The mime type of the sample media content. */
public
final
String
mimeType
;
/**
* The {@link UUID} of the DRM scheme that protects the content, or null if the content is not
* DRM-protected.
*/
@Nullable
public
final
UUID
drmSchemeUuid
;
/**
* The url from which players should obtain DRM licenses, or null if the content is not
* DRM-protected.
*/
@Nullable
public
final
Uri
licenseServerUri
;
/** Data to configure DRM license acquisition. May be null if content is not DRM-protected. */
@Nullable
public
final
DrmConfiguration
drmConfiguration
;
/**
* @param uri See {@link #uri}.
* @param name See {@link #name}.
* @param mimeType See {@link #mimeType}.
*/
public
Sample
(
String
uri
,
String
name
,
String
mimeType
)
{
this
(
uri
,
name
,
mimeType
,
/* drm
SchemeUuid= */
null
,
/* licenseServerUriString
= */
null
);
this
(
uri
,
name
,
mimeType
,
/* drm
Configuration
= */
null
);
}
public
Sample
(
String
uri
,
String
name
,
String
mimeType
,
@Nullable
UUID
drmSchemeUuid
,
@Nullable
String
licenseServerUriString
)
{
String
uri
,
String
name
,
String
mimeType
,
@Nullable
DrmConfiguration
drmConfiguration
)
{
this
.
uri
=
uri
;
this
.
name
=
name
;
this
.
mimeType
=
mimeType
;
this
.
drmSchemeUuid
=
drmSchemeUuid
;
this
.
licenseServerUri
=
licenseServerUriString
!=
null
?
Uri
.
parse
(
licenseServerUriString
)
:
null
;
this
.
drmConfiguration
=
drmConfiguration
;
}
@Override
...
...
@@ -76,6 +57,29 @@ import java.util.UUID;
}
}
/** Holds information required to play DRM-protected content. */
public
static
final
class
DrmConfiguration
{
/** The {@link UUID} of the DRM scheme that protects the content. */
public
final
UUID
drmSchemeUuid
;
/**
* The URI from which players should obtain DRM licenses. May be null if the license server URI
* is provided as part of the media.
*/
@Nullable
public
final
String
licenseServerUri
;
/** HTTP request headers to include the in DRM license requests. */
public
final
Map
<
String
,
String
>
httpRequestHeaders
;
public
DrmConfiguration
(
UUID
drmSchemeUuid
,
@Nullable
String
licenseServerUri
,
Map
<
String
,
String
>
httpRequestHeaders
)
{
this
.
drmSchemeUuid
=
drmSchemeUuid
;
this
.
licenseServerUri
=
licenseServerUri
;
this
.
httpRequestHeaders
=
httpRequestHeaders
;
}
}
public
static
final
String
MIME_TYPE_DASH
=
MimeTypes
.
APPLICATION_MPD
;
public
static
final
String
MIME_TYPE_HLS
=
MimeTypes
.
APPLICATION_M3U8
;
public
static
final
String
MIME_TYPE_SS
=
MimeTypes
.
APPLICATION_SS
;
...
...
demos/cast/src/main/java/com/google/android/exoplayer2/castdemo/MainActivity.java
View file @
33143919
...
...
@@ -16,6 +16,7 @@
package
com
.
google
.
android
.
exoplayer2
.
castdemo
;
import
android.content.Context
;
import
android.net.Uri
;
import
android.os.Bundle
;
import
androidx.core.graphics.ColorUtils
;
import
androidx.appcompat.app.AlertDialog
;
...
...
@@ -36,6 +37,7 @@ import android.widget.TextView;
import
android.widget.Toast
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.SimpleExoPlayer
;
import
com.google.android.exoplayer2.ext.cast.DefaultCastOptionsProvider
;
import
com.google.android.exoplayer2.ext.cast.MediaItem
;
import
com.google.android.exoplayer2.ui.PlayerControlView
;
import
com.google.android.exoplayer2.ui.PlayerView
;
...
...
@@ -121,6 +123,7 @@ public class MainActivity extends AppCompatActivity
String
applicationId
=
castContext
.
getCastOptions
().
getReceiverApplicationId
();
switch
(
applicationId
)
{
case
CastMediaControlIntent
.
DEFAULT_MEDIA_RECEIVER_APPLICATION_ID
:
case
DefaultCastOptionsProvider
.
APP_ID_DEFAULT_RECEIVER_WITH_DRM
:
playerManager
=
new
DefaultReceiverPlayerManager
(
/* listener= */
this
,
...
...
@@ -202,11 +205,17 @@ public class MainActivity extends AppCompatActivity
.
setMedia
(
sample
.
uri
)
.
setTitle
(
sample
.
name
)
.
setMimeType
(
sample
.
mimeType
);
if
(
sample
.
drmSchemeUuid
!=
null
)
{
DemoUtil
.
DrmConfiguration
drmConfiguration
=
sample
.
drmConfiguration
;
if
(
drmConfiguration
!=
null
)
{
mediaItemBuilder
.
setDrmSchemes
(
Collections
.
singletonList
(
new
MediaItem
.
DrmScheme
(
sample
.
drmSchemeUuid
,
new
MediaItem
.
UriBundle
(
sample
.
licenseServerUri
))));
drmConfiguration
.
drmSchemeUuid
,
new
MediaItem
.
UriBundle
(
drmConfiguration
.
licenseServerUri
!=
null
?
Uri
.
parse
(
drmConfiguration
.
licenseServerUri
)
:
Uri
.
EMPTY
,
drmConfiguration
.
httpRequestHeaders
))));
}
playerManager
.
addItem
(
mediaItemBuilder
.
build
());
mediaQueueListAdapter
.
notifyItemInserted
(
playerManager
.
getMediaQueueSize
()
-
1
);
...
...
extensions/cast/src/main/java/com/google/android/exoplayer2/ext/cast/DefaultCastOptionsProvider.java
View file @
33143919
...
...
@@ -27,11 +27,33 @@ import java.util.List;
*/
public
final
class
DefaultCastOptionsProvider
implements
OptionsProvider
{
/**
* App id of the Default Media Receiver app. Apps that do not require DRM support may use this
* receiver receiver app ID.
*
* <p>See https://developers.google.com/cast/docs/caf_receiver/#default_media_receiver.
*/
public
static
final
String
APP_ID_DEFAULT_RECEIVER
=
CastMediaControlIntent
.
DEFAULT_MEDIA_RECEIVER_APPLICATION_ID
;
/**
* App id for receiver app with rudimentary support for DRM.
*
* <p>This app id is only suitable for ExoPlayer's Cast Demo app, and it is not intended for
* production use. In order to use DRM, custom receiver apps should be used. For environments that
* do not require DRM, the default receiver app should be used (see {@link
* #APP_ID_DEFAULT_RECEIVER}).
*/
// TODO: Add a documentation resource link for DRM support in the receiver app [Internal ref:
// b/128603245].
public
static
final
String
APP_ID_DEFAULT_RECEIVER_WITH_DRM
=
"A12D4273"
;
@Override
public
CastOptions
getCastOptions
(
Context
context
)
{
return
new
CastOptions
.
Builder
()
.
setReceiverApplicationId
(
CastMediaControlIntent
.
DEFAULT_MEDIA_RECEIVER_APPLICATION_ID
)
.
setStopReceiverApplicationWhenEndingSession
(
true
).
build
();
.
setReceiverApplicationId
(
APP_ID_DEFAULT_RECEIVER_WITH_DRM
)
.
setStopReceiverApplicationWhenEndingSession
(
true
)
.
build
();
}
@Override
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment