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
1fdc11f2
authored
Sep 20, 2017
by
ojw28
Committed by
GitHub
Sep 20, 2017
Browse files
Options
_('Browse Files')
Download
Plain Diff
Merge pull request #3277 from google/dev-v2-r2.5.3
r2.5.3
parents
9a026671
a8136cbb
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
145 additions
and
55 deletions
RELEASENOTES.md
constants.gradle
demo/src/main/AndroidManifest.xml
extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java
library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerLibraryInfo.java
library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtil.java
library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleInputBuffer.java
library/core/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java
library/core/src/main/java/com/google/android/exoplayer2/text/cea/CeaDecoder.java
library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CachedContentIndex.java
library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/LeastRecentlyUsedCacheEvictor.java
library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCache.java
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java
library/ui/src/main/java/com/google/android/exoplayer2/ui/PlaybackControlView.java
library/ui/src/main/java/com/google/android/exoplayer2/ui/SimpleExoPlayerView.java
RELEASENOTES.md
View file @
1fdc11f2
# Release notes #
### r2.5.3 ###
*
IMA extension: Support skipping of skippable ads on AndroidTV and other
non-touch devices (
[
#3258
](
https://github.com/google/ExoPlayer/issues/3258
)
).
*
HLS: Fix broken WebVTT captions when PTS wraps around
(
[
#2928
](
https://github.com/google/ExoPlayer/issues/2928
)
).
*
Captions: Fix issues rendering CEA-608 captions
(
[
#3250
](
https://github.com/google/ExoPlayer/issues/3250
)
).
*
Workaround broken AAC decoders on Galaxy S6
(
[
#3249
](
https://github.com/google/ExoPlayer/issues/3249
)
).
*
Caching: Fix infinite loop when cache eviction fails
(
[
#3260
](
https://github.com/google/ExoPlayer/issues/3260
)
).
*
Caching: Force use of BouncyCastle on JellyBean to fix decryption issue
(
[
#2755
](
https://github.com/google/ExoPlayer/issues/2755
)
).
### r2.5.2 ###
*
IMA extension: Fix issue where ad playback could end prematurely for some
...
...
constants.gradle
View file @
1fdc11f2
...
...
@@ -24,7 +24,7 @@ project.ext {
supportLibraryVersion
=
'25.4.0'
dexmakerVersion
=
'1.2'
mockitoVersion
=
'1.9.5'
releaseVersion
=
'r2.5.
2
'
releaseVersion
=
'r2.5.
3
'
modulePrefix
=
':'
if
(
gradle
.
ext
.
has
(
'exoplayerModulePrefix'
))
{
modulePrefix
+=
gradle
.
ext
.
exoplayerModulePrefix
...
...
demo/src/main/AndroidManifest.xml
View file @
1fdc11f2
...
...
@@ -16,8 +16,8 @@
<manifest
xmlns:android=
"http://schemas.android.com/apk/res/android"
package=
"com.google.android.exoplayer2.demo"
android:versionCode=
"250
2
"
android:versionName=
"2.5.
2
"
>
android:versionCode=
"250
3
"
android:versionName=
"2.5.
3
"
>
<uses-permission
android:name=
"android.permission.INTERNET"
/>
<uses-permission
android:name=
"android.permission.READ_EXTERNAL_STORAGE"
/>
...
...
extensions/ima/src/main/java/com/google/android/exoplayer2/ext/ima/ImaAdsLoader.java
View file @
1fdc11f2
...
...
@@ -20,6 +20,7 @@ import android.net.Uri;
import
android.os.SystemClock
;
import
android.util.Log
;
import
android.view.ViewGroup
;
import
android.webkit.WebView
;
import
com.google.ads.interactivemedia.v3.api.Ad
;
import
com.google.ads.interactivemedia.v3.api.AdDisplayContainer
;
import
com.google.ads.interactivemedia.v3.api.AdErrorEvent
;
...
...
@@ -112,6 +113,14 @@ public final class ImaAdsLoader implements Player.EventListener, VideoAdPlayer,
*/
private
static
final
long
END_OF_CONTENT_POSITION_THRESHOLD_MS
=
5000
;
/**
* The "Skip ad" button rendered in the IMA WebView does not gain focus by default and cannot be
* clicked via a keypress event. Workaround this issue by calling focus() on the HTML element in
* the WebView directly when an ad starts. See [Internal: b/62371030].
*/
private
static
final
String
FOCUS_SKIP_BUTTON_WORKAROUND_JS
=
"javascript:"
+
"try{ document.getElementsByClassName(\"videoAdUiSkipButton\")[0].focus(); } catch (e) {}"
;
private
final
Uri
adTagUri
;
private
final
Timeline
.
Period
period
;
private
final
List
<
VideoAdPlayerCallback
>
adCallbacks
;
...
...
@@ -121,6 +130,7 @@ public final class ImaAdsLoader implements Player.EventListener, VideoAdPlayer,
private
EventListener
eventListener
;
private
Player
player
;
private
ViewGroup
adUiViewGroup
;
private
VideoProgressUpdate
lastContentProgress
;
private
VideoProgressUpdate
lastAdProgress
;
...
...
@@ -249,6 +259,7 @@ public final class ImaAdsLoader implements Player.EventListener, VideoAdPlayer,
ViewGroup
adUiViewGroup
)
{
this
.
player
=
player
;
this
.
eventListener
=
eventListener
;
this
.
adUiViewGroup
=
adUiViewGroup
;
lastAdProgress
=
null
;
lastContentProgress
=
null
;
adDisplayContainer
.
setAdContainer
(
adUiViewGroup
);
...
...
@@ -278,6 +289,7 @@ public final class ImaAdsLoader implements Player.EventListener, VideoAdPlayer,
player
.
removeListener
(
this
);
player
=
null
;
eventListener
=
null
;
adUiViewGroup
=
null
;
}
/**
...
...
@@ -363,6 +375,11 @@ public final class ImaAdsLoader implements Player.EventListener, VideoAdPlayer,
imaPausedContent
=
true
;
pauseContentInternal
();
break
;
case
STARTED:
if
(
ad
.
isSkippable
())
{
focusSkipButton
();
}
break
;
case
TAPPED:
if
(
eventListener
!=
null
)
{
eventListener
.
onAdTapped
();
...
...
@@ -727,4 +744,13 @@ public final class ImaAdsLoader implements Player.EventListener, VideoAdPlayer,
return
adGroupTimesUs
;
}
private
void
focusSkipButton
()
{
if
(
playingAd
&&
adUiViewGroup
!=
null
&&
adUiViewGroup
.
getChildCount
()
>
0
&&
adUiViewGroup
.
getChildAt
(
0
)
instanceof
WebView
)
{
WebView
webView
=
(
WebView
)
(
adUiViewGroup
.
getChildAt
(
0
));
webView
.
requestFocus
();
webView
.
loadUrl
(
FOCUS_SKIP_BUTTON_WORKAROUND_JS
);
}
}
}
library/core/src/main/java/com/google/android/exoplayer2/ExoPlayerLibraryInfo.java
View file @
1fdc11f2
...
...
@@ -31,13 +31,13 @@ public final class ExoPlayerLibraryInfo {
* The version of the library expressed as a string, for example "1.2.3".
*/
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa.
public
static
final
String
VERSION
=
"2.5.
2
"
;
public
static
final
String
VERSION
=
"2.5.
3
"
;
/**
* The version of the library expressed as {@code "ExoPlayerLib/" + VERSION}.
*/
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public
static
final
String
VERSION_SLASHY
=
"ExoPlayerLib/2.5.
2
"
;
public
static
final
String
VERSION_SLASHY
=
"ExoPlayerLib/2.5.
3
"
;
/**
* The version of the library expressed as an integer, for example 1002003.
...
...
@@ -47,7 +47,7 @@ public final class ExoPlayerLibraryInfo {
* integer version 123045006 (123-045-006).
*/
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public
static
final
int
VERSION_INT
=
200500
2
;
public
static
final
int
VERSION_INT
=
200500
3
;
/**
* Whether the library was compiled with {@link com.google.android.exoplayer2.util.Assertions}
...
...
library/core/src/main/java/com/google/android/exoplayer2/mediacodec/MediaCodecUtil.java
View file @
1fdc11f2
...
...
@@ -325,7 +325,22 @@ public final class MediaCodecUtil {
return
false
;
}
// Work around https://github.com/google/ExoPlayer/issues/548
// Work around https://github.com/google/ExoPlayer/issues/3249.
if
(
Util
.
SDK_INT
<
24
&&
(
"OMX.SEC.aac.dec"
.
equals
(
name
)
||
"OMX.Exynos.AAC.Decoder"
.
equals
(
name
))
&&
Util
.
MANUFACTURER
.
equals
(
"samsung"
)
&&
(
Util
.
DEVICE
.
startsWith
(
"zeroflte"
)
// Galaxy S6
||
Util
.
DEVICE
.
startsWith
(
"zerolte"
)
// Galaxy S6 Edge
||
Util
.
DEVICE
.
startsWith
(
"zenlte"
)
// Galaxy S6 Edge+
||
Util
.
DEVICE
.
equals
(
"SC-05G"
)
// Galaxy S6
||
Util
.
DEVICE
.
equals
(
"marinelteatt"
)
// Galaxy S6 Active
||
Util
.
DEVICE
.
equals
(
"404SC"
)
// Galaxy S6 Edge
||
Util
.
DEVICE
.
equals
(
"SC-04G"
)
||
Util
.
DEVICE
.
equals
(
"SCV31"
)))
{
return
false
;
}
// Work around https://github.com/google/ExoPlayer/issues/548.
// VP8 decoder on Samsung Galaxy S3/S4/S4 Mini/Tab 3/Note 2 does not render video.
if
(
Util
.
SDK_INT
<=
19
&&
"OMX.SEC.vp8.dec"
.
equals
(
name
)
&&
"samsung"
.
equals
(
Util
.
MANUFACTURER
)
...
...
library/core/src/main/java/com/google/android/exoplayer2/text/SubtitleInputBuffer.java
View file @
1fdc11f2
...
...
@@ -37,6 +37,9 @@ public final class SubtitleInputBuffer extends DecoderInputBuffer
@Override
public
int
compareTo
(
@NonNull
SubtitleInputBuffer
other
)
{
if
(
isEndOfStream
()
!=
other
.
isEndOfStream
())
{
return
isEndOfStream
()
?
1
:
-
1
;
}
long
delta
=
timeUs
-
other
.
timeUs
;
if
(
delta
==
0
)
{
return
0
;
...
...
library/core/src/main/java/com/google/android/exoplayer2/text/TextRenderer.java
View file @
1fdc11f2
...
...
@@ -294,9 +294,9 @@ public final class TextRenderer extends BaseRenderer implements Callback {
}
private
long
getNextEventTime
()
{
return
((
nextSubtitleEventIndex
==
C
.
INDEX_UNSET
)
||
(
nextSubtitleEventIndex
>=
subtitle
.
getEventTimeCount
()))
?
Long
.
MAX_VALUE
:
(
subtitle
.
getEventTime
(
nextSubtitleEventIndex
)
);
return
nextSubtitleEventIndex
==
C
.
INDEX_UNSET
||
nextSubtitleEventIndex
>=
subtitle
.
getEventTimeCount
()
?
Long
.
MAX_VALUE
:
subtitle
.
getEventTime
(
nextSubtitleEventIndex
);
}
private
void
updateOutput
(
List
<
Cue
>
cues
)
{
...
...
library/core/src/main/java/com/google/android/exoplayer2/text/cea/CeaDecoder.java
View file @
1fdc11f2
...
...
@@ -24,7 +24,7 @@ import com.google.android.exoplayer2.text.SubtitleInputBuffer;
import
com.google.android.exoplayer2.text.SubtitleOutputBuffer
;
import
com.google.android.exoplayer2.util.Assertions
;
import
java.util.LinkedList
;
import
java.util.
TreeSet
;
import
java.util.
PriorityQueue
;
/**
* Base class for subtitle parsers for CEA captions.
...
...
@@ -36,7 +36,7 @@ import java.util.TreeSet;
private
final
LinkedList
<
SubtitleInputBuffer
>
availableInputBuffers
;
private
final
LinkedList
<
SubtitleOutputBuffer
>
availableOutputBuffers
;
private
final
TreeSet
<
SubtitleInputBuffer
>
queuedInputBuffers
;
private
final
PriorityQueue
<
SubtitleInputBuffer
>
queuedInputBuffers
;
private
SubtitleInputBuffer
dequeuedInputBuffer
;
private
long
playbackPositionUs
;
...
...
@@ -50,7 +50,7 @@ import java.util.TreeSet;
for
(
int
i
=
0
;
i
<
NUM_OUTPUT_BUFFERS
;
i
++)
{
availableOutputBuffers
.
add
(
new
CeaOutputBuffer
(
this
));
}
queuedInputBuffers
=
new
TreeSet
<>();
queuedInputBuffers
=
new
PriorityQueue
<>();
}
@Override
...
...
@@ -73,7 +73,6 @@ import java.util.TreeSet;
@Override
public
void
queueInputBuffer
(
SubtitleInputBuffer
inputBuffer
)
throws
SubtitleDecoderException
{
Assertions
.
checkArgument
(
inputBuffer
!=
null
);
Assertions
.
checkArgument
(
inputBuffer
==
dequeuedInputBuffer
);
if
(
inputBuffer
.
isDecodeOnly
())
{
// We can drop this buffer early (i.e. before it would be decoded) as the CEA formats allow
...
...
@@ -90,13 +89,12 @@ import java.util.TreeSet;
if
(
availableOutputBuffers
.
isEmpty
())
{
return
null
;
}
// iterate through all available input buffers whose timestamps are less than or equal
// to the current playback position; processing input buffers for future content should
// be deferred until they would be applicable
while
(!
queuedInputBuffers
.
isEmpty
()
&&
queuedInputBuffers
.
first
().
timeUs
<=
playbackPositionUs
)
{
SubtitleInputBuffer
inputBuffer
=
queuedInputBuffers
.
poll
First
();
&&
queuedInputBuffers
.
peek
().
timeUs
<=
playbackPositionUs
)
{
SubtitleInputBuffer
inputBuffer
=
queuedInputBuffers
.
poll
();
// If the input buffer indicates we've reached the end of the stream, we can
// return immediately with an output buffer propagating that
...
...
@@ -142,7 +140,7 @@ import java.util.TreeSet;
public
void
flush
()
{
playbackPositionUs
=
0
;
while
(!
queuedInputBuffers
.
isEmpty
())
{
releaseInputBuffer
(
queuedInputBuffers
.
poll
First
());
releaseInputBuffer
(
queuedInputBuffers
.
poll
());
}
if
(
dequeuedInputBuffer
!=
null
)
{
releaseInputBuffer
(
dequeuedInputBuffer
);
...
...
library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/CachedContentIndex.java
View file @
1fdc11f2
...
...
@@ -49,7 +49,7 @@ import javax.crypto.spec.SecretKeySpec;
/**
* This class maintains the index of cached content.
*/
/*package*/
final
class
CachedContentIndex
{
/*package*/
class
CachedContentIndex
{
public
static
final
String
FILE_NAME
=
"cached_content_index.exi"
;
...
...
@@ -99,7 +99,7 @@ import javax.crypto.spec.SecretKeySpec;
if
(
secretKey
!=
null
)
{
Assertions
.
checkArgument
(
secretKey
.
length
==
16
);
try
{
cipher
=
Cipher
.
getInstance
(
"AES/CBC/PKCS5PADDING"
);
cipher
=
getCipher
(
);
secretKeySpec
=
new
SecretKeySpec
(
secretKey
,
"AES"
);
}
catch
(
NoSuchAlgorithmException
|
NoSuchPaddingException
e
)
{
throw
new
IllegalStateException
(
e
);
// Should never happen.
...
...
@@ -354,6 +354,18 @@ import javax.crypto.spec.SecretKeySpec;
return
cachedContent
;
}
private
static
Cipher
getCipher
()
throws
NoSuchPaddingException
,
NoSuchAlgorithmException
{
// Workaround for https://issuetracker.google.com/issues/36976726
if
(
Util
.
SDK_INT
==
18
)
{
try
{
return
Cipher
.
getInstance
(
"AES/CBC/PKCS5PADDING"
,
"BC"
);
}
catch
(
Throwable
ignored
)
{
// ignored
}
}
return
Cipher
.
getInstance
(
"AES/CBC/PKCS5PADDING"
);
}
/**
* Returns an id which isn't used in the given array. If the maximum id in the array is smaller
* than {@link java.lang.Integer#MAX_VALUE} it just returns the next bigger integer. Otherwise it
...
...
library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/LeastRecentlyUsedCacheEvictor.java
View file @
1fdc11f2
...
...
@@ -74,7 +74,7 @@ public final class LeastRecentlyUsedCacheEvictor implements CacheEvictor, Compar
}
private
void
evictCache
(
Cache
cache
,
long
requiredSpace
)
{
while
(
currentSize
+
requiredSpace
>
maxBytes
)
{
while
(
currentSize
+
requiredSpace
>
maxBytes
&&
!
leastRecentlyUsed
.
isEmpty
()
)
{
try
{
cache
.
removeSpan
(
leastRecentlyUsed
.
first
());
}
catch
(
CacheException
e
)
{
...
...
library/core/src/main/java/com/google/android/exoplayer2/upstream/cache/SimpleCache.java
View file @
1fdc11f2
...
...
@@ -48,7 +48,7 @@ public final class SimpleCache implements Cache {
* @param evictor The evictor to be used.
*/
public
SimpleCache
(
File
cacheDir
,
CacheEvictor
evictor
)
{
this
(
cacheDir
,
evictor
,
null
);
this
(
cacheDir
,
evictor
,
null
,
false
);
}
/**
...
...
@@ -75,10 +75,22 @@ public final class SimpleCache implements Cache {
* @param encrypt When false, a plaintext index will be written.
*/
public
SimpleCache
(
File
cacheDir
,
CacheEvictor
evictor
,
byte
[]
secretKey
,
boolean
encrypt
)
{
this
(
cacheDir
,
evictor
,
new
CachedContentIndex
(
cacheDir
,
secretKey
,
encrypt
));
}
/**
* Constructs the cache. The cache will delete any unrecognized files from the directory. Hence
* the directory cannot be used to store other files.
*
* @param cacheDir A dedicated cache directory.
* @param evictor The evictor to be used.
* @param index The CachedContentIndex to be used.
*/
/*package*/
SimpleCache
(
File
cacheDir
,
CacheEvictor
evictor
,
CachedContentIndex
index
)
{
this
.
cacheDir
=
cacheDir
;
this
.
evictor
=
evictor
;
this
.
lockedSpans
=
new
HashMap
<>();
this
.
index
=
new
CachedContentIndex
(
cacheDir
,
secretKey
,
encrypt
)
;
this
.
index
=
index
;
this
.
listeners
=
new
HashMap
<>();
// Start cache initialization.
final
ConditionVariable
conditionVariable
=
new
ConditionVariable
();
...
...
@@ -305,11 +317,14 @@ public final class SimpleCache implements Cache {
return
;
}
totalSpace
-=
span
.
length
;
if
(
removeEmptyCachedContent
&&
cachedContent
.
isEmpty
())
{
index
.
removeEmpty
(
cachedContent
.
key
);
index
.
store
();
try
{
if
(
removeEmptyCachedContent
&&
cachedContent
.
isEmpty
())
{
index
.
removeEmpty
(
cachedContent
.
key
);
index
.
store
();
}
}
finally
{
notifySpanRemoved
(
span
);
}
notifySpanRemoved
(
span
);
}
@Override
...
...
library/hls/src/main/java/com/google/android/exoplayer2/source/hls/WebvttExtractor.java
View file @
1fdc11f2
...
...
@@ -141,8 +141,7 @@ import java.util.regex.Pattern;
throw
new
ParserException
(
"X-TIMESTAMP-MAP doesn't contain media timestamp: "
+
line
);
}
vttTimestampUs
=
WebvttParserUtil
.
parseTimestampUs
(
localTimestampMatcher
.
group
(
1
));
tsTimestampUs
=
TimestampAdjuster
.
ptsToUs
(
Long
.
parseLong
(
mediaTimestampMatcher
.
group
(
1
)));
tsTimestampUs
=
TimestampAdjuster
.
ptsToUs
(
Long
.
parseLong
(
mediaTimestampMatcher
.
group
(
1
)));
}
}
...
...
@@ -155,8 +154,8 @@ import java.util.regex.Pattern;
}
long
firstCueTimeUs
=
WebvttParserUtil
.
parseTimestampUs
(
cueHeaderMatcher
.
group
(
1
));
long
sampleTimeUs
=
timestampAdjuster
.
adjust
Sample
Timestamp
(
firstCueTimeUs
+
tsTimestampUs
-
vttTimestampUs
);
long
sampleTimeUs
=
timestampAdjuster
.
adjust
Ts
Timestamp
(
TimestampAdjuster
.
usToPts
(
firstCueTimeUs
+
tsTimestampUs
-
vttTimestampUs
)
);
long
subsampleOffsetUs
=
sampleTimeUs
-
firstCueTimeUs
;
// Output the track.
TrackOutput
trackOutput
=
buildTrackOutput
(
subsampleOffsetUs
);
...
...
library/ui/src/main/java/com/google/android/exoplayer2/ui/PlaybackControlView.java
View file @
1fdc11f2
...
...
@@ -996,30 +996,30 @@ public class PlaybackControlView extends FrameLayout {
return
false
;
}
if
(
event
.
getAction
()
==
KeyEvent
.
ACTION_DOWN
)
{
switch
(
keyCode
)
{
case
KeyEvent
.
KEYCODE_MEDIA_FAST_FORWARD
:
fastForward
();
break
;
case
KeyEvent
.
KEYCODE_MEDIA_REWIND
:
rewind
();
break
;
case
KeyEvent
.
KEYCODE_MEDIA_PLAY_PAUSE
:
controlDispatcher
.
dispatchSetPlayWhenReady
(
player
,
!
player
.
getPlayWhenReady
())
;
break
;
case
KeyEvent
.
KEYCODE_MEDIA_PLAY
:
controlDispatcher
.
dispatchSetPlayWhenReady
(
player
,
true
)
;
break
;
case
KeyEvent
.
KEYCODE_MEDIA_PAUSE
:
controlDispatcher
.
dispatchSetPlayWhenReady
(
player
,
false
)
;
break
;
case
KeyEvent
.
KEYCODE_MEDIA_NEXT
:
next
()
;
break
;
case
KeyEvent
.
KEYCODE_MEDIA_PREVIOUS
:
previous
()
;
break
;
default
:
break
;
if
(
keyCode
==
KeyEvent
.
KEYCODE_MEDIA_FAST_FORWARD
)
{
fastForward
();
}
else
if
(
keyCode
==
KeyEvent
.
KEYCODE_MEDIA_REWIND
)
{
rewind
()
;
}
else
if
(
event
.
getRepeatCount
()
==
0
)
{
switch
(
keyCode
)
{
case
KeyEvent
.
KEYCODE_MEDIA_PLAY_PAUSE
:
controlDispatcher
.
dispatchSetPlayWhenReady
(
player
,
!
player
.
getPlayWhenReady
());
break
;
case
KeyEvent
.
KEYCODE_MEDIA_PLAY
:
controlDispatcher
.
dispatchSetPlayWhenReady
(
player
,
true
);
break
;
case
KeyEvent
.
KEYCODE_MEDIA_PAUSE
:
controlDispatcher
.
dispatchSetPlayWhenReady
(
player
,
false
);
break
;
case
KeyEvent
.
KEYCODE_MEDIA_NEXT
:
next
();
break
;
case
KeyEvent
.
KEYCODE_MEDIA_PREVIOUS
:
previous
();
break
;
default
:
break
;
}
}
}
return
true
;
...
...
library/ui/src/main/java/com/google/android/exoplayer2/ui/SimpleExoPlayerView.java
View file @
1fdc11f2
...
...
@@ -515,6 +515,13 @@ public final class SimpleExoPlayerView extends FrameLayout {
@Override
public
boolean
dispatchKeyEvent
(
KeyEvent
event
)
{
if
(
player
!=
null
&&
player
.
isPlayingAd
())
{
// Focus any overlay UI now, in case it's provided by a WebView whose contents may update
// dynamically. This is needed to make the "Skip ad" button focused on Android TV when using
// IMA [Internal: b/62371030].
overlayFrameLayout
.
requestFocus
();
return
super
.
dispatchKeyEvent
(
event
);
}
maybeShowController
(
true
);
return
dispatchMediaKeyEvent
(
event
)
||
super
.
dispatchKeyEvent
(
event
);
}
...
...
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