From efd5265e8764e06d5ba349b5e21eaa1bbe9d62df Mon Sep 17 00:00:00 2001 From: Peter Bennett Date: Thu, 17 Sep 2020 11:21:30 -0400 Subject: [PATCH 1/7] text: Fix handling of unbreakable-space in ssa subtitles The character sequence \h is used for "unbreakable space". Replace these sequences with space to avoid strings of \h showing up on screen. --- .../com/google/android/exoplayer2/text/ssa/SsaDecoder.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java b/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java index 3bb39aba9c..d6112ca361 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java @@ -264,7 +264,8 @@ public final class SsaDecoder extends SimpleSubtitleDecoder { String text = SsaStyle.Overrides.stripStyleOverrides(rawText) .replaceAll("\\\\N", "\n") - .replaceAll("\\\\n", "\n"); + .replaceAll("\\\\n", "\n") + .replaceAll("\\\\h", " "); Cue cue = createCue(text, style, styleOverrides, screenWidth, screenHeight); int startTimeIndex = addCuePlacerholderByTime(startTimeUs, cueTimesUs, cues); From cc10657c09ad9676a843de2d1c4170bbf462a509 Mon Sep 17 00:00:00 2001 From: kimvde Date: Thu, 17 Sep 2020 17:47:29 +0100 Subject: [PATCH 2/7] Fix dump file write directory PiperOrigin-RevId: 332254072 --- .../com/google/android/exoplayer2/testutil/DumpFileAsserts.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testutils/src/main/java/com/google/android/exoplayer2/testutil/DumpFileAsserts.java b/testutils/src/main/java/com/google/android/exoplayer2/testutil/DumpFileAsserts.java index 42884ec6f4..1423a3a33b 100644 --- a/testutils/src/main/java/com/google/android/exoplayer2/testutil/DumpFileAsserts.java +++ b/testutils/src/main/java/com/google/android/exoplayer2/testutil/DumpFileAsserts.java @@ -98,7 +98,7 @@ public class DumpFileAsserts { } else { File file = DUMP_FILE_ACTION == WRITE_TO_LOCAL - ? new File(StandardSystemProperty.USER_DIR.value(), "../../testdata/src/test") + ? new File(StandardSystemProperty.USER_DIR.value(), "../../testdata/src/test/assets") : context.getExternalFilesDir(null); file = new File(file, dumpFile); Assertions.checkStateNotNull(file.getParentFile()).mkdirs(); From 4aa3a0482d8bf1eb3b7f08c6127a953295b3c93f Mon Sep 17 00:00:00 2001 From: kimvde Date: Fri, 18 Sep 2020 10:54:46 +0100 Subject: [PATCH 3/7] Add unit tests for Transformer PiperOrigin-RevId: 332416139 --- .../google/android/exoplayer2/MetadataRetrieverTest.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/test/java/com/google/android/exoplayer2/MetadataRetrieverTest.java b/library/core/src/test/java/com/google/android/exoplayer2/MetadataRetrieverTest.java index 09b546e89e..e666ec979d 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/MetadataRetrieverTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/MetadataRetrieverTest.java @@ -31,11 +31,9 @@ import com.google.common.util.concurrent.ListenableFuture; import java.util.concurrent.ExecutionException; import org.junit.Test; import org.junit.runner.RunWith; -import org.robolectric.annotation.LooperMode; /** Tests for {@link MetadataRetriever}. */ @RunWith(AndroidJUnit4.class) -@LooperMode(LooperMode.Mode.PAUSED) public class MetadataRetrieverTest { @Test @@ -100,7 +98,9 @@ public class MetadataRetrieverTest { ListenableFuture trackGroupsFuture) throws InterruptedException, ExecutionException { while (!trackGroupsFuture.isDone()) { - // Simulate advancing SystemClock so that delayed messages sent to handlers are received. + // TODO: update once [Internal: b/168084145] is implemented. + // Advance SystemClock so that messages that are sent with a delay to the MetadataRetriever + // looper are received. SystemClock.setCurrentTimeMillis(SystemClock.uptimeMillis() + 100); Thread.sleep(/* millis= */ 100); } From 2f21b10442f3909019ba52bec7ef5c45022d43fa Mon Sep 17 00:00:00 2001 From: bachinger Date: Mon, 21 Sep 2020 14:38:09 +0100 Subject: [PATCH 4/7] Mention moving skipSilence in release note Issue: #7939 PiperOrigin-RevId: 332838586 --- RELEASENOTES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index e3df35dd36..3fb578a564 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -49,6 +49,9 @@ * Deprecate `EventListener.onSeekProcessed` because seek changes now happen instantly and listening to `onPositionDiscontinuity` is sufficient. + * Split off `skipSilence' from `PlaybackParameter` and move it + to `AudioComponent.setSkipSilenceEnabled` with callback + `AudioListener.onSkipSilenceEnabledChanged`. * `ExoPlayer`: * Add `setMediaSource(s)` and `addMediaSource(s)` to `ExoPlayer`, for adding `MediaSource` instances directly to the playlist. From dc2427439120b0d0869021967190a39a80fa4490 Mon Sep 17 00:00:00 2001 From: krocard Date: Mon, 21 Sep 2020 16:38:19 +0100 Subject: [PATCH 5/7] Recover from audio server crash while sleeping for offload Without this patch, playback would be frozen indefinitely until the user manually pauses and unpauses it. This has the side effect of disabling offload until the next stop due to the workaround of disabling offload when it encounters a failure. As an audio server crash is considered very infrequent, especially in stable conditions like an audio only playback, it is unlikely that disabling offload is an issue. PiperOrigin-RevId: 332857094 --- .../android/exoplayer2/audio/DefaultAudioSink.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java index 1e04b1e8d7..41e76440c1 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java @@ -28,6 +28,7 @@ import android.os.Handler; import android.os.SystemClock; import android.util.Pair; import androidx.annotation.IntDef; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RequiresApi; import com.google.android.exoplayer2.C; @@ -1694,6 +1695,16 @@ public final class DefaultAudioSink implements AudioSink { } } + @Override + public void onTearDown(@NonNull AudioTrack track) { + if (listener != null && playing) { + // A new Audio Track needs to be created and it's buffer filled, which will be done on the + // next handleBuffer call. + // Request this call explicitly in case ExoPlayer is sleeping waiting for a data request. + listener.onOffloadBufferEmptying(); + } + } + public void register(AudioTrack audioTrack) { audioTrack.registerStreamEventCallback(handler::post, this); } From 77d125b243ca0529dc5a73861c3723bf95f1d4e4 Mon Sep 17 00:00:00 2001 From: ibaker Date: Mon, 21 Sep 2020 17:24:01 +0100 Subject: [PATCH 6/7] Use replace() instead of replaceAll() in SsaDecoder We're not using regex so there's no need to use replaceAll() PiperOrigin-RevId: 332865724 --- .../com/google/android/exoplayer2/text/ssa/SsaDecoder.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java b/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java index 064e8dac89..f44db4924f 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/text/ssa/SsaDecoder.java @@ -263,9 +263,9 @@ public final class SsaDecoder extends SimpleSubtitleDecoder { SsaStyle.Overrides styleOverrides = SsaStyle.Overrides.parseFromDialogue(rawText); String text = SsaStyle.Overrides.stripStyleOverrides(rawText) - .replaceAll("\\\\N", "\n") - .replaceAll("\\\\n", "\n") - .replaceAll("\\\\h", "\u00A0"); + .replace("\\N", "\n") + .replace("\\n", "\n") + .replace("\\h", "\u00A0"); Cue cue = createCue(text, style, styleOverrides, screenWidth, screenHeight); int startTimeIndex = addCuePlacerholderByTime(startTimeUs, cueTimesUs, cues); From 39f9eadefa5bf5eb70330c3e92e2cb99b30023cf Mon Sep 17 00:00:00 2001 From: olly Date: Mon, 21 Sep 2020 22:51:56 +0100 Subject: [PATCH 7/7] Add blog posts to release notes PiperOrigin-RevId: 332940209 --- RELEASENOTES.md | 62 +++++++++++++++++++++++++++++-------------------- 1 file changed, 37 insertions(+), 25 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 3fb578a564..ffdfc1c1e7 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -12,19 +12,24 @@ ### 2.12.0 (2020-09-11) ### +To learn more about what's new in 2.12, read the corresponding +[blog post](https://medium.com/google-exoplayer/exoplayer-2-12-whats-new-e43ef8ff72e7). + * Core library: * `Player`: * Add a top level playlist API based on a new `MediaItem` class - ([#6161](https://github.com/google/ExoPlayer/issues/6161)). The - new methods for playlist manipulation are `setMediaItem(s)`, + ([#6161](https://github.com/google/ExoPlayer/issues/6161)). The new + methods for playlist manipulation are `setMediaItem(s)`, `addMediaItem(s)`, `moveMediaItem(s)`, `removeMediaItem(s)` and `clearMediaItems`. The playlist can be queried using `getMediaItemCount` and `getMediaItemAt`. This API should be used - instead of `ConcatenatingMediaSource` in most cases. - * Add `getCurrentMediaItem` for getting the currently playing item - in the playlist. - * Add `EventListener.onMediaItemTransition` to report when - playback transitions from one item to another in the playlist. + instead of `ConcatenatingMediaSource` in most cases. Learn more by + reading + [this blog post](https://medium.com/google-exoplayer/a-top-level-playlist-api-for-exoplayer-abe0a24edb55). + * Add `getCurrentMediaItem` for getting the currently playing item in + the playlist. + * Add `EventListener.onMediaItemTransition` to report when playback + transitions from one item to another in the playlist. * Add `play` and `pause` convenience methods. They are equivalent to `setPlayWhenReady(true)` and `setPlayWhenReady(false)` respectively. * Add `getCurrentLiveOffset` for getting the offset of the current @@ -33,6 +38,11 @@ player. * Add `AudioComponent.setAudioSessionId` to set the audio session ID. This method is also available on `SimpleExoPlayer`. + * Remove `PlaybackParameters.skipSilence`, and replace it with + `AudioComponent.setSkipSilenceEnabled`. This method is also + available on `SimpleExoPlayer`. An + `AudioListener.onSkipSilenceEnabledChanged` callback is also + added. * Add `TextComponent.getCurrentCues` to get the current cues. This method is also available on `SimpleExoPlayer`. The current cues are no longer automatically forwarded to a `TextOutput` when it's added @@ -49,9 +59,6 @@ * Deprecate `EventListener.onSeekProcessed` because seek changes now happen instantly and listening to `onPositionDiscontinuity` is sufficient. - * Split off `skipSilence' from `PlaybackParameter` and move it - to `AudioComponent.setSkipSilenceEnabled` with callback - `AudioListener.onSkipSilenceEnabledChanged`. * `ExoPlayer`: * Add `setMediaSource(s)` and `addMediaSource(s)` to `ExoPlayer`, for adding `MediaSource` instances directly to the playlist. @@ -89,8 +96,8 @@ ([#7309](https://github.com/google/ExoPlayer/issues/7309)). `LoadErrorHandlingPolicy` implementations should migrate to implementing the non-deprecated methods of the interface. - * Add an option to `MergingMediaSource` to adjust the time offsets - between the merged sources + * Add an option to `MergingMediaSource` to adjust the time offsets between + the merged sources ([#6103](https://github.com/google/ExoPlayer/issues/6103)). * Move `MediaSourceEventListener.LoadEventInfo` and `MediaSourceEventListener.MediaLoadData` to be top-level classes in @@ -100,11 +107,10 @@ generalize them to work with `Decoder` rather than `SimpleDecoder`. * Deprecate `C.MSG_*` constants, replacing them with constants in `Renderer`. - * Split the `library-core` module into `library-core`, - `library-common` and `library-extractor`. The `library-core` module - has an API dependency on both of the new modules, so this change - should be transparent to developers including ExoPlayer using Gradle - dependencies. + * Split the `library-core` module into `library-core`, `library-common` + and `library-extractor`. The `library-core` module has an API dependency + on both of the new modules, so this change should be transparent to + developers including ExoPlayer using Gradle dependencies. * Add a dependency on Guava. * Video: * Pass frame rate hint to `Surface.setFrameRate` on Android 11. @@ -144,6 +150,10 @@ the `AudioCapabilities` ([#7404](https://github.com/google/ExoPlayer/issues/7404)). * Text: + * Many of the changes described below improve support for Japanese + subtitles. Read + [this blog post](https://medium.com/google-exoplayer/improved-japanese-subtitle-support-7598fee12cf4) + to learn more. * Add a WebView-based output option to `SubtitleView`. This can display some features not supported by the existing Canvas-based output such as vertical text and rubies. It can be enabled by calling @@ -306,8 +316,8 @@ * Analytics: * Extend `EventTime` with more details about the current player state ([#7332](https://github.com/google/ExoPlayer/issues/7332)). - * Add `AnalyticsListener.onVideoFrameProcessingOffset` to report how - early or late video frames are processed relative to them needing to be + * Add `AnalyticsListener.onVideoFrameProcessingOffset` to report how early + or late video frames are processed relative to them needing to be presented. Video frame processing offset fields are also added to `DecoderCounters`. * Fix incorrect `MediaPeriodId` for some renderer errors reported by @@ -317,7 +327,9 @@ * Test utils: Add `TestExoPlayer`, a utility class with APIs to create `SimpleExoPlayer` instances with fake components for testing. * Media2 extension: This is a new extension that makes it easy to use - ExoPlayer together with AndroidX Media2. + ExoPlayer together with AndroidX Media2. Read + [this blog post](https://medium.com/google-exoplayer/the-media2-extension-for-exoplayer-d6b7d89b9063) + to learn more. * Cast extension: Implement playlist API and deprecate the old queue manipulation API. * IMA extension: @@ -347,11 +359,11 @@ * Add `clip_start_position_ms` and `clip_end_position_ms` to allow clipped samples. * Use `StyledPlayerControlView` rather than `PlayerView`. - * Remove support for media tunneling, random ABR and playback of - spherical video. Developers wishing to experiment with these features - can enable them by modifying the demo app source code. - * Add support for downloading DRM-protected content using offline - Widevine licenses. + * Remove support for media tunneling, random ABR and playback of spherical + video. Developers wishing to experiment with these features can enable + them by modifying the demo app source code. + * Add support for downloading DRM-protected content using offline Widevine + licenses. ### 2.11.8 (2020-08-25) ###