Description
Hi.
I’m using Exoplayer in my streaming app for Android TV, I have Nvidia Shield Pro 2019 as testing device, Android TV v.9 installed.
After upgrading Exoplayer library to the latest version 2.13.0 I’ve noticed that HLS streams are not playing smoothly while same streams with same settings on the same device played smoothly with 2.12.3 and before.
I’ve tried different streams from different sources, they all behave in a similar way.
Try this stream for example - there is a marquee below, in 2.12.3 and before it was flawlessly smooth, in 2.13.0 it stutters every second or about that.
SurfaceView is used to show video, TV screen refresh is adjusted to video frame rate.
Studied Release Notes, documentation and sample app, cannot find what’s wrong, can you please help?
Player initialization code is below:
public static SimpleExoPlayer initPlayer(Context context, SimpleExoPlayer player, final String videoUrl,
View videoView, final Player.EventListener listener,
final boolean tunneled, final boolean silent, final boolean forceMaxBit) {
if (null != player) {
player.release();
}
DataSource.Factory dataSourceFactory = new DefaultHttpDataSource.Factory()
.setUserAgent(PubVar.usrAgent)
.setConnectTimeoutMs(10000)
.setReadTimeoutMs(10000)
.setAllowCrossProtocolRedirects(true);
DefaultRenderersFactory renderersFactory = new DefaultRenderersFactory(context).setEnableDecoderFallback(true);
renderersFactory.setExtensionRendererMode(DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF);
LoadControl loadControl = new DefaultLoadControl.Builder()
.setBufferDurationsMs(PubVar.minBuffer, PubVar.maxBuffer, 2000, 5000)
.setTargetBufferBytes(C.LENGTH_UNSET)
.setPrioritizeTimeOverSizeThresholds(false)
.build();
DefaultTrackSelector trackSelector = new DefaultTrackSelector(context, new AdaptiveTrackSelection.Factory());
DefaultTrackSelector.ParametersBuilder tsParamsBuilder = trackSelector.buildUponParameters()
.setAllowAudioMixedChannelCountAdaptiveness(true)
.setAllowAudioMixedSampleRateAdaptiveness(true)
.setAllowAudioMixedMimeTypeAdaptiveness(true)
.setAllowVideoMixedMimeTypeAdaptiveness(true)
.setAllowVideoNonSeamlessAdaptiveness(true)
.setExceedAudioConstraintsIfNecessary(true)
.setExceedVideoConstraintsIfNecessary(true)
.setExceedRendererCapabilitiesIfNecessary(true)
.setForceHighestSupportedBitrate(PubVar.forceMaxBitrate || forceMaxBit)
.setTunnelingEnabled(tunneled && PubVar.syncMode.equalsIgnoreCase("tunnel"));
trackSelector.setParameters(tsParamsBuilder);
final Uri vidUri = Uri.parse(videoUrl);
@C.ContentType int contentType = Util.inferContentType(vidUri);
if (contentType == C.TYPE_OTHER && videoUrl.toLowerCase().contains("m3u8"))
contentType = C.TYPE_HLS;
MediaSourceFactory mediaSourceFactory;
if (contentType == C.TYPE_HLS) { // init HLS
HlsExtractorFactory hlsFactory = new DefaultHlsExtractorFactory();
mediaSourceFactory = new HlsMediaSource.Factory(dataSourceFactory)
.setAllowChunklessPreparation(true)
.setExtractorFactory(hlsFactory);
} else {
if (contentType == C.TYPE_DASH) { // init DASH
mediaSourceFactory = new DashMediaSource.Factory(dataSourceFactory);
} else {
if (contentType == C.TYPE_SS) { // init SmoothStream
mediaSourceFactory = new SsMediaSource.Factory(dataSourceFactory);
} else { // init Extractors or Progressive
ExtractorsFactory extractorsFactory = new DefaultExtractorsFactory()
.setTsExtractorFlags(FLAG_ALLOW_NON_IDR_KEYFRAMES
| FLAG_DETECT_ACCESS_UNITS
| FLAG_IGNORE_SPLICE_INFO_STREAM
| FLAG_ENABLE_HDMV_DTS_AUDIO_STREAMS
)
.setMp4ExtractorFlags(Mp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS)
.setFragmentedMp4ExtractorFlags(
FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_EDIT_LISTS
| FragmentedMp4Extractor.FLAG_WORKAROUND_IGNORE_TFDT_BOX
| FragmentedMp4Extractor.FLAG_WORKAROUND_EVERY_VIDEO_FRAME_IS_SYNC_FRAME
| FragmentedMp4Extractor.FLAG_ENABLE_EMSG_TRACK
)
.setTsExtractorMode(TsExtractor.MODE_MULTI_PMT);
trackSelector = new DefaultTrackSelector(context);
mediaSourceFactory = new ProgressiveMediaSource.Factory(dataSourceFactory, extractorsFactory)
.setContinueLoadingCheckIntervalBytes(ProgressiveMediaSource.DEFAULT_LOADING_CHECK_INTERVAL_BYTES / 2);
}
}
}
player = new SimpleExoPlayer.Builder(context, renderersFactory)
.setMediaSourceFactory(mediaSourceFactory)
.setTrackSelector(trackSelector)
.setLoadControl(loadControl)
.setUseLazyPreparation(true)
.build();
if (null != videoView) {
if (videoView instanceof SurfaceView) {
player.clearVideoSurfaceView(((SurfaceView) videoView));
player.setVideoSurfaceView((SurfaceView) videoView);
}
if (videoView instanceof TextureView) {
player.setVideoTextureView((TextureView) videoView);
}
}
if (null != listener) player.addListener(listener);
player.setVideoScalingMode(C.VIDEO_SCALING_MODE_SCALE_TO_FIT);
if (silent) player.setVolume(0);
player.setMediaItem(MediaItem.fromUri(vidUri), false);
player.setPlayWhenReady(true);
return player;
}
Activity