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
Show 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 @@
...
@@ -2,6 +2,7 @@
### dev-v2 (not yet released) ###
### dev-v2 (not yet released) ###
*
Add basic DRM support to the Cast demo app.
*
Add
`ResolvingDataSource`
for just-in-time resolution of
`DataSpec`
s
*
Add
`ResolvingDataSource`
for just-in-time resolution of
`DataSpec`
s
(
[
#5779
](
https://github.com/google/ExoPlayer/issues/5779
)
).
(
[
#5779
](
https://github.com/google/ExoPlayer/issues/5779
)
).
*
Assume that encrypted content requires secure decoders in renderer support
*
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;
...
@@ -44,11 +44,14 @@ import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
import
com.google.android.exoplayer2.ui.PlayerControlView
;
import
com.google.android.exoplayer2.ui.PlayerControlView
;
import
com.google.android.exoplayer2.ui.PlayerView
;
import
com.google.android.exoplayer2.ui.PlayerView
;
import
com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory
;
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.MediaInfo
;
import
com.google.android.gms.cast.MediaMetadata
;
import
com.google.android.gms.cast.MediaMetadata
;
import
com.google.android.gms.cast.MediaQueueItem
;
import
com.google.android.gms.cast.MediaQueueItem
;
import
com.google.android.gms.cast.framework.CastContext
;
import
com.google.android.gms.cast.framework.CastContext
;
import
java.util.ArrayList
;
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. */
/** Manages players and an internal media queue for the ExoPlayer/Cast demo app. */
/* package */
class
DefaultReceiverPlayerManager
/* package */
class
DefaultReceiverPlayerManager
...
@@ -394,12 +397,47 @@ import java.util.ArrayList;
...
@@ -394,12 +397,47 @@ import java.util.ArrayList;
private
static
MediaQueueItem
buildMediaQueueItem
(
MediaItem
item
)
{
private
static
MediaQueueItem
buildMediaQueueItem
(
MediaItem
item
)
{
MediaMetadata
movieMetadata
=
new
MediaMetadata
(
MediaMetadata
.
MEDIA_TYPE_MOVIE
);
MediaMetadata
movieMetadata
=
new
MediaMetadata
(
MediaMetadata
.
MEDIA_TYPE_MOVIE
);
movieMetadata
.
putString
(
MediaMetadata
.
KEY_TITLE
,
item
.
title
);
movieMetadata
.
putString
(
MediaMetadata
.
KEY_TITLE
,
item
.
title
);
MediaInfo
mediaInfo
=
MediaInfo
.
Builder
mediaInfoBuilder
=
new
MediaInfo
.
Builder
(
item
.
media
.
uri
.
toString
())
new
MediaInfo
.
Builder
(
item
.
media
.
uri
.
toString
())
.
setStreamType
(
MediaInfo
.
STREAM_TYPE_BUFFERED
)
.
setStreamType
(
MediaInfo
.
STREAM_TYPE_BUFFERED
)
.
setContentType
(
item
.
mimeType
)
.
setContentType
(
item
.
mimeType
)
.
setMetadata
(
movieMetadata
)
.
setMetadata
(
movieMetadata
);
.
build
();
if
(!
item
.
drmSchemes
.
isEmpty
())
{
return
new
MediaQueueItem
.
Builder
(
mediaInfo
).
build
();
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 @@
...
@@ -15,13 +15,13 @@
*/
*/
package
com
.
google
.
android
.
exoplayer2
.
castdemo
;
package
com
.
google
.
android
.
exoplayer2
.
castdemo
;
import
android.net.Uri
;
import
androidx.annotation.Nullable
;
import
androidx.annotation.Nullable
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
com.google.android.exoplayer2.util.MimeTypes
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.UUID
;
import
java.util.UUID
;
/** Utility methods and constants for the Cast demo application. */
/** Utility methods and constants for the Cast demo application. */
...
@@ -30,44 +30,25 @@ import java.util.UUID;
...
@@ -30,44 +30,25 @@ import java.util.UUID;
/** Represents a media sample. */
/** Represents a media sample. */
public
static
final
class
Sample
{
public
static
final
class
Sample
{
/** The
uri
of the media content. */
/** The
URI
of the media content. */
public
final
String
uri
;
public
final
String
uri
;
/** The name of the sample. */
/** The name of the sample. */
public
final
String
name
;
public
final
String
name
;
/** The mime type of the sample media content. */
/** The mime type of the sample media content. */
public
final
String
mimeType
;
public
final
String
mimeType
;
/**
/** Data to configure DRM license acquisition. May be null if content is not DRM-protected. */
* The {@link UUID} of the DRM scheme that protects the content, or null if the content is not
@Nullable
public
final
DrmConfiguration
drmConfiguration
;
* 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
;
/**
* @param uri See {@link #uri}.
* @param name See {@link #name}.
* @param mimeType See {@link #mimeType}.
*/
public
Sample
(
String
uri
,
String
name
,
String
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
(
public
Sample
(
String
uri
,
String
uri
,
String
name
,
String
mimeType
,
@Nullable
DrmConfiguration
drmConfiguration
)
{
String
name
,
String
mimeType
,
@Nullable
UUID
drmSchemeUuid
,
@Nullable
String
licenseServerUriString
)
{
this
.
uri
=
uri
;
this
.
uri
=
uri
;
this
.
name
=
name
;
this
.
name
=
name
;
this
.
mimeType
=
mimeType
;
this
.
mimeType
=
mimeType
;
this
.
drmSchemeUuid
=
drmSchemeUuid
;
this
.
drmConfiguration
=
drmConfiguration
;
this
.
licenseServerUri
=
licenseServerUriString
!=
null
?
Uri
.
parse
(
licenseServerUriString
)
:
null
;
}
}
@Override
@Override
...
@@ -76,6 +57,29 @@ import java.util.UUID;
...
@@ -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_DASH
=
MimeTypes
.
APPLICATION_MPD
;
public
static
final
String
MIME_TYPE_HLS
=
MimeTypes
.
APPLICATION_M3U8
;
public
static
final
String
MIME_TYPE_HLS
=
MimeTypes
.
APPLICATION_M3U8
;
public
static
final
String
MIME_TYPE_SS
=
MimeTypes
.
APPLICATION_SS
;
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 @@
...
@@ -16,6 +16,7 @@
package
com
.
google
.
android
.
exoplayer2
.
castdemo
;
package
com
.
google
.
android
.
exoplayer2
.
castdemo
;
import
android.content.Context
;
import
android.content.Context
;
import
android.net.Uri
;
import
android.os.Bundle
;
import
android.os.Bundle
;
import
androidx.core.graphics.ColorUtils
;
import
androidx.core.graphics.ColorUtils
;
import
androidx.appcompat.app.AlertDialog
;
import
androidx.appcompat.app.AlertDialog
;
...
@@ -36,6 +37,7 @@ import android.widget.TextView;
...
@@ -36,6 +37,7 @@ import android.widget.TextView;
import
android.widget.Toast
;
import
android.widget.Toast
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.C
;
import
com.google.android.exoplayer2.SimpleExoPlayer
;
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.ext.cast.MediaItem
;
import
com.google.android.exoplayer2.ui.PlayerControlView
;
import
com.google.android.exoplayer2.ui.PlayerControlView
;
import
com.google.android.exoplayer2.ui.PlayerView
;
import
com.google.android.exoplayer2.ui.PlayerView
;
...
@@ -121,6 +123,7 @@ public class MainActivity extends AppCompatActivity
...
@@ -121,6 +123,7 @@ public class MainActivity extends AppCompatActivity
String
applicationId
=
castContext
.
getCastOptions
().
getReceiverApplicationId
();
String
applicationId
=
castContext
.
getCastOptions
().
getReceiverApplicationId
();
switch
(
applicationId
)
{
switch
(
applicationId
)
{
case
CastMediaControlIntent
.
DEFAULT_MEDIA_RECEIVER_APPLICATION_ID
:
case
CastMediaControlIntent
.
DEFAULT_MEDIA_RECEIVER_APPLICATION_ID
:
case
DefaultCastOptionsProvider
.
APP_ID_DEFAULT_RECEIVER_WITH_DRM
:
playerManager
=
playerManager
=
new
DefaultReceiverPlayerManager
(
new
DefaultReceiverPlayerManager
(
/* listener= */
this
,
/* listener= */
this
,
...
@@ -202,11 +205,17 @@ public class MainActivity extends AppCompatActivity
...
@@ -202,11 +205,17 @@ public class MainActivity extends AppCompatActivity
.
setMedia
(
sample
.
uri
)
.
setMedia
(
sample
.
uri
)
.
setTitle
(
sample
.
name
)
.
setTitle
(
sample
.
name
)
.
setMimeType
(
sample
.
mimeType
);
.
setMimeType
(
sample
.
mimeType
);
if
(
sample
.
drmSchemeUuid
!=
null
)
{
DemoUtil
.
DrmConfiguration
drmConfiguration
=
sample
.
drmConfiguration
;
if
(
drmConfiguration
!=
null
)
{
mediaItemBuilder
.
setDrmSchemes
(
mediaItemBuilder
.
setDrmSchemes
(
Collections
.
singletonList
(
Collections
.
singletonList
(
new
MediaItem
.
DrmScheme
(
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
());
playerManager
.
addItem
(
mediaItemBuilder
.
build
());
mediaQueueListAdapter
.
notifyItemInserted
(
playerManager
.
getMediaQueueSize
()
-
1
);
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;
...
@@ -27,11 +27,33 @@ import java.util.List;
*/
*/
public
final
class
DefaultCastOptionsProvider
implements
OptionsProvider
{
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
@Override
public
CastOptions
getCastOptions
(
Context
context
)
{
public
CastOptions
getCastOptions
(
Context
context
)
{
return
new
CastOptions
.
Builder
()
return
new
CastOptions
.
Builder
()
.
setReceiverApplicationId
(
CastMediaControlIntent
.
DEFAULT_MEDIA_RECEIVER_APPLICATION_ID
)
.
setReceiverApplicationId
(
APP_ID_DEFAULT_RECEIVER_WITH_DRM
)
.
setStopReceiverApplicationWhenEndingSession
(
true
).
build
();
.
setStopReceiverApplicationWhenEndingSession
(
true
)
.
build
();
}
}
@Override
@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