|
39 | 39 | import androidx.annotation.Nullable; |
40 | 40 | import androidx.annotation.RequiresApi; |
41 | 41 | import com.google.android.exoplayer2.C; |
| 42 | +import com.google.android.exoplayer2.ExoPlayer.AudioOffloadListener; |
42 | 43 | import com.google.android.exoplayer2.Format; |
43 | 44 | import com.google.android.exoplayer2.PlaybackParameters; |
44 | 45 | import com.google.android.exoplayer2.analytics.PlayerId; |
@@ -265,6 +266,7 @@ public static final class Builder { |
265 | 266 | private boolean enableAudioTrackPlaybackParams; |
266 | 267 | private int offloadMode; |
267 | 268 | AudioTrackBufferSizeProvider audioTrackBufferSizeProvider; |
| 269 | + @Nullable AudioOffloadListener audioOffloadListener; |
268 | 270 |
|
269 | 271 | /** Creates a new builder. */ |
270 | 272 | public Builder() { |
@@ -370,6 +372,19 @@ public Builder setAudioTrackBufferSizeProvider( |
370 | 372 | return this; |
371 | 373 | } |
372 | 374 |
|
| 375 | + /** |
| 376 | + * Sets an optional {@link AudioOffloadListener} to receive events relevant to offloaded |
| 377 | + * playback. |
| 378 | + * |
| 379 | + * <p>The default value is null. |
| 380 | + */ |
| 381 | + @CanIgnoreReturnValue |
| 382 | + public Builder setExperimentalAudioOffloadListener( |
| 383 | + @Nullable AudioOffloadListener audioOffloadListener) { |
| 384 | + this.audioOffloadListener = audioOffloadListener; |
| 385 | + return this; |
| 386 | + } |
| 387 | + |
373 | 388 | /** Builds the {@link DefaultAudioSink}. Must only be called once per Builder instance. */ |
374 | 389 | public DefaultAudioSink build() { |
375 | 390 | if (audioProcessorChain == null) { |
@@ -500,6 +515,7 @@ public DefaultAudioSink build() { |
500 | 515 | initializationExceptionPendingExceptionHolder; |
501 | 516 | private final PendingExceptionHolder<WriteException> writeExceptionPendingExceptionHolder; |
502 | 517 | private final AudioTrackBufferSizeProvider audioTrackBufferSizeProvider; |
| 518 | + @Nullable private final AudioOffloadListener audioOffloadListener; |
503 | 519 |
|
504 | 520 | @Nullable private PlayerId playerId; |
505 | 521 | @Nullable private Listener listener; |
@@ -660,6 +676,7 @@ private DefaultAudioSink(Builder builder) { |
660 | 676 | new PendingExceptionHolder<>(AUDIO_TRACK_RETRY_DURATION_MS); |
661 | 677 | writeExceptionPendingExceptionHolder = |
662 | 678 | new PendingExceptionHolder<>(AUDIO_TRACK_RETRY_DURATION_MS); |
| 679 | + audioOffloadListener = builder.audioOffloadListener; |
663 | 680 | } |
664 | 681 |
|
665 | 682 | // AudioSink implementation. |
@@ -1087,7 +1104,12 @@ private AudioTrack buildAudioTrackWithRetry() throws InitializationException { |
1087 | 1104 |
|
1088 | 1105 | private AudioTrack buildAudioTrack(Configuration configuration) throws InitializationException { |
1089 | 1106 | try { |
1090 | | - return configuration.buildAudioTrack(tunneling, audioAttributes, audioSessionId); |
| 1107 | + AudioTrack audioTrack = |
| 1108 | + configuration.buildAudioTrack(tunneling, audioAttributes, audioSessionId); |
| 1109 | + if (audioOffloadListener != null) { |
| 1110 | + audioOffloadListener.onExperimentalOffloadedPlayback(isOffloadedPlayback(audioTrack)); |
| 1111 | + } |
| 1112 | + return audioTrack; |
1091 | 1113 | } catch (InitializationException e) { |
1092 | 1114 | if (listener != null) { |
1093 | 1115 | listener.onAudioSinkError(e); |
|
0 commit comments