未验证 提交 5bfad37c 编写于 作者: O Oliver Woodman 提交者: GitHub

Merge pull request #7562 from google/dev-v2-r2.11.7

r2.11.7
# Release notes # # Release notes #
### 2.11.7 (2020-06-29) ###
* IMA extension: Fix the way postroll "content complete" notifications are
handled to avoid repeatedly refreshing the timeline after playback ends.
### 2.11.6 (2020-06-24) ### ### 2.11.6 (2020-06-24) ###
* UI: Prevent `PlayerView` from temporarily hiding the video surface when * UI: Prevent `PlayerView` from temporarily hiding the video surface when
......
...@@ -13,8 +13,8 @@ ...@@ -13,8 +13,8 @@
// limitations under the License. // limitations under the License.
project.ext { project.ext {
// ExoPlayer version and version code. // ExoPlayer version and version code.
releaseVersion = '2.11.6' releaseVersion = '2.11.7'
releaseVersionCode = 2011006 releaseVersionCode = 2011007
minSdkVersion = 16 minSdkVersion = 16
appTargetSdkVersion = 29 appTargetSdkVersion = 29
targetSdkVersion = 28 // TODO: Bump once b/143232359 is resolved targetSdkVersion = 28 // TODO: Bump once b/143232359 is resolved
......
...@@ -1026,7 +1026,7 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader { ...@@ -1026,7 +1026,7 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader {
if (imaAdState == IMA_AD_STATE_NONE if (imaAdState == IMA_AD_STATE_NONE
&& playbackState == Player.STATE_BUFFERING && playbackState == Player.STATE_BUFFERING
&& playWhenReady) { && playWhenReady) {
checkForContentComplete(); ensureSentContentCompleteIfAtEndOfStream();
} else if (imaAdState != IMA_AD_STATE_NONE && playbackState == Player.STATE_ENDED) { } else if (imaAdState != IMA_AD_STATE_NONE && playbackState == Player.STATE_ENDED) {
AdMediaInfo adMediaInfo = Assertions.checkNotNull(imaAdMediaInfo); AdMediaInfo adMediaInfo = Assertions.checkNotNull(imaAdMediaInfo);
if (adMediaInfo == null) { if (adMediaInfo == null) {
...@@ -1048,15 +1048,8 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader { ...@@ -1048,15 +1048,8 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader {
return; return;
} }
if (!playingAd && !player.isPlayingAd()) { if (!playingAd && !player.isPlayingAd()) {
checkForContentComplete(); ensureSentContentCompleteIfAtEndOfStream();
if (sentContentComplete) { if (!sentContentComplete && !timeline.isEmpty()) {
for (int i = 0; i < adPlaybackState.adGroupCount; i++) {
if (adPlaybackState.adGroupTimesUs[i] != C.TIME_END_OF_SOURCE) {
adPlaybackState = adPlaybackState.withSkippedAdGroup(/* adGroupIndex= */ i);
}
}
updateAdPlaybackState();
} else if (!timeline.isEmpty()) {
long positionMs = getContentPeriodPositionMs(player, timeline, period); long positionMs = getContentPeriodPositionMs(player, timeline, period);
timeline.getPeriod(/* periodIndex= */ 0, period); timeline.getPeriod(/* periodIndex= */ 0, period);
int newAdGroupIndex = period.getAdGroupIndexForPositionUs(C.msToUs(positionMs)); int newAdGroupIndex = period.getAdGroupIndexForPositionUs(C.msToUs(positionMs));
...@@ -1090,11 +1083,7 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader { ...@@ -1090,11 +1083,7 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader {
if (!sentContentComplete && !wasPlayingAd && playingAd && imaAdState == IMA_AD_STATE_NONE) { if (!sentContentComplete && !wasPlayingAd && playingAd && imaAdState == IMA_AD_STATE_NONE) {
int adGroupIndex = player.getCurrentAdGroupIndex(); int adGroupIndex = player.getCurrentAdGroupIndex();
if (adPlaybackState.adGroupTimesUs[adGroupIndex] == C.TIME_END_OF_SOURCE) { if (adPlaybackState.adGroupTimesUs[adGroupIndex] == C.TIME_END_OF_SOURCE) {
adsLoader.contentComplete(); sendContentComplete();
if (DEBUG) {
Log.d(TAG, "adsLoader.contentComplete from period transition");
}
sentContentComplete = true;
} else { } else {
// IMA hasn't called playAd yet, so fake the content position. // IMA hasn't called playAd yet, so fake the content position.
fakeContentProgressElapsedRealtimeMs = SystemClock.elapsedRealtime(); fakeContentProgressElapsedRealtimeMs = SystemClock.elapsedRealtime();
...@@ -1212,18 +1201,29 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader { ...@@ -1212,18 +1201,29 @@ public final class ImaAdsLoader implements Player.EventListener, AdsLoader {
updateAdPlaybackState(); updateAdPlaybackState();
} }
private void checkForContentComplete() { private void ensureSentContentCompleteIfAtEndOfStream() {
long positionMs = getContentPeriodPositionMs(Assertions.checkNotNull(player), timeline, period);
if (!sentContentComplete if (!sentContentComplete
&& contentDurationMs != C.TIME_UNSET && contentDurationMs != C.TIME_UNSET
&& pendingContentPositionMs == C.TIME_UNSET && pendingContentPositionMs == C.TIME_UNSET
&& positionMs + THRESHOLD_END_OF_CONTENT_MS >= contentDurationMs) { && getContentPeriodPositionMs(Assertions.checkNotNull(player), timeline, period)
adsLoader.contentComplete(); + THRESHOLD_END_OF_CONTENT_MS
if (DEBUG) { >= contentDurationMs) {
Log.d(TAG, "adsLoader.contentComplete from content position check"); sendContentComplete();
}
}
private void sendContentComplete() {
adsLoader.contentComplete();
sentContentComplete = true;
if (DEBUG) {
Log.d(TAG, "adsLoader.contentComplete");
}
for (int i = 0; i < adPlaybackState.adGroupCount; i++) {
if (adPlaybackState.adGroupTimesUs[i] != C.TIME_END_OF_SOURCE) {
adPlaybackState = adPlaybackState.withSkippedAdGroup(/* adGroupIndex= */ i);
} }
sentContentComplete = true;
} }
updateAdPlaybackState();
} }
private void updateAdPlaybackState() { private void updateAdPlaybackState() {
......
...@@ -29,11 +29,11 @@ public final class ExoPlayerLibraryInfo { ...@@ -29,11 +29,11 @@ public final class ExoPlayerLibraryInfo {
/** The version of the library expressed as a string, for example "1.2.3". */ /** 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. // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION_INT) or vice versa.
public static final String VERSION = "2.11.6"; public static final String VERSION = "2.11.7";
/** The version of the library expressed as {@code "ExoPlayerLib/" + VERSION}. */ /** The version of the library expressed as {@code "ExoPlayerLib/" + VERSION}. */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa. // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final String VERSION_SLASHY = "ExoPlayerLib/2.11.6"; public static final String VERSION_SLASHY = "ExoPlayerLib/2.11.7";
/** /**
* The version of the library expressed as an integer, for example 1002003. * The version of the library expressed as an integer, for example 1002003.
...@@ -43,7 +43,7 @@ public final class ExoPlayerLibraryInfo { ...@@ -43,7 +43,7 @@ public final class ExoPlayerLibraryInfo {
* integer version 123045006 (123-045-006). * integer version 123045006 (123-045-006).
*/ */
// Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa. // Intentionally hardcoded. Do not derive from other constants (e.g. VERSION) or vice versa.
public static final int VERSION_INT = 2011006; public static final int VERSION_INT = 2011007;
/** /**
* Whether the library was compiled with {@link com.google.android.exoplayer2.util.Assertions} * Whether the library was compiled with {@link com.google.android.exoplayer2.util.Assertions}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册