1
0
Fork 0
mirror of https://github.com/TeamNewPipe/NewPipe.git synced 2025-10-03 09:49:21 +02:00

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.
This commit is contained in:
Artem Shtefan 2025-08-12 20:38:44 +03:00
parent 9bc8139b8c
commit 4e88b7cd50
5 changed files with 77 additions and 8 deletions

View file

@ -72,6 +72,7 @@ import com.google.android.exoplayer2.PlaybackParameters;
import com.google.android.exoplayer2.Player.PositionInfo;
import com.google.android.exoplayer2.Timeline;
import com.google.android.exoplayer2.Tracks;
import com.google.android.exoplayer2.audio.SilenceSkippingAudioProcessor;
import com.google.android.exoplayer2.ext.mediasession.MediaSessionConnector;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.text.CueGroup;
@ -293,10 +294,20 @@ public final class Player implements PlaybackListener, Listener {
new DefaultBandwidthMeter.Builder(context).build());
loadController = new LoadController();
renderFactory = prefs.getBoolean(
context.getString(
R.string.always_use_exoplayer_set_output_surface_workaround_key), false)
? new CustomRenderersFactory(context) : new DefaultRenderersFactory(context);
final boolean alwaysUseExoplayerSetOutputSurfaceWorkaround = prefs.getBoolean(
context.getString(R.string.always_use_exoplayer_set_output_surface_workaround_key),
false);
final int maxSilenceDurationMillis = prefs.getInt(
context.getString(R.string.max_silence_duration_key),
Integer.parseInt(context.getString(R.string.max_silence_duration_value)));
final SilenceSkippingAudioProcessor silenceSkippingAudioProcessor =
new SilenceSkippingAudioProcessor(
MILLISECONDS.toMicros(maxSilenceDurationMillis),
MILLISECONDS.toMicros(maxSilenceDurationMillis),
SilenceSkippingAudioProcessor.DEFAULT_SILENCE_THRESHOLD_LEVEL);
renderFactory = new CustomRenderersFactory(
context, alwaysUseExoplayerSetOutputSurfaceWorkaround,
silenceSkippingAudioProcessor);
renderFactory.setEnableDecoderFallback(
prefs.getBoolean(

View file

@ -5,6 +5,12 @@ import android.os.Handler;
import com.google.android.exoplayer2.DefaultRenderersFactory;
import com.google.android.exoplayer2.Renderer;
import com.google.android.exoplayer2.audio.AudioCapabilities;
import com.google.android.exoplayer2.audio.AudioProcessor;
import com.google.android.exoplayer2.audio.AudioSink;
import com.google.android.exoplayer2.audio.DefaultAudioSink;
import com.google.android.exoplayer2.audio.SilenceSkippingAudioProcessor;
import com.google.android.exoplayer2.audio.SonicAudioProcessor;
import com.google.android.exoplayer2.mediacodec.MediaCodecSelector;
import com.google.android.exoplayer2.video.VideoRendererEventListener;
@ -22,8 +28,17 @@ import java.util.ArrayList;
*/
public final class CustomRenderersFactory extends DefaultRenderersFactory {
public CustomRenderersFactory(final Context context) {
private final boolean alwaysUseExoplayerSetOutputSurfaceWorkaround;
private final SilenceSkippingAudioProcessor silenceSkippingAudioProcessor;
public CustomRenderersFactory(
final Context context,
final boolean alwaysUseExoplayerSetOutputSurfaceWorkaround,
final SilenceSkippingAudioProcessor silenceSkippingAudioProcessor) {
super(context);
this.alwaysUseExoplayerSetOutputSurfaceWorkaround =
alwaysUseExoplayerSetOutputSurfaceWorkaround;
this.silenceSkippingAudioProcessor = silenceSkippingAudioProcessor;
}
@SuppressWarnings("checkstyle:ParameterNumber")
@ -36,8 +51,35 @@ public final class CustomRenderersFactory extends DefaultRenderersFactory {
final VideoRendererEventListener eventListener,
final long allowedVideoJoiningTimeMs,
final ArrayList<Renderer> out) {
out.add(new CustomMediaCodecVideoRenderer(context, getCodecAdapterFactory(),
mediaCodecSelector, allowedVideoJoiningTimeMs, enableDecoderFallback, eventHandler,
eventListener, MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY));
if (alwaysUseExoplayerSetOutputSurfaceWorkaround) {
out.add(new CustomMediaCodecVideoRenderer(context, getCodecAdapterFactory(),
mediaCodecSelector, allowedVideoJoiningTimeMs, enableDecoderFallback,
eventHandler, eventListener, MAX_DROPPED_VIDEO_FRAME_COUNT_TO_NOTIFY));
} else {
super.buildVideoRenderers(context, extensionRendererMode, mediaCodecSelector,
enableDecoderFallback, eventHandler, eventListener, allowedVideoJoiningTimeMs,
out);
}
}
@Override
protected AudioSink buildAudioSink(
final Context context,
final boolean enableFloatOutput,
final boolean enableAudioTrackPlaybackParams,
final boolean enableOffload) {
return new DefaultAudioSink.Builder()
.setAudioCapabilities(AudioCapabilities.getCapabilities(context))
.setEnableFloatOutput(enableFloatOutput)
.setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams)
.setOffloadMode(
enableOffload
? DefaultAudioSink.OFFLOAD_MODE_ENABLED_GAPLESS_REQUIRED
: DefaultAudioSink.OFFLOAD_MODE_DISABLED)
.setAudioProcessorChain(new DefaultAudioSink.DefaultAudioProcessorChain(
new AudioProcessor[]{}, silenceSkippingAudioProcessor,
new SonicAudioProcessor()
))
.build();
}
}

View file

@ -123,6 +123,10 @@
<string name="default_popup_resolution_key">default_popup_resolution</string>
<string name="default_popup_resolution_value">480p</string>
<string name="best_resolution_key">best_resolution</string>
<string name="max_silence_duration_value">1000</string>
<string name="max_silence_duration_min">100</string>
<string name="max_silence_duration_max">5000</string>
<string name="max_silence_duration_key">max_silence_duration</string>
<string-array name="high_resolution_list_values">
<item>2160p</item>

View file

@ -50,6 +50,7 @@
<string name="default_popup_resolution_title">Default popup resolution</string>
<string name="show_higher_resolutions_title">Show higher resolutions</string>
<string name="show_higher_resolutions_summary">Only some devices can play 2K/4K videos</string>
<string name="max_silence_duration_title">Maximal silence duration in milliseconds that remains when &quot;fast forwarding during silence&quot; is enabled</string>
<string name="play_with_kodi_title">Play with Kodi</string>
<string name="kore_not_found">Install missing Kore app\?</string>
<string name="show_play_with_kodi_title">Show \"Play with Kodi\" option</string>

View file

@ -77,6 +77,17 @@
app:singleLineTitle="false"
app:iconSpaceReserved="false"/>
<SeekBarPreference
android:defaultValue="@string/max_silence_duration_value"
app:min="@string/max_silence_duration_min"
android:max="@string/max_silence_duration_max"
android:key="@string/max_silence_duration_key"
android:title="@string/max_silence_duration_title"
app:singleLineTitle="false"
app:iconSpaceReserved="false"
app:useSimpleSummaryProvider="true"
app:showSeekBarValue="true" />
<PreferenceScreen
android:fragment="org.schabi.newpipe.settings.ExoPlayerSettingsFragment"
android:key="@string/exoplayer_settings_key"