From 8823856814c79c80e1533d99f38ad4270e8f1f5c Mon Sep 17 00:00:00 2001 From: "Warren R. Bank" <warren.r.bank@gmail.com> Date: Sun, 1 Dec 2024 16:23:07 -0800 Subject: [PATCH] enable legacy decoding of text captions issue: https://github.com/androidx/media/issues/1516 https://github.com/androidx/media/issues/1644 references: https://github.com/androidx/media/blob/1.5.0/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/text/TextRenderer.java#L289 https://github.com/androidx/media/blob/1.5.0/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/source/MediaSource.java#L117 --- .../exoplayer2/ExoPlayerUtils.java | 1 + .../exoplayer2/PlayerManager.java | 46 +++++++++++++------ .../customizations/MyRenderersFactory.java | 1 + 3 files changed, 35 insertions(+), 13 deletions(-) diff --git a/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/ExoPlayerUtils.java b/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/ExoPlayerUtils.java index 7351967..d5a971e 100644 --- a/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/ExoPlayerUtils.java +++ b/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/ExoPlayerUtils.java @@ -91,6 +91,7 @@ public static synchronized DefaultHttpDataSource.Factory getHttpDataSourceFactor cookieManager.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER); CookieHandler.setDefault(cookieManager); httpDataSourceFactory = new DefaultHttpDataSource.Factory(); + httpDataSourceFactory.setAllowCrossProtocolRedirects(true); if (USER_AGENT != null) { httpDataSourceFactory.setUserAgent(USER_AGENT); diff --git a/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/PlayerManager.java b/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/PlayerManager.java index 35c56dd..a0fd00d 100644 --- a/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/PlayerManager.java +++ b/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/PlayerManager.java @@ -133,6 +133,8 @@ private PlayerManager(Context context) { : 0 ); + extractorsFactory.experimentalSetTextTrackTranscodingEnabled(true); + trackSelector.setParameters( trackSelector.buildUponParameters() .setTunnelingEnabled( @@ -156,10 +158,13 @@ private PlayerManager(Context context) { this.rtmpDataSourceFactory = ExoPlayerUtils.getRtmpDataSourceFactory(); this.downloadTracker = ExoPlayerUtils.getDownloadTracker(context); + MediaSource.Factory msFactory = new DefaultMediaSourceFactory(cacheDataSourceFactory, extractorsFactory); + msFactory.experimentalParseSubtitlesDuringExtraction(false); + ExoPlayer.Builder builder = new ExoPlayer.Builder( context, (RenderersFactory) renderersFactory, - new DefaultMediaSourceFactory(cacheDataSourceFactory, extractorsFactory), + msFactory, trackSelector, loadControl, DefaultBandwidthMeter.getSingletonInstance(context), @@ -1678,45 +1683,60 @@ private MediaSource buildMediaSource(VideoSource sample) { } private MediaSource buildUriMediaSource(VideoSource sample) { - DataSource.Factory factory = (ExternalStorageUtils.isFileUri(sample.uri) || ExternalStorageUtils.isContentUri(sample.uri)) + DataSource.Factory dsFactory = (ExternalStorageUtils.isFileUri(sample.uri) || ExternalStorageUtils.isContentUri(sample.uri)) ? defaultDataSourceFactory : cacheDataSourceFactory; - if (factory == null) + if (dsFactory == null) return null; MediaItem mediaItem = sample.getMediaItem(); + MediaSource.Factory msFactory = null; + switch (sample.uri_mimeType) { case "application/x-mpegURL": case "application/x-mpegurl": - return new HlsMediaSource.Factory(factory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy).createMediaSource(mediaItem); + msFactory = new HlsMediaSource.Factory(dsFactory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy); + break; case "application/dash+xml": - return new DashMediaSource.Factory(factory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy).createMediaSource(mediaItem); + msFactory = new DashMediaSource.Factory(dsFactory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy); + break; case "application/vnd.ms-sstr+xml": - return new SsMediaSource.Factory(factory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy).createMediaSource(mediaItem); + msFactory = new SsMediaSource.Factory(dsFactory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy); + break; case "application/x-rtsp": - return new RtspMediaSource.Factory().createMediaSource(mediaItem); + msFactory = new RtspMediaSource.Factory(); + break; case "application/x-rtmp": - factory = rtmpDataSourceFactory; - return new ProgressiveMediaSource.Factory(factory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy).createMediaSource(mediaItem); + dsFactory = rtmpDataSourceFactory; + msFactory = new ProgressiveMediaSource.Factory(dsFactory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy); + break; default: - return new ProgressiveMediaSource.Factory(factory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy).createMediaSource(mediaItem); + msFactory = new ProgressiveMediaSource.Factory(dsFactory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy); + break; } + + if (msFactory == null) + return null; + + msFactory.experimentalParseSubtitlesDuringExtraction(false); + + return msFactory.createMediaSource(mediaItem); } private ArrayList<MediaSource> buildCaptionMediaSources(MediaSource video) { ArrayList<MediaSource> captions = new ArrayList<MediaSource>(); - DataSource.Factory factory; + DataSource.Factory dsFactory; try { for (MediaItem.SubtitleConfiguration subtitleConfiguration : video.getMediaItem().localConfiguration.subtitleConfigurations) { - factory = ExternalStorageUtils.isFileUri(subtitleConfiguration.uri.toString()) + dsFactory = ExternalStorageUtils.isFileUri(subtitleConfiguration.uri.toString()) ? defaultDataSourceFactory : httpDataSourceFactory; captions.add( - new SingleSampleMediaSource.Factory(factory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy).createMediaSource(subtitleConfiguration, C.TIME_UNSET) + new SingleSampleMediaSource.Factory(dsFactory).setLoadErrorHandlingPolicy(loadErrorHandlingPolicy).createMediaSource(subtitleConfiguration, C.TIME_UNSET) ); } } diff --git a/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/customizations/MyRenderersFactory.java b/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/customizations/MyRenderersFactory.java index 69f8c88..e769312 100644 --- a/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/customizations/MyRenderersFactory.java +++ b/android-studio-project/ExoPlayer-AirPlay-Receiver/src/main/java/com/github/warren_bank/exoplayer_airplay_receiver/exoplayer2/customizations/MyRenderersFactory.java @@ -33,6 +33,7 @@ protected void buildTextRenderers( ArrayList<Renderer> out ) { textRenderer = new MyTextRenderer(output, outputLooper); + textRenderer.experimentalSetLegacyDecodingEnabled(true); out.add(textRenderer); }