notify AudioListener about changes of skipSilenceEnabled

This change adds the callback onSkipSilenceEnabledChange to the AudioListener and calls it when changed by the user by calling setPlaybackParameters, or when changed internally by the DefaultAudioSink if the parameters are not applicable. It needs to be plumped through AudioSink, AudioRenderer to SEP which eventually calls the AudioListener.

No changes to the Player interface so far. The getter of skipSilenceEnabled is added to SimpleExoPlayer for completeness, but not yet to the Player interface. The setter is not yet exposed, but implemented as a private method for implementation reasons.

PiperOrigin-RevId: 297590291
This commit is contained in:
bachinger 2020-02-27 15:21:52 +00:00 committed by kim-vde
parent 7c2889c620
commit d69572eb65
10 changed files with 112 additions and 33 deletions

View file

@ -334,6 +334,7 @@ public class SimpleExoPlayer extends BasePlayer
private int audioSessionId;
private AudioAttributes audioAttributes;
private float audioVolume;
private boolean skipSilenceEnabled;
private List<Cue> currentCues;
@Nullable private VideoFrameMetadataListener videoFrameMetadataListener;
@Nullable private CameraMotionListener cameraMotionListener;
@ -929,6 +930,11 @@ public class SimpleExoPlayer extends BasePlayer
}
}
/** Returns whether skipping silences in the audio stream is enabled. */
public boolean isSkipSilenceEnabled() {
return skipSilenceEnabled;
}
/**
* Sets a listener to receive video events, removing all existing listeners.
*
@ -1347,6 +1353,7 @@ public class SimpleExoPlayer extends BasePlayer
@Override
public void setPlaybackParameters(@Nullable PlaybackParameters playbackParameters) {
verifyApplicationThread();
setSkipSilenceEnabled(playbackParameters != null && playbackParameters.skipSilence);
player.setPlaybackParameters(playbackParameters);
}
@ -1659,6 +1666,24 @@ public class SimpleExoPlayer extends BasePlayer
: PLAY_WHEN_READY_CHANGE_REASON_USER_REQUEST;
}
@SuppressWarnings("SuspiciousMethodCalls")
private void setSkipSilenceEnabled(boolean skipSilenceEnabled) {
if (this.skipSilenceEnabled == skipSilenceEnabled) {
return;
}
this.skipSilenceEnabled = skipSilenceEnabled;
for (AudioListener listener : audioListeners) {
// Prevent duplicate notification if a listener is both a AudioRendererEventListener and
// a AudioListener, as they have the same method signature.
if (!audioDebugListeners.contains(listener)) {
listener.onSkipSilenceEnabledChanged(skipSilenceEnabled);
}
}
for (AudioRendererEventListener listener : audioDebugListeners) {
listener.onSkipSilenceEnabledChanged(skipSilenceEnabled);
}
}
private final class ComponentListener
implements VideoRendererEventListener,
AudioRendererEventListener,
@ -1814,6 +1839,11 @@ public class SimpleExoPlayer extends BasePlayer
audioSessionId = C.AUDIO_SESSION_ID_UNSET;
}
@Override
public void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {
setSkipSilenceEnabled(skipSilenceEnabled);
}
// TextOutput implementation
@Override

View file

@ -220,6 +220,14 @@ public class AnalyticsCollector
}
}
@Override
public void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {
EventTime eventTime = generateReadingMediaPeriodEventTime();
for (AnalyticsListener listener : listeners) {
listener.onSkipSilenceEnabledChanged(eventTime, skipSilenceEnabled);
}
}
@Override
public void onVolumeChanged(float audioVolume) {
EventTime eventTime = generateReadingMediaPeriodEventTime();

View file

@ -450,6 +450,14 @@ public interface AnalyticsListener {
default void onAudioUnderrun(
EventTime eventTime, int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {}
/**
* Called when skipping silences is enabled or disabled in the audio stream.
*
* @param eventTime The event time.
* @param skipSilenceEnabled Whether skipping silences in the audio stream is enabled.
*/
default void onSkipSilenceEnabledChanged(EventTime eventTime, boolean skipSilenceEnabled) {}
/**
* Called after video frames have been dropped.
*

View file

@ -38,4 +38,11 @@ public interface AudioListener {
* @param volume The new volume, with 0 being silence and 1 being unity gain.
*/
default void onVolumeChanged(float volume) {}
/**
* Called when skipping silences is enabled or disabled in the audio stream.
*
* @param skipSilenceEnabled Whether skipping silences in the audio stream is enabled.
*/
default void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {}
}

View file

@ -85,8 +85,13 @@ public interface AudioRendererEventListener {
default void onAudioDisabled(DecoderCounters counters) {}
/**
* Dispatches events to a {@link AudioRendererEventListener}.
* Called when skipping silences is enabled or disabled in the audio stream.
*
* @param skipSilenceEnabled Whether skipping silences in the audio stream is enabled.
*/
default void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {}
/** Dispatches events to a {@link AudioRendererEventListener}. */
final class EventDispatcher {
@Nullable private final Handler handler;
@ -170,5 +175,12 @@ public interface AudioRendererEventListener {
handler.post(() -> castNonNull(listener).onAudioSessionId(audioSessionId));
}
}
/** Invokes {@link AudioRendererEventListener#onSkipSilenceEnabledChanged(boolean)}. */
public void skipSilenceEnabledChanged(final boolean skipSilenceEnabled) {
if (handler != null) {
handler.post(() -> castNonNull(listener).onSkipSilenceEnabledChanged(skipSilenceEnabled));
}
}
}
}

View file

@ -84,6 +84,12 @@ public interface AudioSink {
*/
void onUnderrun(int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs);
/**
* Called when skipping silences is enabled or disabled.
*
* @param skipSilenceEnabled Whether skipping silences is enabled.
*/
void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled);
}
/**

View file

@ -884,9 +884,6 @@ public final class DefaultAudioSink implements AudioSink {
@Override
public void setPlaybackSpeed(float playbackSpeed) {
if (configuration != null && !configuration.canApplyPlaybackParameters) {
playbackSpeed = DEFAULT_PLAYBACK_SPEED;
}
setPlaybackSpeedAndSkipSilence(playbackSpeed, getSkipSilenceEnabled());
}
@ -897,9 +894,6 @@ public final class DefaultAudioSink implements AudioSink {
@Override
public void setSkipSilenceEnabled(boolean skipSilenceEnabled) {
if (configuration != null && !configuration.canApplyPlaybackParameters) {
skipSilenceEnabled = DEFAULT_SKIP_SILENCE;
}
setPlaybackSpeedAndSkipSilence(getPlaybackSpeed(), skipSilenceEnabled);
}
@ -1080,10 +1074,6 @@ public final class DefaultAudioSink implements AudioSink {
}
private void setPlaybackSpeedAndSkipSilence(float playbackSpeed, boolean skipSilence) {
if (configuration != null && !configuration.canApplyPlaybackParameters) {
playbackSpeed = DEFAULT_PLAYBACK_SPEED;
skipSilence = DEFAULT_SKIP_SILENCE;
}
MediaPositionParameters currentMediaPositionParameters = getMediaPositionParameters();
if (playbackSpeed != currentMediaPositionParameters.playbackSpeed
|| skipSilence != currentMediaPositionParameters.skipSilence) {
@ -1119,17 +1109,20 @@ public final class DefaultAudioSink implements AudioSink {
configuration.canApplyPlaybackParameters
? audioProcessorChain.applyPlaybackSpeed(getPlaybackSpeed())
: DEFAULT_PLAYBACK_SPEED;
boolean skipSilence =
boolean skipSilenceEnabled =
configuration.canApplyPlaybackParameters
? audioProcessorChain.applySkipSilenceEnabled(getSkipSilenceEnabled())
: DEFAULT_SKIP_SILENCE;
mediaPositionParametersCheckpoints.add(
new MediaPositionParameters(
playbackSpeed,
skipSilence,
skipSilenceEnabled,
/* mediaTimeUs= */ Math.max(0, presentationTimeUs),
/* audioTrackPositionUs= */ configuration.framesToDurationUs(getWrittenFrames())));
setupAudioProcessors();
if (listener != null) {
listener.onSkipSilenceEnabledChanged(skipSilenceEnabled);
}
}
/**

View file

@ -469,24 +469,25 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
* order to spatialize the audio channels. For this use case, any {@link Virtualizer} instances
* should be released in {@link #onDisabled()} (if not before).
*
* @see AudioSink.Listener#onAudioSessionId(int)
* <p>See {@link AudioSink.Listener#onAudioSessionId(int)}.
*/
protected void onAudioSessionId(int audioSessionId) {
// Do nothing.
}
/**
* @see AudioSink.Listener#onPositionDiscontinuity()
*/
/** See {@link AudioSink.Listener#onPositionDiscontinuity()}. */
protected void onAudioTrackPositionDiscontinuity() {
// Do nothing.
}
/**
* @see AudioSink.Listener#onUnderrun(int, long, long)
*/
protected void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs,
long elapsedSinceLastFeedMs) {
/** See {@link AudioSink.Listener#onUnderrun(int, long, long)}. */
protected void onAudioTrackUnderrun(
int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {
// Do nothing.
}
/** See {@link AudioSink.Listener#onSkipSilenceEnabledChanged(boolean)}. */
protected void onAudioTrackSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {
// Do nothing.
}
@ -843,6 +844,10 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
onAudioTrackUnderrun(bufferSize, bufferSizeMs, elapsedSinceLastFeedMs);
}
@Override
public void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {
eventDispatcher.skipSilenceEnabledChanged(skipSilenceEnabled);
onAudioTrackSkipSilenceEnabledChanged(skipSilenceEnabled);
}
}
}

View file

@ -270,24 +270,25 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
* order to spatialize the audio channels. For this use case, any {@link Virtualizer} instances
* should be released in {@link #onDisabled()} (if not before).
*
* @see AudioSink.Listener#onAudioSessionId(int)
* <p>See {@link AudioSink.Listener#onAudioSessionId(int)}.
*/
protected void onAudioSessionId(int audioSessionId) {
// Do nothing.
}
/**
* @see AudioSink.Listener#onPositionDiscontinuity()
*/
/** See {@link AudioSink.Listener#onPositionDiscontinuity()}. */
protected void onAudioTrackPositionDiscontinuity() {
// Do nothing.
}
/**
* @see AudioSink.Listener#onUnderrun(int, long, long)
*/
protected void onAudioTrackUnderrun(int bufferSize, long bufferSizeMs,
long elapsedSinceLastFeedMs) {
/** See {@link AudioSink.Listener#onUnderrun(int, long, long)}. */
protected void onAudioTrackUnderrun(
int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) {
// Do nothing.
}
/** See {@link AudioSink.Listener#onSkipSilenceEnabledChanged(boolean)}. */
protected void onAudioTrackSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {
// Do nothing.
}
@ -693,6 +694,10 @@ public abstract class SimpleDecoderAudioRenderer extends BaseRenderer implements
onAudioTrackUnderrun(bufferSize, bufferSizeMs, elapsedSinceLastFeedMs);
}
@Override
public void onSkipSilenceEnabledChanged(boolean skipSilenceEnabled) {
eventDispatcher.skipSilenceEnabledChanged(skipSilenceEnabled);
onAudioTrackSkipSilenceEnabledChanged(skipSilenceEnabled);
}
}
}

View file

@ -319,6 +319,11 @@ public class EventLogger implements AnalyticsListener {
+ audioAttributes.allowedCapturePolicy);
}
@Override
public void onSkipSilenceEnabledChanged(EventTime eventTime, boolean skipSilenceEnabled) {
logd(eventTime, "skipSilenceEnabled", Boolean.toString(skipSilenceEnabled));
}
@Override
public void onVolumeChanged(EventTime eventTime, float volume) {
logd(eventTime, "volume", Float.toString(volume));