From f3bd8eab9503d8bef9a31c95eb390fd6ea883e00 Mon Sep 17 00:00:00 2001 From: peerless2012 Date: Mon, 9 Mar 2026 15:15:12 +0800 Subject: [PATCH] Add full support for ass/ssa. --- README.md | 2 +- app/build.gradle | 5 +++++ .../java/com/brouken/player/PlayerActivity.java | 16 +++++++++++++++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 33411171..82aa62bf 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ It properly syncs audio with video track when using Bluetooth earphones/speaker. * **Video**: H.263, H.264 AVC (Baseline Profile; Main Profile on Android 6+), H.265 HEVC, MPEG-4 SP, VP8, VP9, AV1 * **Containers**: MP4, MOV, WebM, MKV, Ogg, MPEG-TS, MPEG-PS, FLV, AVI (🚧) * **Streaming**: DASH, HLS, SmoothStreaming, RTSP - * **Subtitles**: SRT, SSA/ASS ([limited styling](https://github.com/google/ExoPlayer/issues/8435)), TTML, VTT, DVB + * **Subtitles**: SRT, SSA/ASS ([powered by libass-android](https://github.com/peerless2012/libass-android)), TTML, VTT, DVB HDR (HDR10+ and Dolby Vision) video playback on compatible/supported hardware. diff --git a/app/build.gradle b/app/build.gradle index 5deae424..3cccdeec 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -114,6 +114,11 @@ dependencies { implementation 'androidx.preference:preference:1.2.1' implementation 'com.squareup.okhttp3:okhttp:5.3.2' implementation 'com.sigpwned:chardet4j:77.1.0' + implementation('io.github.peerless2012:ass-media:0.4.0') { + exclude group: "androidx.media3", module: "media3-ui" + exclude group: "androidx.media3", module: "media3-extractor" + exclude group: "androidx.media3", module: "media3-exoplayer" + } implementation project(path: ':doubletapplayerview') implementation project(path: ':android-file-chooser') implementation fileTree(dir: "libs", include: ["lib-*.aar"]) diff --git a/app/src/main/java/com/brouken/player/PlayerActivity.java b/app/src/main/java/com/brouken/player/PlayerActivity.java index 1e2a7f18..f60f6261 100644 --- a/app/src/main/java/com/brouken/player/PlayerActivity.java +++ b/app/src/main/java/com/brouken/player/PlayerActivity.java @@ -75,6 +75,8 @@ import androidx.media3.common.TrackSelectionOverride; import androidx.media3.common.TrackSelectionParameters; import androidx.media3.common.Tracks; +import androidx.media3.datasource.DataSource; +import androidx.media3.datasource.DefaultDataSource; import androidx.media3.datasource.DefaultHttpDataSource; import androidx.media3.exoplayer.DefaultRenderersFactory; import androidx.media3.exoplayer.ExoPlaybackException; @@ -111,6 +113,9 @@ import java.util.Objects; import java.util.concurrent.TimeUnit; +import io.github.peerless2012.ass.media.kt.AssPlayerKt; +import io.github.peerless2012.ass.media.type.AssRenderType; + public class PlayerActivity extends Activity { private PlayerListener playerListener; @@ -1231,6 +1236,7 @@ public void initializePlayer() { .setTrackSelector(trackSelector) .setMediaSourceFactory(new DefaultMediaSourceFactory(this, extractorsFactory)); + DataSource.Factory dataSourceFactory = null; if (haveMedia && isNetworkUri) { if (mPrefs.mediaUri.getScheme().toLowerCase().startsWith("http")) { HashMap headers = new HashMap<>(); @@ -1240,11 +1246,19 @@ public void initializePlayer() { DefaultHttpDataSource.Factory defaultHttpDataSourceFactory = new DefaultHttpDataSource.Factory(); defaultHttpDataSourceFactory.setDefaultRequestProperties(headers); playerBuilder.setMediaSourceFactory(new DefaultMediaSourceFactory(defaultHttpDataSourceFactory, extractorsFactory)); + dataSourceFactory = defaultHttpDataSourceFactory; } } } - player = playerBuilder.build(); + player = AssPlayerKt.buildWithAssSupport( + playerBuilder, + this, + AssRenderType.OVERLAY_OPEN_GL, + playerView.getSubtitleView(), + dataSourceFactory != null? dataSourceFactory : new DefaultDataSource.Factory(this), + extractorsFactory, + renderersFactory); AudioAttributes audioAttributes = new AudioAttributes.Builder() .setUsage(C.USAGE_MEDIA)