Skip to content

Commit 4e88b7c

Browse files
Artem ShtefanArtem Shtefan
authored andcommitted
Improve skipping silences.
ExoPlayer allows controlling silence skipping by adjusting the silence duration that is removed by `SilenceSkippingAudioProcessor`. The default behavior with the default parameters for this component makes it hard to listen to content because it leaves almost no pauses. After this commit it is possible to adjust silence length that remains and shorten only long pauses.
1 parent 9bc8139 commit 4e88b7c

File tree

5 files changed

+77
-8
lines changed

5 files changed

+77
-8
lines changed

app/src/main/java/org/schabi/newpipe/player/Player.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
import com.google.android.exoplayer2.Player.PositionInfo;
7373
import com.google.android.exoplayer2.Timeline;
7474
import com.google.android.exoplayer2.Tracks;
75+
import com.google.android.exoplayer2.audio.SilenceSkippingAudioProcessor;
7576
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
7677
import com.google.android.exoplayer2.source.MediaSource;
7778
import com.google.android.exoplayer2.text.CueGroup;
@@ -293,10 +294,20 @@ public Player(@NonNull final PlayerService service,
293294
new DefaultBandwidthMeter.Builder(context).build());
294295
loadController = new LoadController();
295296

296-
renderFactory = prefs.getBoolean(
297-
context.getString(
298-
R.string.always_use_exoplayer_set_output_surface_workaround_key), false)
299-
? new CustomRenderersFactory(context) : new DefaultRenderersFactory(context);
297+
final boolean alwaysUseExoplayerSetOutputSurfaceWorkaround = prefs.getBoolean(
298+
context.getString(R.string.always_use_exoplayer_set_output_surface_workaround_key),
299+
false);
300+
final int maxSilenceDurationMillis = prefs.getInt(
301+
context.getString(R.string.max_silence_duration_key),
302+
Integer.parseInt(context.getString(R.string.max_silence_duration_value)));
303+
final SilenceSkippingAudioProcessor silenceSkippingAudioProcessor =
304+
new SilenceSkippingAudioProcessor(
305+
MILLISECONDS.toMicros(maxSilenceDurationMillis),
306+
MILLISECONDS.toMicros(maxSilenceDurationMillis),
307+
SilenceSkippingAudioProcessor.DEFAULT_SILENCE_THRESHOLD_LEVEL);
308+
renderFactory = new CustomRenderersFactory(
309+
context, alwaysUseExoplayerSetOutputSurfaceWorkaround,
310+
silenceSkippingAudioProcessor);
300311

301312
renderFactory.setEnableDecoderFallback(
302313
prefs.getBoolean(

app/src/main/java/org/schabi/newpipe/player/helper/CustomRenderersFactory.java

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55

66
import com.google.android.exoplayer2.DefaultRenderersFactory;
77
import com.google.android.exoplayer2.Renderer;
8+
import com.google.android.exoplayer2.audio.AudioCapabilities;
9+
import com.google.android.exoplayer2.audio.AudioProcessor;
10+
import com.google.android.exoplayer2.audio.AudioSink;
11+
import com.google.android.exoplayer2.audio.DefaultAudioSink;
12+
import com.google.android.exoplayer2.audio.SilenceSkippingAudioProcessor;
13+
import com.google.android.exoplayer2.audio.SonicAudioProcessor;
814
import com.google.android.exoplayer2.mediacodec.MediaCodecSelector;
915
import com.google.android.exoplayer2.video.VideoRendererEventListener;
1016

@@ -22,8 +28,17 @@
2228
*/
2329
public final class CustomRenderersFactory extends DefaultRenderersFactory {
2430

25-
public CustomRenderersFactory(final Context context) {
31+
private final boolean alwaysUseExoplayerSetOutputSurfaceWorkaround;
32+
private final SilenceSkippingAudioProcessor silenceSkippingAudioProcessor;
33+
34+
public CustomRenderersFactory(
35+
final Context context,
36+
final boolean alwaysUseExoplayerSetOutputSurfaceWorkaround,
37+
final SilenceSkippingAudioProcessor silenceSkippingAudioProcessor) {
2638
super(context);
39+
this.alwaysUseExoplayerSetOutputSurfaceWorkaround =
40+
alwaysUseExoplayerSetOutputSurfaceWorkaround;
41+
this.silenceSkippingAudioProcessor = silenceSkippingAudioProcessor;
2742
}
2843

2944
@SuppressWarnings("checkstyle:ParameterNumber")
@@ -36,8 +51,35 @@ protected void buildVideoRenderers(final Context context,
3651
final VideoRendererEventListener eventListener,
3752
final long allowedVideoJoiningTimeMs,
3853
final ArrayList<Renderer> out) {
39-
out.add(new CustomMediaCodecVideoRenderer(context, getCodecAdapterFactory(),
40-
mediaCodecSelector, allowedVideoJoiningTimeMs, enableDecoderFallback, eventHandler,
41-
eventListener, MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY));
54+
if (alwaysUseExoplayerSetOutputSurfaceWorkaround) {
55+
out.add(new CustomMediaCodecVideoRenderer(context, getCodecAdapterFactory(),
56+
mediaCodecSelector, allowedVideoJoiningTimeMs, enableDecoderFallback,
57+
eventHandler, eventListener, MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY));
58+
} else {
59+
super.buildVideoRenderers(context, extensionRendererMode, mediaCodecSelector,
60+
enableDecoderFallback, eventHandler, eventListener, allowedVideoJoiningTimeMs,
61+
out);
62+
}
63+
}
64+
65+
@Override
66+
protected AudioSink buildAudioSink(
67+
final Context context,
68+
final boolean enableFloatOutput,
69+
final boolean enableAudioTrackPlaybackParams,
70+
final boolean enableOffload) {
71+
return new DefaultAudioSink.Builder()
72+
.setAudioCapabilities(AudioCapabilities.getCapabilities(context))
73+
.setEnableFloatOutput(enableFloatOutput)
74+
.setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams)
75+
.setOffloadMode(
76+
enableOffload
77+
? DefaultAudioSink.OFFLOAD_MODE_ENABLED_GAPLESS_REQUIRED
78+
: DefaultAudioSink.OFFLOAD_MODE_DISABLED)
79+
.setAudioProcessorChain(new DefaultAudioSink.DefaultAudioProcessorChain(
80+
new AudioProcessor[]{}, silenceSkippingAudioProcessor,
81+
new SonicAudioProcessor()
82+
))
83+
.build();
4284
}
4385
}

app/src/main/res/values/settings_keys.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@
123123
<string name="default_popup_resolution_key">default_popup_resolution</string>
124124
<string name="default_popup_resolution_value">480p</string>
125125
<string name="best_resolution_key">best_resolution</string>
126+
<string name="max_silence_duration_value">1000</string>
127+
<string name="max_silence_duration_min">100</string>
128+
<string name="max_silence_duration_max">5000</string>
129+
<string name="max_silence_duration_key">max_silence_duration</string>
126130

127131
<string-array name="high_resolution_list_values">
128132
<item>2160p</item>

app/src/main/res/values/strings.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
<string name="default_popup_resolution_title">Default popup resolution</string>
5151
<string name="show_higher_resolutions_title">Show higher resolutions</string>
5252
<string name="show_higher_resolutions_summary">Only some devices can play 2K/4K videos</string>
53+
<string name="max_silence_duration_title">Maximal silence duration in milliseconds that remains when &quot;fast forwarding during silence&quot; is enabled</string>
5354
<string name="play_with_kodi_title">Play with Kodi</string>
5455
<string name="kore_not_found">Install missing Kore app\?</string>
5556
<string name="show_play_with_kodi_title">Show \"Play with Kodi\" option</string>

app/src/main/res/xml/video_audio_settings.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,17 @@
7777
app:singleLineTitle="false"
7878
app:iconSpaceReserved="false"/>
7979

80+
<SeekBarPreference
81+
android:defaultValue="@string/max_silence_duration_value"
82+
app:min="@string/max_silence_duration_min"
83+
android:max="@string/max_silence_duration_max"
84+
android:key="@string/max_silence_duration_key"
85+
android:title="@string/max_silence_duration_title"
86+
app:singleLineTitle="false"
87+
app:iconSpaceReserved="false"
88+
app:useSimpleSummaryProvider="true"
89+
app:showSeekBarValue="true" />
90+
8091
<PreferenceScreen
8192
android:fragment="org.schabi.newpipe.settings.ExoPlayerSettingsFragment"
8293
android:key="@string/exoplayer_settings_key"

0 commit comments

Comments
 (0)