[feat] improve subtitle track selection and integrate the event synchronization logic related to nowPlaying (by @LLLLZD)

This commit is contained in:
Yuriy Liskov
2026-03-04 22:15:32 +02:00
parent 53eb137755
commit e76e9ec7e4
10 changed files with 89 additions and 15 deletions

View File

@@ -256,6 +256,11 @@ public abstract class BasePlayerController implements PlayerEventListener {
// NOP
}
@Override
public void onButtonState(int buttonId, int buttonState) {
// NOP
}
@Override
public void onTrackChanged(FormatItem track) {
// NOP

View File

@@ -94,21 +94,23 @@ public class RemoteController extends BasePlayerController implements OnDataChan
@Override
public void onPlay() {
postPlay(RemoteControlService.STATE_PLAYING);
postPlayState(RemoteControlService.STATE_PLAYING);
}
@Override
public void onPause() {
postPlay(RemoteControlService.STATE_PAUSED);
postPlayState(RemoteControlService.STATE_PAUSED);
}
@Override
public void onPlayEnd() {
switch (getPlayerData().getPlaybackMode()) {
case PlayerConstants.PLAYBACK_MODE_CLOSE:
postPlayState(RemoteControlService.STATE_IDLE);
break;
case PlayerConstants.PLAYBACK_MODE_PAUSE:
case PlayerConstants.PLAYBACK_MODE_ALL:
postPlay(RemoteControlService.STATE_PAUSED);
postPlayState(RemoteControlService.STATE_PAUSED);
break;
case PlayerConstants.PLAYBACK_MODE_ONE:
postStartPlaying(getVideo(), RemoteControlService.STATE_PLAYING);
@@ -116,9 +118,39 @@ public class RemoteController extends BasePlayerController implements OnDataChan
}
}
@Override
public void onTrackSelected(FormatItem track) {
if (track.getType() == FormatItem.TYPE_SUBTITLE) {
if (getPlayer() == null) {
return;
}
// Post subtitle change immediately when user select subtitle track.
int currentState = getPlayer().getButtonState(R.id.lb_control_closed_captioning);
if (currentState == PlayerUI.BUTTON_ON) {
postSubtitleChange(track.getFormatId(), track.getLanguage());
}
}
}
@Override
public void onButtonState(int buttonId, int buttonState) {
if (buttonId == R.id.lb_control_closed_captioning) {
if (buttonState == PlayerUI.BUTTON_ON) {
FormatItem selected = getPlayerData().getFormat(FormatItem.TYPE_SUBTITLE);
if (selected != null) {
postSubtitleChange(selected.getFormatId(), selected.getLanguage());
} else {
postSubtitleChange(null, null);
}
} else if (buttonState == PlayerUI.BUTTON_OFF) {
postSubtitleChange(null, null);
}
}
}
@Override
public void onEngineReleased() {
postPlay(RemoteControlService.STATE_PAUSED);
postPlayState(RemoteControlService.STATE_IDLE);
// Below doesn't work on Vanced
//postStartPlaying(null);
}
@@ -183,7 +215,18 @@ public class RemoteController extends BasePlayerController implements OnDataChan
);
}
private void postPlay(int state) {
private void postSubtitleChange(String vssId, String languageCode) {
if (isRemoteDisabled()) {
return;
}
RxHelper.disposeActions(mPostStateAction);
mPostStateAction = RxHelper.execute(
mRemoteControlService.postSubtitleChangeObserve(vssId, languageCode)
);
}
private void postPlayState(int state) {
if (getPlayer() == null) {
return;
}
@@ -301,11 +344,9 @@ public class RemoteController extends BasePlayerController implements OnDataChan
getPlayer().setFormat(selected);
}
}
getPlayer().showSubtitles(true);
getPlayer().setButtonState(R.id.lb_control_closed_captioning, PlayerUI.BUTTON_ON);
getPlaybackPresenter().onButtonClicked(R.id.lb_control_closed_captioning, PlayerUI.BUTTON_OFF);
} else if (getPlayer() != null) {
getPlayer().showSubtitles(false);
getPlayer().setButtonState(R.id.lb_control_closed_captioning, PlayerUI.BUTTON_OFF);
getPlaybackPresenter().onButtonClicked(R.id.lb_control_closed_captioning, PlayerUI.BUTTON_ON);
}
openNewVideo(newVideo2);
break;
@@ -336,7 +377,7 @@ public class RemoteController extends BasePlayerController implements OnDataChan
movePlayerToForeground();
getPlayer().setPlayWhenReady(true);
//postStartPlaying(getController().getVideo(), true);
postPlay(RemoteControlService.STATE_PLAYING);
postPlayState(RemoteControlService.STATE_PLAYING);
} else {
// Already connected
openNewVideo(getVideo() != null ? getVideo() : mRemoteControlData.getLastVideo());
@@ -347,7 +388,7 @@ public class RemoteController extends BasePlayerController implements OnDataChan
movePlayerToForeground();
getPlayer().setPlayWhenReady(false);
//postStartPlaying(getController().getVideo(), false);
postPlay(RemoteControlService.STATE_PAUSED);
postPlayState(RemoteControlService.STATE_PAUSED);
} else {
// Already connected
openNewVideo(getVideo() != null ? getVideo() : mRemoteControlData.getLastVideo());

View File

@@ -44,4 +44,5 @@ public interface PlayerEngineEventListener {
void onEngineError(int type, int rendererIndex, Throwable error);
void onTrackChanged(FormatItem track);
void onTrackSelected(FormatItem track);
void onButtonState(int buttonId, int buttonState);
}

View File

@@ -419,6 +419,11 @@ public class PlaybackPresenter extends BasePresenter<PlaybackView> implements Pl
process(listener -> listener.onTrackChanged(track));
}
@Override
public void onButtonState(int buttonId, int buttonState) {
process(listener -> listener.onButtonState(buttonId, buttonState));
}
@Override
public void onButtonClicked(int buttonId, int buttonState) {
process(listener -> listener.onButtonClicked(buttonId, buttonState));

View File

@@ -374,6 +374,11 @@ public class ExoFormatItem implements FormatItem {
return mId;
}
@Override
public String getFormatId() {
return mFormatId;
}
@Override
public CharSequence getTitle() {
return mTitle;

View File

@@ -24,6 +24,7 @@ public interface FormatItem {
int TYPE_AUDIO = 1;
int TYPE_SUBTITLE = 2;
int getId();
String getFormatId();
CharSequence getTitle();
boolean isDefault();
boolean isSelected();

View File

@@ -403,7 +403,9 @@ public class DashManifestParser2 {
private RepresentationInfo parseRepresentation(MediaSubtitle sub) {
int roleFlags = C.ROLE_FLAG_SUBTITLE;
int selectionFlags = 0;
String id = String.valueOf(mId++);
//String id = String.valueOf(mId++);
// keep mId incrementing, but use vssId as id to make it unique and more meaningful
mId++;
int bandwidth = 268;
String mimeType = sub.getMimeType();
String codecs = sub.getCodecs();
@@ -422,7 +424,9 @@ public class DashManifestParser2 {
Format format =
buildFormat(
id,
//id,
// use vssId as id to make it unique
sub.getVssId(),
label,
mimeType,
width,

View File

@@ -407,7 +407,9 @@ public class SabrManifestParser {
private RepresentationInfo parseRepresentation(MediaSubtitle sub) {
int roleFlags = C.ROLE_FLAG_SUBTITLE;
int selectionFlags = 0;
String id = String.valueOf(mId++);
//String id = String.valueOf(mId++);
// keep mId incrementing, but use vssId as id to make it unique and more meaningful
mId++;
int bandwidth = 268;
String mimeType = sub.getMimeType();
String codecs = sub.getCodecs();
@@ -426,7 +428,9 @@ public class SabrManifestParser {
Format format =
buildFormat(
id,
//id,
// use vssId as id to make it unique
sub.getVssId(),
label,
mimeType,
width,

View File

@@ -805,6 +805,11 @@ public class PlaybackFragment extends SeekModePlaybackFragment implements Playba
public boolean onKeyDown(int keyCode) {
return mPlaybackPresenter.onKeyDown(keyCode);
}
@Override
public void onButtonState(int buttonId, int buttonState) {
mPlaybackPresenter.onButtonState(buttonId, buttonState);
}
}
// Begin Ui events

View File

@@ -310,6 +310,7 @@ public class VideoPlayerGlue extends MaxControlsVideoPlayerGlue<PlayerAdapter> i
}
public void setButtonState(int buttonId, int buttonState) {
mActionListener.onButtonState(buttonId, buttonState);
setActionIndex(mActions.get(buttonId), buttonState);
}
@@ -592,5 +593,7 @@ public class VideoPlayerGlue extends MaxControlsVideoPlayerGlue<PlayerAdapter> i
void onTopEdgeFocused();
boolean onKeyDown(int keyCode);
void onButtonState(int buttonId, int buttonState);
}
}