mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +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
5b3efa8ad9
commit
a069ebda47
@ -27,6 +27,8 @@
|
|||||||
* Make `AudioTrackBufferSizeProvider` a public interface.
|
* Make `AudioTrackBufferSizeProvider` a public interface.
|
||||||
* Add `WrappingMediaSource` to simplify wrapping a single `MediaSource`
|
* Add `WrappingMediaSource` to simplify wrapping a single `MediaSource`
|
||||||
([#7279](https://github.com/google/ExoPlayer/issues/7279)).
|
([#7279](https://github.com/google/ExoPlayer/issues/7279)).
|
||||||
|
* Add `ExoPlayer.setPreferredAudioDevice` to set the preferred audio
|
||||||
|
output device ([#135](https://github.com/androidx/media/issues/135)).
|
||||||
* Metadata:
|
* Metadata:
|
||||||
* `MetadataRenderer` can now be configured to render metadata as soon as
|
* `MetadataRenderer` can now be configured to render metadata as soon as
|
||||||
they are available. Create an instance with
|
they are available. Create an instance with
|
||||||
|
@ -20,6 +20,7 @@ import static androidx.media3.common.util.Assertions.checkNotNull;
|
|||||||
import static androidx.media3.common.util.Assertions.checkState;
|
import static androidx.media3.common.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 androidx.media3.common.AudioAttributes;
|
import androidx.media3.common.AudioAttributes;
|
||||||
import androidx.media3.common.AuxEffectInfo;
|
import androidx.media3.common.AuxEffectInfo;
|
||||||
@ -1473,6 +1475,16 @@ public interface ExoPlayer extends Player {
|
|||||||
@UnstableApi
|
@UnstableApi
|
||||||
void clearAuxEffectInfo();
|
void clearAuxEffectInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the preferred audio device.
|
||||||
|
*
|
||||||
|
* @param audioDeviceInfo The preferred {@linkplain AudioDeviceInfo audio device}, or null to
|
||||||
|
* restore the default.
|
||||||
|
*/
|
||||||
|
@UnstableApi
|
||||||
|
@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.
|
||||||
*
|
*
|
||||||
|
@ -26,6 +26,7 @@ import static androidx.media3.exoplayer.Renderer.MSG_SET_AUDIO_SESSION_ID;
|
|||||||
import static androidx.media3.exoplayer.Renderer.MSG_SET_AUX_EFFECT_INFO;
|
import static androidx.media3.exoplayer.Renderer.MSG_SET_AUX_EFFECT_INFO;
|
||||||
import static androidx.media3.exoplayer.Renderer.MSG_SET_CAMERA_MOTION_LISTENER;
|
import static androidx.media3.exoplayer.Renderer.MSG_SET_CAMERA_MOTION_LISTENER;
|
||||||
import static androidx.media3.exoplayer.Renderer.MSG_SET_CHANGE_FRAME_RATE_STRATEGY;
|
import static androidx.media3.exoplayer.Renderer.MSG_SET_CHANGE_FRAME_RATE_STRATEGY;
|
||||||
|
import static androidx.media3.exoplayer.Renderer.MSG_SET_PREFERRED_AUDIO_DEVICE;
|
||||||
import static androidx.media3.exoplayer.Renderer.MSG_SET_SCALING_MODE;
|
import static androidx.media3.exoplayer.Renderer.MSG_SET_SCALING_MODE;
|
||||||
import static androidx.media3.exoplayer.Renderer.MSG_SET_SKIP_SILENCE_ENABLED;
|
import static androidx.media3.exoplayer.Renderer.MSG_SET_SKIP_SILENCE_ENABLED;
|
||||||
import static androidx.media3.exoplayer.Renderer.MSG_SET_VIDEO_FRAME_METADATA_LISTENER;
|
import static androidx.media3.exoplayer.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;
|
||||||
@ -1442,6 +1444,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();
|
||||||
|
@ -198,6 +198,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 androidx.media3.exoplayer;
|
package androidx.media3.exoplayer;
|
||||||
|
|
||||||
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 androidx.media3.common.AudioAttributes;
|
import androidx.media3.common.AudioAttributes;
|
||||||
import androidx.media3.common.AuxEffectInfo;
|
import androidx.media3.common.AuxEffectInfo;
|
||||||
@ -628,6 +630,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 androidx.media3.exoplayer.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 androidx.media3.common.AudioAttributes;
|
import androidx.media3.common.AudioAttributes;
|
||||||
import androidx.media3.common.AuxEffectInfo;
|
import androidx.media3.common.AuxEffectInfo;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
@ -420,6 +422,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 androidx.media3.common.AudioAttributes;
|
import androidx.media3.common.AudioAttributes;
|
||||||
import androidx.media3.common.AuxEffectInfo;
|
import androidx.media3.common.AuxEffectInfo;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
@ -623,6 +626,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:
|
||||||
@ -795,4 +803,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;
|
||||||
@ -565,6 +566,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;
|
||||||
@ -913,6 +915,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;
|
||||||
@ -1413,6 +1418,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);
|
||||||
@ -2309,6 +2324,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 androidx.media3.exoplayer.audio;
|
package androidx.media3.exoplayer.audio;
|
||||||
|
|
||||||
|
import android.media.AudioDeviceInfo;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.media3.common.AudioAttributes;
|
import androidx.media3.common.AudioAttributes;
|
||||||
import androidx.media3.common.AuxEffectInfo;
|
import androidx.media3.common.AuxEffectInfo;
|
||||||
import androidx.media3.common.Format;
|
import androidx.media3.common.Format;
|
||||||
@ -138,6 +140,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 androidx.media3.common.AudioAttributes;
|
import androidx.media3.common.AudioAttributes;
|
||||||
import androidx.media3.common.AuxEffectInfo;
|
import androidx.media3.common.AuxEffectInfo;
|
||||||
import androidx.media3.common.C;
|
import androidx.media3.common.C;
|
||||||
@ -749,6 +752,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;
|
||||||
@ -942,4 +950,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 androidx.media3.test.utils;
|
package androidx.media3.test.utils;
|
||||||
|
|
||||||
|
import android.media.AudioDeviceInfo;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.media3.common.AudioAttributes;
|
import androidx.media3.common.AudioAttributes;
|
||||||
@ -236,6 +237,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