Merge d55d6a1a9b4e7e64da78a45526f60e80a2de2f54 into 35b70c5e9e8d791ae268bac677a3b760b1b4e8bf

This commit is contained in:
a-shtefan 2026-02-20 17:48:11 -08:00 committed by GitHub
commit 7dd0478585
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 81 additions and 10 deletions

View File

@ -73,6 +73,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;
@ -301,10 +302,21 @@ 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 long maxSilenceDurationMicros = MILLISECONDS.toMicros(maxSilenceDurationMillis);
final SilenceSkippingAudioProcessor silenceSkippingAudioProcessor =
new SilenceSkippingAudioProcessor(
maxSilenceDurationMicros,
maxSilenceDurationMicros,
SilenceSkippingAudioProcessor.DEFAULT_SILENCE_THRESHOLD_LEVEL);
renderFactory = new CustomRenderersFactory(
context, alwaysUseExoplayerSetOutputSurfaceWorkaround,
silenceSkippingAudioProcessor);
renderFactory.setEnableDecoderFallback(
prefs.getBoolean(

View File

@ -5,14 +5,21 @@ 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;
import java.util.ArrayList;
/**
* A {@link DefaultRenderersFactory} which only uses {@link CustomMediaCodecVideoRenderer} as an
* implementation of video codec renders.
* A {@link DefaultRenderersFactory} which uses {@link CustomMediaCodecVideoRenderer} as an
* implementation of video codec renders and uses a provided {@link SilenceSkippingAudioProcessor}
* to control silence skipping behavior more precisely.
*
* <p>
* As no ExoPlayer extension is currently used, the reflection code used by ExoPlayer to try to
@ -22,8 +29,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 +52,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">500</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 \"fast forwarding during silence\" 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

@ -37,4 +37,15 @@
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>