mirror of
https://github.com/androidx/media.git
synced 2025-05-05 06:30:24 +08:00
Add setPreferredAudioDevice method to ExoPlayer
This allows to access the associated functionality of AudioTrack and fills a feature gap to MediaPlayer, which has a similar method. Issue: androidx/media#135 PiperOrigin-RevId: 476398964
This commit is contained in:
parent
29cf09316e
commit
ccb820dd2f
@ -20,6 +20,7 @@ import static com.google.android.exoplayer2.util.Assertions.checkNotNull;
|
|||||||
import static com.google.android.exoplayer2.util.Assertions.checkState;
|
import static com.google.android.exoplayer2.util.Assertions.checkState;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.media.AudioDeviceInfo;
|
||||||
import android.media.AudioTrack;
|
import android.media.AudioTrack;
|
||||||
import android.media.MediaCodec;
|
import android.media.MediaCodec;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
@ -29,6 +30,7 @@ import android.view.SurfaceView;
|
|||||||
import android.view.TextureView;
|
import android.view.TextureView;
|
||||||
import androidx.annotation.IntRange;
|
import androidx.annotation.IntRange;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import com.google.android.exoplayer2.analytics.AnalyticsCollector;
|
import com.google.android.exoplayer2.analytics.AnalyticsCollector;
|
||||||
import com.google.android.exoplayer2.analytics.AnalyticsListener;
|
import com.google.android.exoplayer2.analytics.AnalyticsListener;
|
||||||
@ -1403,6 +1405,15 @@ public interface ExoPlayer extends Player {
|
|||||||
/** Detaches any previously attached auxiliary audio effect from the underlying audio track. */
|
/** Detaches any previously attached auxiliary audio effect from the underlying audio track. */
|
||||||
void clearAuxEffectInfo();
|
void clearAuxEffectInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the preferred audio device.
|
||||||
|
*
|
||||||
|
* @param audioDeviceInfo The preferred {@linkplain AudioDeviceInfo audio device}, or null to
|
||||||
|
* restore the default.
|
||||||
|
*/
|
||||||
|
@RequiresApi(23)
|
||||||
|
void setPreferredAudioDevice(@Nullable AudioDeviceInfo audioDeviceInfo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets whether skipping silences in the audio stream is enabled.
|
* Sets whether skipping silences in the audio stream is enabled.
|
||||||
*
|
*
|
||||||
|
@ -23,6 +23,7 @@ import static com.google.android.exoplayer2.Renderer.MSG_SET_AUDIO_SESSION_ID;
|
|||||||
import static com.google.android.exoplayer2.Renderer.MSG_SET_AUX_EFFECT_INFO;
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_AUX_EFFECT_INFO;
|
||||||
import static com.google.android.exoplayer2.Renderer.MSG_SET_CAMERA_MOTION_LISTENER;
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_CAMERA_MOTION_LISTENER;
|
||||||
import static com.google.android.exoplayer2.Renderer.MSG_SET_CHANGE_FRAME_RATE_STRATEGY;
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_CHANGE_FRAME_RATE_STRATEGY;
|
||||||
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_PREFERRED_AUDIO_DEVICE;
|
||||||
import static com.google.android.exoplayer2.Renderer.MSG_SET_SCALING_MODE;
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_SCALING_MODE;
|
||||||
import static com.google.android.exoplayer2.Renderer.MSG_SET_SKIP_SILENCE_ENABLED;
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_SKIP_SILENCE_ENABLED;
|
||||||
import static com.google.android.exoplayer2.Renderer.MSG_SET_VIDEO_FRAME_METADATA_LISTENER;
|
import static com.google.android.exoplayer2.Renderer.MSG_SET_VIDEO_FRAME_METADATA_LISTENER;
|
||||||
@ -38,6 +39,7 @@ import android.annotation.SuppressLint;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.graphics.SurfaceTexture;
|
import android.graphics.SurfaceTexture;
|
||||||
|
import android.media.AudioDeviceInfo;
|
||||||
import android.media.AudioFormat;
|
import android.media.AudioFormat;
|
||||||
import android.media.AudioTrack;
|
import android.media.AudioTrack;
|
||||||
import android.media.MediaFormat;
|
import android.media.MediaFormat;
|
||||||
@ -1431,6 +1433,13 @@ import java.util.concurrent.TimeoutException;
|
|||||||
setAuxEffectInfo(new AuxEffectInfo(AuxEffectInfo.NO_AUX_EFFECT_ID, /* sendLevel= */ 0f));
|
setAuxEffectInfo(new AuxEffectInfo(AuxEffectInfo.NO_AUX_EFFECT_ID, /* sendLevel= */ 0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(23)
|
||||||
|
@Override
|
||||||
|
public void setPreferredAudioDevice(@Nullable AudioDeviceInfo audioDeviceInfo) {
|
||||||
|
verifyApplicationThread();
|
||||||
|
sendRendererMessage(TRACK_TYPE_AUDIO, MSG_SET_PREFERRED_AUDIO_DEVICE, audioDeviceInfo);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setVolume(float volume) {
|
public void setVolume(float volume) {
|
||||||
verifyApplicationThread();
|
verifyApplicationThread();
|
||||||
|
@ -194,6 +194,13 @@ public interface Renderer extends PlayerMessage.Target {
|
|||||||
* <p>The message payload must be a {@link WakeupListener} instance.
|
* <p>The message payload must be a {@link WakeupListener} instance.
|
||||||
*/
|
*/
|
||||||
int MSG_SET_WAKEUP_LISTENER = 11;
|
int MSG_SET_WAKEUP_LISTENER = 11;
|
||||||
|
/**
|
||||||
|
* The type of a message that can be passed to audio renderers via {@link
|
||||||
|
* ExoPlayer#createMessage(PlayerMessage.Target)}. The message payload should be an {@link
|
||||||
|
* android.media.AudioDeviceInfo} instance representing the preferred audio device, or null to
|
||||||
|
* restore the default.
|
||||||
|
*/
|
||||||
|
int MSG_SET_PREFERRED_AUDIO_DEVICE = 12;
|
||||||
/**
|
/**
|
||||||
* Applications or extensions may define custom {@code MSG_*} constants that can be passed to
|
* Applications or extensions may define custom {@code MSG_*} constants that can be passed to
|
||||||
* renderers. These custom constants must be greater than or equal to this value.
|
* renderers. These custom constants must be greater than or equal to this value.
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
package com.google.android.exoplayer2;
|
package com.google.android.exoplayer2;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.media.AudioDeviceInfo;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.view.Surface;
|
import android.view.Surface;
|
||||||
import android.view.SurfaceHolder;
|
import android.view.SurfaceHolder;
|
||||||
@ -23,6 +24,7 @@ import android.view.SurfaceView;
|
|||||||
import android.view.TextureView;
|
import android.view.TextureView;
|
||||||
import androidx.annotation.IntRange;
|
import androidx.annotation.IntRange;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
import com.google.android.exoplayer2.analytics.AnalyticsCollector;
|
import com.google.android.exoplayer2.analytics.AnalyticsCollector;
|
||||||
import com.google.android.exoplayer2.analytics.AnalyticsListener;
|
import com.google.android.exoplayer2.analytics.AnalyticsListener;
|
||||||
@ -617,6 +619,13 @@ public class SimpleExoPlayer extends BasePlayer
|
|||||||
player.clearAuxEffectInfo();
|
player.clearAuxEffectInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(23)
|
||||||
|
@Override
|
||||||
|
public void setPreferredAudioDevice(@Nullable AudioDeviceInfo audioDeviceInfo) {
|
||||||
|
blockUntilConstructorFinished();
|
||||||
|
player.setPreferredAudioDevice(audioDeviceInfo);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setVolume(float volume) {
|
public void setVolume(float volume) {
|
||||||
blockUntilConstructorFinished();
|
blockUntilConstructorFinished();
|
||||||
|
@ -17,9 +17,11 @@ package com.google.android.exoplayer2.audio;
|
|||||||
|
|
||||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
|
|
||||||
|
import android.media.AudioDeviceInfo;
|
||||||
import android.media.AudioTrack;
|
import android.media.AudioTrack;
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
@ -416,6 +418,15 @@ public interface AudioSink {
|
|||||||
/** Sets the auxiliary effect. */
|
/** Sets the auxiliary effect. */
|
||||||
void setAuxEffectInfo(AuxEffectInfo auxEffectInfo);
|
void setAuxEffectInfo(AuxEffectInfo auxEffectInfo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the preferred audio device.
|
||||||
|
*
|
||||||
|
* @param audioDeviceInfo The preferred {@linkplain AudioDeviceInfo audio device}, or null to
|
||||||
|
* restore the default.
|
||||||
|
*/
|
||||||
|
@RequiresApi(23)
|
||||||
|
default void setPreferredDevice(@Nullable AudioDeviceInfo audioDeviceInfo) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enables tunneling, if possible. The sink is reset if tunneling was previously disabled.
|
* Enables tunneling, if possible. The sink is reset if tunneling was previously disabled.
|
||||||
* Enabling tunneling is only possible if the sink is based on a platform {@link AudioTrack}, and
|
* Enabling tunneling is only possible if the sink is based on a platform {@link AudioTrack}, and
|
||||||
|
@ -23,11 +23,14 @@ import static com.google.common.base.MoreObjects.firstNonNull;
|
|||||||
import static java.lang.Math.max;
|
import static java.lang.Math.max;
|
||||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
|
|
||||||
|
import android.media.AudioDeviceInfo;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
|
import androidx.annotation.DoNotInline;
|
||||||
import androidx.annotation.IntDef;
|
import androidx.annotation.IntDef;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
import com.google.android.exoplayer2.BaseRenderer;
|
import com.google.android.exoplayer2.BaseRenderer;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
@ -619,6 +622,11 @@ public abstract class DecoderAudioRenderer<
|
|||||||
case MSG_SET_AUDIO_SESSION_ID:
|
case MSG_SET_AUDIO_SESSION_ID:
|
||||||
audioSink.setAudioSessionId((Integer) message);
|
audioSink.setAudioSessionId((Integer) message);
|
||||||
break;
|
break;
|
||||||
|
case MSG_SET_PREFERRED_AUDIO_DEVICE:
|
||||||
|
if (Util.SDK_INT >= 23) {
|
||||||
|
Api23.setAudioSinkPreferredDevice(audioSink, message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case MSG_SET_CAMERA_MOTION_LISTENER:
|
case MSG_SET_CAMERA_MOTION_LISTENER:
|
||||||
case MSG_SET_CHANGE_FRAME_RATE_STRATEGY:
|
case MSG_SET_CHANGE_FRAME_RATE_STRATEGY:
|
||||||
case MSG_SET_SCALING_MODE:
|
case MSG_SET_SCALING_MODE:
|
||||||
@ -791,4 +799,16 @@ public abstract class DecoderAudioRenderer<
|
|||||||
eventDispatcher.audioSinkError(audioSinkError);
|
eventDispatcher.audioSinkError(audioSinkError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(23)
|
||||||
|
private static final class Api23 {
|
||||||
|
private Api23() {}
|
||||||
|
|
||||||
|
@DoNotInline
|
||||||
|
public static void setAudioSinkPreferredDevice(
|
||||||
|
AudioSink audioSink, @Nullable Object messagePayload) {
|
||||||
|
@Nullable AudioDeviceInfo audioDeviceInfo = (AudioDeviceInfo) messagePayload;
|
||||||
|
audioSink.setPreferredDevice(audioDeviceInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,6 +24,7 @@ import static java.lang.Math.min;
|
|||||||
import static java.lang.annotation.ElementType.TYPE_USE;
|
import static java.lang.annotation.ElementType.TYPE_USE;
|
||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
|
import android.media.AudioDeviceInfo;
|
||||||
import android.media.AudioFormat;
|
import android.media.AudioFormat;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.media.AudioTrack;
|
import android.media.AudioTrack;
|
||||||
@ -556,6 +557,7 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
private boolean externalAudioSessionIdProvided;
|
private boolean externalAudioSessionIdProvided;
|
||||||
private int audioSessionId;
|
private int audioSessionId;
|
||||||
private AuxEffectInfo auxEffectInfo;
|
private AuxEffectInfo auxEffectInfo;
|
||||||
|
@Nullable private AudioDeviceInfoApi23 preferredDevice;
|
||||||
private boolean tunneling;
|
private boolean tunneling;
|
||||||
private long lastFeedElapsedRealtimeMs;
|
private long lastFeedElapsedRealtimeMs;
|
||||||
private boolean offloadDisabledUntilNextConfiguration;
|
private boolean offloadDisabledUntilNextConfiguration;
|
||||||
@ -904,6 +906,9 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
audioTrack.attachAuxEffect(auxEffectInfo.effectId);
|
audioTrack.attachAuxEffect(auxEffectInfo.effectId);
|
||||||
audioTrack.setAuxEffectSendLevel(auxEffectInfo.sendLevel);
|
audioTrack.setAuxEffectSendLevel(auxEffectInfo.sendLevel);
|
||||||
}
|
}
|
||||||
|
if (preferredDevice != null && Util.SDK_INT >= 23) {
|
||||||
|
Api23.setPreferredDeviceOnAudioTrack(audioTrack, preferredDevice);
|
||||||
|
}
|
||||||
|
|
||||||
startMediaTimeUsNeedsInit = true;
|
startMediaTimeUsNeedsInit = true;
|
||||||
return true;
|
return true;
|
||||||
@ -1404,6 +1409,16 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
this.auxEffectInfo = auxEffectInfo;
|
this.auxEffectInfo = auxEffectInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(23)
|
||||||
|
@Override
|
||||||
|
public void setPreferredDevice(@Nullable AudioDeviceInfo audioDeviceInfo) {
|
||||||
|
this.preferredDevice =
|
||||||
|
audioDeviceInfo == null ? null : new AudioDeviceInfoApi23(audioDeviceInfo);
|
||||||
|
if (audioTrack != null) {
|
||||||
|
Api23.setPreferredDeviceOnAudioTrack(audioTrack, this.preferredDevice);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enableTunnelingV21() {
|
public void enableTunnelingV21() {
|
||||||
Assertions.checkState(Util.SDK_INT >= 21);
|
Assertions.checkState(Util.SDK_INT >= 21);
|
||||||
@ -2300,6 +2315,28 @@ public final class DefaultAudioSink implements AudioSink {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(23)
|
||||||
|
private static final class AudioDeviceInfoApi23 {
|
||||||
|
|
||||||
|
public final AudioDeviceInfo audioDeviceInfo;
|
||||||
|
|
||||||
|
public AudioDeviceInfoApi23(AudioDeviceInfo audioDeviceInfo) {
|
||||||
|
this.audioDeviceInfo = audioDeviceInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@RequiresApi(23)
|
||||||
|
private static final class Api23 {
|
||||||
|
private Api23() {}
|
||||||
|
|
||||||
|
@DoNotInline
|
||||||
|
public static void setPreferredDeviceOnAudioTrack(
|
||||||
|
AudioTrack audioTrack, @Nullable AudioDeviceInfoApi23 audioDeviceInfo) {
|
||||||
|
audioTrack.setPreferredDevice(
|
||||||
|
audioDeviceInfo == null ? null : audioDeviceInfo.audioDeviceInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@RequiresApi(31)
|
@RequiresApi(31)
|
||||||
private static final class Api31 {
|
private static final class Api31 {
|
||||||
private Api31() {}
|
private Api31() {}
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.audio;
|
package com.google.android.exoplayer2.audio;
|
||||||
|
|
||||||
|
import android.media.AudioDeviceInfo;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
import com.google.android.exoplayer2.Format;
|
import com.google.android.exoplayer2.Format;
|
||||||
import com.google.android.exoplayer2.PlaybackParameters;
|
import com.google.android.exoplayer2.PlaybackParameters;
|
||||||
import com.google.android.exoplayer2.analytics.PlayerId;
|
import com.google.android.exoplayer2.analytics.PlayerId;
|
||||||
@ -134,6 +136,12 @@ public class ForwardingAudioSink implements AudioSink {
|
|||||||
sink.setAuxEffectInfo(auxEffectInfo);
|
sink.setAuxEffectInfo(auxEffectInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(23)
|
||||||
|
@Override
|
||||||
|
public void setPreferredDevice(@Nullable AudioDeviceInfo audioDeviceInfo) {
|
||||||
|
sink.setPreferredDevice(audioDeviceInfo);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enableTunnelingV21() {
|
public void enableTunnelingV21() {
|
||||||
sink.enableTunnelingV21();
|
sink.enableTunnelingV21();
|
||||||
|
@ -23,13 +23,16 @@ import static java.lang.Math.max;
|
|||||||
|
|
||||||
import android.annotation.SuppressLint;
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.media.AudioDeviceInfo;
|
||||||
import android.media.AudioFormat;
|
import android.media.AudioFormat;
|
||||||
import android.media.MediaCodec;
|
import android.media.MediaCodec;
|
||||||
import android.media.MediaCrypto;
|
import android.media.MediaCrypto;
|
||||||
import android.media.MediaFormat;
|
import android.media.MediaFormat;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import androidx.annotation.CallSuper;
|
import androidx.annotation.CallSuper;
|
||||||
|
import androidx.annotation.DoNotInline;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
import com.google.android.exoplayer2.C;
|
import com.google.android.exoplayer2.C;
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
import com.google.android.exoplayer2.ExoPlayer;
|
import com.google.android.exoplayer2.ExoPlayer;
|
||||||
@ -745,6 +748,11 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
|||||||
AuxEffectInfo auxEffectInfo = (AuxEffectInfo) message;
|
AuxEffectInfo auxEffectInfo = (AuxEffectInfo) message;
|
||||||
audioSink.setAuxEffectInfo(auxEffectInfo);
|
audioSink.setAuxEffectInfo(auxEffectInfo);
|
||||||
break;
|
break;
|
||||||
|
case MSG_SET_PREFERRED_AUDIO_DEVICE:
|
||||||
|
if (Util.SDK_INT >= 23) {
|
||||||
|
Api23.setAudioSinkPreferredDevice(audioSink, message);
|
||||||
|
}
|
||||||
|
break;
|
||||||
case MSG_SET_SKIP_SILENCE_ENABLED:
|
case MSG_SET_SKIP_SILENCE_ENABLED:
|
||||||
audioSink.setSkipSilenceEnabled((Boolean) message);
|
audioSink.setSkipSilenceEnabled((Boolean) message);
|
||||||
break;
|
break;
|
||||||
@ -938,4 +946,16 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
|||||||
eventDispatcher.audioSinkError(audioSinkError);
|
eventDispatcher.audioSinkError(audioSinkError);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RequiresApi(23)
|
||||||
|
private static final class Api23 {
|
||||||
|
private Api23() {}
|
||||||
|
|
||||||
|
@DoNotInline
|
||||||
|
public static void setAudioSinkPreferredDevice(
|
||||||
|
AudioSink audioSink, @Nullable Object messagePayload) {
|
||||||
|
@Nullable AudioDeviceInfo audioDeviceInfo = (AudioDeviceInfo) messagePayload;
|
||||||
|
audioSink.setPreferredDevice(audioDeviceInfo);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.exoplayer2.testutil;
|
package com.google.android.exoplayer2.testutil;
|
||||||
|
|
||||||
|
import android.media.AudioDeviceInfo;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import com.google.android.exoplayer2.ExoPlaybackException;
|
import com.google.android.exoplayer2.ExoPlaybackException;
|
||||||
@ -234,6 +235,11 @@ public class StubExoPlayer extends StubPlayer implements ExoPlayer {
|
|||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setPreferredAudioDevice(@Nullable AudioDeviceInfo audioDeviceInfo) {
|
||||||
|
throw new UnsupportedOperationException();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSkipSilenceEnabled(boolean skipSilenceEnabled) {
|
public void setSkipSilenceEnabled(boolean skipSilenceEnabled) {
|
||||||
throw new UnsupportedOperationException();
|
throw new UnsupportedOperationException();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user