mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Add setPlaybackLooper ExoPlayer builder method
The method allows clients to specify a pre-existing thread to use for playback. This can be used to run multiple ExoPlayer instances on the same playback thread. PiperOrigin-RevId: 488980749 (cherry picked from commit e1fe3120e29a66ac2dcde6e9960756197bac6444)
This commit is contained in:
parent
c11b5cf91c
commit
9ba059f73f
@ -34,6 +34,8 @@ This release corresponds to the
|
||||
* Fix bug where removing listeners during the player release can cause an
|
||||
`IllegalStateException`
|
||||
([#10758](https://github.com/google/ExoPlayer/issues/10758)).
|
||||
* Add `ExoPlayer.Builder.setPlaybackLooper` that sets a pre-existing
|
||||
playback thread for a new ExoPlayer instance.
|
||||
* Build:
|
||||
* Enforce minimum `compileSdkVersion` to avoid compilation errors
|
||||
([#10684](https://github.com/google/ExoPlayer/issues/10684)).
|
||||
|
@ -24,6 +24,7 @@ import android.media.AudioDeviceInfo;
|
||||
import android.media.AudioTrack;
|
||||
import android.media.MediaCodec;
|
||||
import android.os.Looper;
|
||||
import android.os.Process;
|
||||
import android.view.Surface;
|
||||
import android.view.SurfaceHolder;
|
||||
import android.view.SurfaceView;
|
||||
@ -485,6 +486,7 @@ public interface ExoPlayer extends Player {
|
||||
/* package */ long detachSurfaceTimeoutMs;
|
||||
/* package */ boolean pauseAtEndOfMediaItems;
|
||||
/* package */ boolean usePlatformDiagnostics;
|
||||
@Nullable /* package */ Looper playbackLooper;
|
||||
/* package */ boolean buildCalled;
|
||||
|
||||
/**
|
||||
@ -527,6 +529,7 @@ public interface ExoPlayer extends Player {
|
||||
* <li>{@code pauseAtEndOfMediaItems}: {@code false}
|
||||
* <li>{@code usePlatformDiagnostics}: {@code true}
|
||||
* <li>{@link Clock}: {@link Clock#DEFAULT}
|
||||
* <li>{@code playbackLooper}: {@code null} (create new thread)
|
||||
* </ul>
|
||||
*
|
||||
* @param context A {@link Context}.
|
||||
@ -1134,6 +1137,24 @@ public interface ExoPlayer extends Player {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link Looper} that will be used for playback.
|
||||
*
|
||||
* <p>The backing thread should run with priority {@link Process#THREAD_PRIORITY_AUDIO} and
|
||||
* should handle messages within 10ms.
|
||||
*
|
||||
* @param playbackLooper A {@link looper}.
|
||||
* @return This builder.
|
||||
* @throws IllegalStateException If {@link #build()} has already been called.
|
||||
*/
|
||||
@CanIgnoreReturnValue
|
||||
@UnstableApi
|
||||
public Builder setPlaybackLooper(Looper playbackLooper) {
|
||||
checkState(!buildCalled);
|
||||
this.playbackLooper = playbackLooper;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds an {@link ExoPlayer} instance.
|
||||
*
|
||||
|
@ -345,7 +345,8 @@ import java.util.concurrent.TimeoutException;
|
||||
applicationLooper,
|
||||
clock,
|
||||
playbackInfoUpdateListener,
|
||||
playerId);
|
||||
playerId,
|
||||
builder.playbackLooper);
|
||||
|
||||
volume = 1;
|
||||
repeatMode = Player.REPEAT_MODE_OFF;
|
||||
|
@ -189,7 +189,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
private final LoadControl loadControl;
|
||||
private final BandwidthMeter bandwidthMeter;
|
||||
private final HandlerWrapper handler;
|
||||
private final HandlerThread internalPlaybackThread;
|
||||
@Nullable private final HandlerThread internalPlaybackThread;
|
||||
private final Looper playbackLooper;
|
||||
private final Timeline.Window window;
|
||||
private final Timeline.Period period;
|
||||
@ -244,7 +244,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
Looper applicationLooper,
|
||||
Clock clock,
|
||||
PlaybackInfoUpdateListener playbackInfoUpdateListener,
|
||||
PlayerId playerId) {
|
||||
PlayerId playerId,
|
||||
Looper playbackLooper) {
|
||||
this.playbackInfoUpdateListener = playbackInfoUpdateListener;
|
||||
this.renderers = renderers;
|
||||
this.trackSelector = trackSelector;
|
||||
@ -285,12 +286,18 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
mediaSourceList =
|
||||
new MediaSourceList(/* listener= */ this, analyticsCollector, eventHandler, playerId);
|
||||
|
||||
// Note: The documentation for Process.THREAD_PRIORITY_AUDIO that states "Applications can
|
||||
// not normally change to this priority" is incorrect.
|
||||
internalPlaybackThread = new HandlerThread("ExoPlayer:Playback", Process.THREAD_PRIORITY_AUDIO);
|
||||
internalPlaybackThread.start();
|
||||
playbackLooper = internalPlaybackThread.getLooper();
|
||||
handler = clock.createHandler(playbackLooper, this);
|
||||
if (playbackLooper != null) {
|
||||
internalPlaybackThread = null;
|
||||
this.playbackLooper = playbackLooper;
|
||||
} else {
|
||||
// Note: The documentation for Process.THREAD_PRIORITY_AUDIO that states "Applications can
|
||||
// not normally change to this priority" is incorrect.
|
||||
internalPlaybackThread =
|
||||
new HandlerThread("ExoPlayer:Playback", Process.THREAD_PRIORITY_AUDIO);
|
||||
internalPlaybackThread.start();
|
||||
this.playbackLooper = internalPlaybackThread.getLooper();
|
||||
}
|
||||
handler = clock.createHandler(this.playbackLooper, this);
|
||||
}
|
||||
|
||||
public void experimentalSetForegroundModeTimeoutMs(long setForegroundModeTimeoutMs) {
|
||||
@ -393,7 +400,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
@Override
|
||||
public synchronized void sendMessage(PlayerMessage message) {
|
||||
if (released || !internalPlaybackThread.isAlive()) {
|
||||
if (released || !playbackLooper.getThread().isAlive()) {
|
||||
Log.w(TAG, "Ignoring messages sent after release.");
|
||||
message.markAsProcessed(/* isDelivered= */ false);
|
||||
return;
|
||||
@ -408,7 +415,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
* @return Whether the operations succeeded. If false, the operation timed out.
|
||||
*/
|
||||
public synchronized boolean setForegroundMode(boolean foregroundMode) {
|
||||
if (released || !internalPlaybackThread.isAlive()) {
|
||||
if (released || !playbackLooper.getThread().isAlive()) {
|
||||
return true;
|
||||
}
|
||||
if (foregroundMode) {
|
||||
@ -430,7 +437,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
* @return Whether the release succeeded. If false, the release timed out.
|
||||
*/
|
||||
public synchronized boolean release() {
|
||||
if (released || !internalPlaybackThread.isAlive()) {
|
||||
if (released || !playbackLooper.getThread().isAlive()) {
|
||||
return true;
|
||||
}
|
||||
handler.sendEmptyMessage(MSG_RELEASE);
|
||||
@ -1382,7 +1389,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
/* resetError= */ false);
|
||||
loadControl.onReleased();
|
||||
setState(Player.STATE_IDLE);
|
||||
internalPlaybackThread.quit();
|
||||
if (internalPlaybackThread != null) {
|
||||
internalPlaybackThread.quit();
|
||||
}
|
||||
synchronized (this) {
|
||||
released = true;
|
||||
notifyAll();
|
||||
|
Loading…
x
Reference in New Issue
Block a user