diff --git a/library/src/main/java/com/google/android/exoplayer/MediaCodecAudioTrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/MediaCodecAudioTrackRenderer.java index 2a4e3e2b09..c49227e6d4 100644 --- a/library/src/main/java/com/google/android/exoplayer/MediaCodecAudioTrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/MediaCodecAudioTrackRenderer.java @@ -22,6 +22,7 @@ import com.google.android.exoplayer.drm.DrmSessionManager; import com.google.android.exoplayer.util.MimeTypes; import android.annotation.TargetApi; +import android.media.AudioManager; import android.media.MediaCodec; import android.media.audiofx.Virtualizer; import android.os.Handler; @@ -89,7 +90,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem * content is not required. * @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions. * For example a media file may start with a short clear region so as to allow playback to - * begin in parallel with key acquisision. This parameter specifies whether the renderer is + * begin in parallel with key acquisition. This parameter specifies whether the renderer is * permitted to play clear regions of encrypted media files before {@code drmSessionManager} * has obtained the keys necessary to decrypt encrypted regions of the media. */ @@ -115,7 +116,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem * content is not required. * @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions. * For example a media file may start with a short clear region so as to allow playback to - * begin in parallel with key acquisision. This parameter specifies whether the renderer is + * begin in parallel with key acquisition. This parameter specifies whether the renderer is * permitted to play clear regions of encrypted media files before {@code drmSessionManager} * has obtained the keys necessary to decrypt encrypted regions of the media. * @param eventHandler A handler to use when delivering events to {@code eventListener}. May be @@ -134,7 +135,7 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem * content is not required. * @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions. * For example a media file may start with a short clear region so as to allow playback to - * begin in parallel with key acquisision. This parameter specifies whether the renderer is + * begin in parallel with key acquisition. This parameter specifies whether the renderer is * permitted to play clear regions of encrypted media files before {@code drmSessionManager} * has obtained the keys necessary to decrypt encrypted regions of the media. * @param eventHandler A handler to use when delivering events to {@code eventListener}. May be @@ -146,10 +147,33 @@ public class MediaCodecAudioTrackRenderer extends MediaCodecTrackRenderer implem public MediaCodecAudioTrackRenderer(SampleSource source, DrmSessionManager drmSessionManager, boolean playClearSamplesWithoutKeys, Handler eventHandler, EventListener eventListener, AudioCapabilities audioCapabilities) { + this(source, drmSessionManager, playClearSamplesWithoutKeys, eventHandler, eventListener, + audioCapabilities, AudioManager.STREAM_MUSIC); + } + + /** + * @param source The upstream source from which the renderer obtains samples. + * @param drmSessionManager For use with encrypted content. May be null if support for encrypted + * content is not required. + * @param playClearSamplesWithoutKeys Encrypted media may contain clear (un-encrypted) regions. + * For example a media file may start with a short clear region so as to allow playback to + * begin in parallel with key acquisition. This parameter specifies whether the renderer is + * permitted to play clear regions of encrypted media files before {@code drmSessionManager} + * has obtained the keys necessary to decrypt encrypted regions of the media. + * @param eventHandler A handler to use when delivering events to {@code eventListener}. May be + * null if delivery of events is not required. + * @param eventListener A listener of events. May be null if delivery of events is not required. + * @param audioCapabilities The audio capabilities for playback on this device. May be null if the + * default capabilities (no encoded audio passthrough support) should be assumed. + * @param streamType The type of audio stream for the {@link AudioTrack}. + */ + public MediaCodecAudioTrackRenderer(SampleSource source, DrmSessionManager drmSessionManager, + boolean playClearSamplesWithoutKeys, Handler eventHandler, EventListener eventListener, + AudioCapabilities audioCapabilities, int streamType) { super(source, drmSessionManager, playClearSamplesWithoutKeys, eventHandler, eventListener); this.eventListener = eventListener; this.audioSessionId = AudioTrack.SESSION_ID_NOT_SET; - this.audioTrack = new AudioTrack(audioCapabilities); + this.audioTrack = new AudioTrack(audioCapabilities, streamType); } @Override diff --git a/library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java b/library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java index ba76789394..ee3a9fb6b8 100644 --- a/library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java +++ b/library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java @@ -165,6 +165,7 @@ public final class AudioTrack { public static boolean failOnSpuriousAudioTimestamp = false; private final AudioCapabilities audioCapabilities; + private final int streamType; private final ConditionVariable releasingConditionVariable; private final long[] playheadOffsets; private final AudioTrackUtil audioTrackUtil; @@ -208,16 +209,18 @@ public final class AudioTrack { * Creates an audio track with default audio capabilities (no encoded audio passthrough support). */ public AudioTrack() { - this(null); + this(null, AudioManager.STREAM_MUSIC); } /** - * Creates an audio track using the specified audio capabilities. + * Creates an audio track using the specified audio capabilities and stream type. * * @param audioCapabilities The current audio playback capabilities. + * @param streamType The type of audio stream for the underlying {@link android.media.AudioTrack}. */ - public AudioTrack(AudioCapabilities audioCapabilities) { + public AudioTrack(AudioCapabilities audioCapabilities, int streamType) { this.audioCapabilities = audioCapabilities; + this.streamType = streamType; releasingConditionVariable = new ConditionVariable(true); if (Util.SDK_INT >= 18) { try { @@ -326,19 +329,19 @@ public final class AudioTrack { releasingConditionVariable.block(); if (sessionId == SESSION_ID_NOT_SET) { - audioTrack = new android.media.AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, - channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STREAM); + audioTrack = new android.media.AudioTrack(streamType, sampleRate, channelConfig, encoding, + bufferSize, android.media.AudioTrack.MODE_STREAM); } else { // Re-attach to the same audio session. - audioTrack = new android.media.AudioTrack(AudioManager.STREAM_MUSIC, sampleRate, - channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STREAM, sessionId); + audioTrack = new android.media.AudioTrack(streamType, sampleRate, channelConfig, encoding, + bufferSize, android.media.AudioTrack.MODE_STREAM, sessionId); } checkAudioTrackInitialized(); sessionId = audioTrack.getAudioSessionId(); if (enablePreV21AudioSessionWorkaround) { if (Util.SDK_INT < 21) { - // The workaround creates an audio track with a one byte buffer on the same session, and + // The workaround creates an audio track with a two byte buffer on the same session, and // does not release it until this object is released, which keeps the session active. if (keepSessionIdAudioTrack != null && sessionId != keepSessionIdAudioTrack.getAudioSessionId()) { @@ -349,9 +352,8 @@ public final class AudioTrack { int channelConfig = AudioFormat.CHANNEL_OUT_MONO; int encoding = AudioFormat.ENCODING_PCM_16BIT; int bufferSize = 2; // Use a two byte buffer, as it is not actually used for playback. - keepSessionIdAudioTrack = new android.media.AudioTrack(AudioManager.STREAM_MUSIC, - sampleRate, channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STATIC, - sessionId); + keepSessionIdAudioTrack = new android.media.AudioTrack(streamType, sampleRate, + channelConfig, encoding, bufferSize, android.media.AudioTrack.MODE_STATIC, sessionId); } } }