player: subtitle style + refactor

This commit is contained in:
Yuriy Liskov
2022-08-05 01:30:03 +03:00
parent 5bdd38a331
commit e9cdf4d5a6
7 changed files with 135 additions and 108 deletions

View File

@@ -144,6 +144,9 @@ public class PlayerUIManager extends PlayerEventListenerHelper implements Metada
option -> getController().setFormat(UiOptionItem.toFormat(option)),
getActivity().getString(R.string.subtitles_disabled)));
OptionCategory stylesCategory = AppDialogUtil.createSubtitleStylesCategory(getActivity(), mPlayerData);
settingsPresenter.appendRadioCategory(stylesCategory.title, stylesCategory.options);
settingsPresenter.showDialog(subtitlesCategoryTitle, this::setSubtitleButtonState);
}

View File

@@ -51,15 +51,12 @@ public class SubtitleManager implements TextOutput {
}
}
public interface OnSelectSubtitleStyle {
void onSelectSubtitleStyle(SubtitleStyle style);
}
public SubtitleManager(Activity activity, int subViewId) {
mContext = activity;
mSubtitleView = activity.findViewById(subViewId);
mPrefs = AppPrefs.instance(activity);
mPlayerData = PlayerData.instance(activity);
mPlayerData.setOnChange(this::configureSubtitleView);
configureSubtitleView();
}
@@ -70,25 +67,25 @@ public class SubtitleManager implements TextOutput {
}
}
public List<SubtitleStyle> getSubtitleStyles() {
return mSubtitleStyles;
}
public SubtitleStyle getSubtitleStyle() {
return mPlayerData.getSubtitleStyle();
}
public void setSubtitleStyle(SubtitleStyle subtitleStyle) {
mPlayerData.setSubtitleStyle(subtitleStyle);
configureSubtitleView();
}
public void show(boolean show) {
if (mSubtitleView != null) {
mSubtitleView.setVisibility(show ? View.VISIBLE : View.GONE);
}
}
private List<SubtitleStyle> getSubtitleStyles() {
return mSubtitleStyles;
}
private SubtitleStyle getSubtitleStyle() {
return mPlayerData.getSubtitleStyle();
}
private void setSubtitleStyle(SubtitleStyle subtitleStyle) {
mPlayerData.setSubtitleStyle(subtitleStyle);
configureSubtitleView();
}
private List<Cue> forceCenterAlignment(List<Cue> cues) {
List<Cue> result = new ArrayList<>();

View File

@@ -2,18 +2,14 @@ package com.liskovsoft.smartyoutubetv2.common.misc;
import android.os.Handler;
import android.os.Looper;
import com.liskovsoft.sharedutils.helpers.Helpers;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import com.liskovsoft.smartyoutubetv2.common.utils.WeakHashSet;
public class TickleManager {
private static TickleManager sInstance;
private final Handler mHandler = new Handler(Looper.getMainLooper());
private final Runnable mUpdateHandler = this::updateTickle;
// Usually listener is a view. So use weak refs to not hold it forever.
private final List<WeakReference<TickleListener>> mListeners = new ArrayList<>();
private final WeakHashSet<TickleListener> mListeners = new WeakHashSet<>();
private boolean mIsEnabled = true;
private static final long DEFAULT_INTERVAL_MS = 60_000;
private long mIntervalMs = DEFAULT_INTERVAL_MS;
@@ -34,9 +30,7 @@ public class TickleManager {
}
public void addListener(TickleListener listener) {
if (listener != null && !contains(listener)) {
cleanup();
mListeners.add(new WeakReference<>(listener));
if (mListeners.add(listener)) {
if (mListeners.size() == 1) { // periodic callback not started yet
updateTickle();
} else if (isEnabled()) {
@@ -46,9 +40,7 @@ public class TickleManager {
}
public void removeListener(TickleListener listener) {
if (listener != null) {
remove(listener);
}
mListeners.remove(listener);
}
public void setEnabled(boolean enabled) {
@@ -82,25 +74,8 @@ public class TickleManager {
mHandler.removeCallbacks(mUpdateHandler);
if (isEnabled() && !mListeners.isEmpty()) {
for (WeakReference<TickleListener> listener : mListeners) {
if (listener.get() != null) {
listener.get().onTickle();
}
}
mListeners.forEach(TickleListener::onTickle);
mHandler.postDelayed(mUpdateHandler, mIntervalMs);
}
}
private boolean contains(TickleListener listener) {
return Helpers.containsIf(mListeners, item -> listener.equals(item.get()));
}
private void remove(TickleListener listener) {
Helpers.removeIf(mListeners, item -> listener.equals(item.get()));
}
private void cleanup() {
Helpers.removeIf(mListeners, item -> item.get() == null);
}
}

View File

@@ -1,10 +1,9 @@
package com.liskovsoft.smartyoutubetv2.common.prefs;
import java.util.HashSet;
import java.util.Set;
import com.liskovsoft.smartyoutubetv2.common.utils.WeakHashSet;
public class DataChangeBase {
private final Set<Runnable> mOnChangeList = new HashSet<>();
private final WeakHashSet<Runnable> mOnChangeList = new WeakHashSet<>();
public void setOnChange(Runnable callback) {
mOnChangeList.add(callback);
@@ -15,8 +14,6 @@ public class DataChangeBase {
}
protected void persistState() {
for (Runnable callback : mOnChangeList) {
callback.run();
}
mOnChangeList.forEach(Runnable::run);
}
}

View File

@@ -18,7 +18,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class PlayerData {
public class PlayerData extends DataChangeBase {
private static final String VIDEO_PLAYER_DATA = "video_player_data";
public static final int ONLY_UI = 0;
public static final int UI_AND_PAUSE = 1;
@@ -79,7 +79,7 @@ public class PlayerData {
mPrefs = AppPrefs.instance(context);
initSubtitleStyles();
initDefaultFormats();
restoreData();
restoreState();
}
public static PlayerData instance(Context context) {
@@ -92,7 +92,7 @@ public class PlayerData {
public void setOKButtonBehavior(int option) {
mOKButtonBehavior = option;
persistData();
persistState();
}
public int getOKButtonBehavior() {
@@ -101,7 +101,7 @@ public class PlayerData {
public void setUIHideTimoutSec(int timoutSec) {
mUIHideTimeoutSec = timoutSec;
persistData();
persistState();
}
public int getUIHideTimoutSec() {
@@ -110,7 +110,7 @@ public class PlayerData {
public void enableAbsoluteDate(boolean show) {
mIsAbsoluteDateEnabled = show;
persistData();
persistState();
}
public boolean isAbsoluteDateEnabled() {
@@ -119,7 +119,7 @@ public class PlayerData {
public void setSeekPreviewMode(int mode) {
mSeekPreviewMode = mode;
persistData();
persistState();
}
public int getSeekPreviewMode() {
@@ -128,7 +128,7 @@ public class PlayerData {
public void enableSeekConfirmPause(boolean enable) {
mIsSeekConfirmPauseEnabled = enable;
persistData();
persistState();
}
public boolean isSeekConfirmPauseEnabled() {
@@ -137,7 +137,7 @@ public class PlayerData {
public void enableSeekConfirmPlay(boolean enable) {
mIsSeekConfirmPlayEnabled = enable;
persistData();
persistState();
}
public boolean isSeekConfirmPlayEnabled() {
@@ -150,7 +150,7 @@ public class PlayerData {
public void enableClock(boolean enable) {
mIsClockEnabled = enable;
persistData();
persistState();
}
public boolean isGlobalClockEnabled() {
@@ -159,7 +159,7 @@ public class PlayerData {
public void enableGlobalClock(boolean enable) {
mIsGlobalClockEnabled = enable;
persistData();
persistState();
}
public boolean isGlobalEndingTimeEnabled() {
@@ -168,7 +168,7 @@ public class PlayerData {
public void enableGlobalEndingTime(boolean enable) {
mIsGlobalEndingTimeEnabled = enable;
persistData();
persistState();
}
public boolean isRemainingTimeEnabled() {
@@ -177,7 +177,7 @@ public class PlayerData {
public void enableRemainingTime(boolean enable) {
mIsRemainingTimeEnabled = enable;
persistData();
persistState();
}
public boolean isEndingTimeEnabled() {
@@ -186,7 +186,7 @@ public class PlayerData {
public void enableEndingTime(boolean enable) {
mIsEndingTimeEnabled = enable;
persistData();
persistState();
}
public boolean isQualityInfoEnabled() {
@@ -195,12 +195,12 @@ public class PlayerData {
public void enableQualityInfo(boolean enable) {
mIsQualityInfoEnabled = enable;
persistData();
persistState();
}
public void setBackgroundMode(int type) {
mBackgroundMode = type;
persistData();
persistState();
}
public int getBackgroundMode() {
@@ -209,7 +209,7 @@ public class PlayerData {
public void setPlaybackMode(int type) {
mPlaybackMode = type;
persistData();
persistState();
}
public int getPlaybackMode() {
@@ -223,7 +223,7 @@ public class PlayerData {
public void enableRememberSpeed(boolean enable) {
mIsRememberSpeedEnabled = enable;
mIsRememberSpeedEachEnabled = false;
persistData();
persistState();
}
public boolean isRememberSpeedEachEnabled() {
@@ -233,7 +233,7 @@ public class PlayerData {
public void enableRememberSpeedEach(boolean enable) {
mIsRememberSpeedEachEnabled = enable;
mIsRememberSpeedEnabled = false;
persistData();
persistState();
}
public boolean isLegacyCodecsForced() {
@@ -242,7 +242,7 @@ public class PlayerData {
public void forceLegacyCodecs(boolean enable) {
mIsLegacyCodecsForced = enable;
persistData();
persistState();
}
public boolean isAfrEnabled() {
@@ -251,7 +251,7 @@ public class PlayerData {
public void setAfrEnabled(boolean enabled) {
mIsAfrEnabled = enabled;
persistData();
persistState();
}
public boolean isAfrFpsCorrectionEnabled() {
@@ -260,7 +260,7 @@ public class PlayerData {
public void setAfrFpsCorrectionEnabled(boolean enabled) {
mIsAfrFpsCorrectionEnabled = enabled;
persistData();
persistState();
}
public boolean isAfrResSwitchEnabled() {
@@ -269,7 +269,7 @@ public class PlayerData {
public void setAfrResSwitchEnabled(boolean enabled) {
mIsAfrResSwitchEnabled = enabled;
persistData();
persistState();
}
public int getAfrPauseMs() {
@@ -278,7 +278,7 @@ public class PlayerData {
public void setAfrPauseMs(int pauseSec) {
mAfrPauseMs = pauseSec;
persistData();
persistState();
}
public boolean isDoubleRefreshRateEnabled() {
@@ -287,7 +287,7 @@ public class PlayerData {
public void setDoubleRefreshRateEnabled(boolean enabled) {
mIsDoubleRefreshRateEnabled = enabled;
persistData();
persistState();
}
public boolean isTooltipsEnabled() {
@@ -296,7 +296,7 @@ public class PlayerData {
public void enableTooltips(boolean enable) {
mIsTooltipsEnabled = enable;
persistData();
persistState();
}
public boolean isNumberKeySeekEnabled() {
@@ -305,7 +305,7 @@ public class PlayerData {
public void enableNumberKeySeek(boolean enable) {
mIsNumberKeySeekEnabled = enable;
persistData();
persistState();
}
public FormatItem getFormat(int type) {
@@ -343,12 +343,12 @@ public class PlayerData {
break;
}
persistData();
persistState();
}
public void setVideoBufferType(int type) {
mVideoBufferType = type;
persistData();
persistState();
}
public int getVideoBufferType() {
@@ -365,7 +365,7 @@ public class PlayerData {
public void setSubtitleStyle(SubtitleStyle subtitleStyle) {
mSubtitleStyleIndex = mSubtitleStyles.indexOf(subtitleStyle);
persistData();
persistState();
}
public float getSubtitleScale() {
@@ -374,7 +374,7 @@ public class PlayerData {
public void setSubtitleScale(float scale) {
mSubtitleScale = scale;
persistData();
persistState();
}
public float getSubtitlePosition() {
@@ -383,7 +383,7 @@ public class PlayerData {
public void setSubtitlePosition(float position) {
mSubtitlePosition = position;
persistData();
persistState();
}
public float getPlayerVolume() {
@@ -392,12 +392,12 @@ public class PlayerData {
public void setPlayerVolume(float scale) {
mPlayerVolume = scale;
persistData();
persistState();
}
public void setVideoZoomMode(int mode) {
mVideoZoomMode = mode;
persistData();
persistState();
}
public int getVideoZoomMode() {
@@ -406,7 +406,7 @@ public class PlayerData {
public void setVideoAspectRatio(float ratio) {
mVideoAspectRatio = ratio;
persistData();
persistState();
}
public float getVideoAspectRatio() {
@@ -419,7 +419,7 @@ public class PlayerData {
}
mSpeed = speed;
persistData();
persistState();
}
public float getSpeed() {
@@ -432,12 +432,12 @@ public class PlayerData {
public void setAudioDelayMs(int delayMs) {
mAudioDelayMs = delayMs;
persistData();
persistState();
}
public void enableSonyTimerFix(boolean enable) {
mIsSonyTimerFixEnabled = enable;
persistData();
persistState();
}
public boolean isSonyTimerFixEnabled() {
@@ -446,7 +446,7 @@ public class PlayerData {
public void enableTimeCorrection(boolean enable) {
mIsTimeCorrectionEnabled = enable;
persistData();
persistState();
}
public boolean isTimeCorrectionEnabled() {
@@ -459,7 +459,7 @@ public class PlayerData {
public void enableSkip24Rate(boolean enable) {
mIsSkip24RateEnabled = enable;
persistData();
persistState();
}
public boolean isLiveChatEnabled() {
@@ -468,7 +468,7 @@ public class PlayerData {
public void enableLiveChat(boolean enable) {
mIsLiveChatEnabled = enable;
persistData();
persistState();
}
public FormatItem getDefaultAudioFormat() {
@@ -499,7 +499,7 @@ public class PlayerData {
public void setStartSeekIncrementMs(int startSeekIncrementMs) {
mStartSeekIncrementMs = startSeekIncrementMs;
persistData();
persistState();
}
private void initSubtitleStyles() {
@@ -525,7 +525,7 @@ public class PlayerData {
mDefaultVideoFormats.put("P1", FormatItem.VIDEO_FHD_AVC_60); // Chinese projector (see annoying emails)
}
private void restoreData() {
private void restoreState() {
String data = mPrefs.getData(VIDEO_PLAYER_DATA);
String[] split = Helpers.splitObjectLegacy(data);
@@ -582,7 +582,8 @@ public class PlayerData {
}
}
private void persistData() {
@Override
protected void persistState() {
mPrefs.setData(VIDEO_PLAYER_DATA, Helpers.mergeObject(mOKButtonBehavior, mUIHideTimeoutSec, mIsAbsoluteDateEnabled, mSeekPreviewMode, mIsSeekConfirmPauseEnabled,
mIsClockEnabled, mIsRemainingTimeEnabled, mBackgroundMode, null, // afrData was there
Helpers.toString(mVideoFormat), Helpers.toString(mAudioFormat), Helpers.toString(mSubtitleFormat),
@@ -594,5 +595,7 @@ public class PlayerData {
mIsGlobalEndingTimeEnabled, mIsEndingTimeEnabled, mIsDoubleRefreshRateEnabled, mIsSeekConfirmPlayEnabled,
mStartSeekIncrementMs, null, mSubtitleScale, mPlayerVolume, mIsTooltipsEnabled, mSubtitlePosition, mIsNumberKeySeekEnabled,
mIsSkip24RateEnabled, mAfrPauseMs, mIsLiveChatEnabled));
super.persistState();
}
}

View File

@@ -14,16 +14,16 @@ import com.liskovsoft.smartyoutubetv2.common.app.models.data.Playlist;
import com.liskovsoft.smartyoutubetv2.common.app.models.data.Video;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.controller.PlaybackController;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.controller.PlaybackEngineController;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.ui.OptionCallback;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.ui.OptionCategory;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.ui.OptionItem;
import com.liskovsoft.smartyoutubetv2.common.app.models.playback.ui.UiOptionItem;
import com.liskovsoft.smartyoutubetv2.common.app.presenters.AppDialogPresenter;
import com.liskovsoft.smartyoutubetv2.common.app.presenters.dialogs.menu.VideoMenuPresenter.VideoMenuCallback;
import com.liskovsoft.smartyoutubetv2.common.app.views.ViewManager;
import com.liskovsoft.smartyoutubetv2.common.exoplayer.other.SubtitleManager.SubtitleStyle;
import com.liskovsoft.smartyoutubetv2.common.exoplayer.selector.FormatItem;
import com.liskovsoft.smartyoutubetv2.common.exoplayer.selector.FormatItem.VideoPreset;
import com.liskovsoft.smartyoutubetv2.common.exoplayer.other.SubtitleManager.OnSelectSubtitleStyle;
import com.liskovsoft.smartyoutubetv2.common.exoplayer.other.SubtitleManager.SubtitleStyle;
import com.liskovsoft.smartyoutubetv2.common.misc.AppDataSourceManager;
import com.liskovsoft.smartyoutubetv2.common.misc.MediaServiceManager;
import com.liskovsoft.smartyoutubetv2.common.prefs.GeneralData;
@@ -262,27 +262,20 @@ public class AppDialogUtil {
}
public static OptionCategory createSubtitleStylesCategory(Context context, PlayerData playerData) {
return createSubtitleStylesCategory(context, playerData, style -> {});
}
private static OptionCategory createSubtitleStylesCategory(Context context, PlayerData playerData, OnSelectSubtitleStyle onSelectSubtitleStyle) {
List<SubtitleStyle> subtitleStyles = playerData.getSubtitleStyles();
String subtitleStyleTitle = context.getString(R.string.subtitle_style);
return OptionCategory.from(SUBTITLE_STYLES_ID, OptionCategory.TYPE_RADIO, subtitleStyleTitle, fromSubtitleStyles(context, playerData, subtitleStyles, onSelectSubtitleStyle));
return OptionCategory.from(SUBTITLE_STYLES_ID, OptionCategory.TYPE_RADIO, subtitleStyleTitle, fromSubtitleStyles(context, playerData, subtitleStyles));
}
private static List<OptionItem> fromSubtitleStyles(Context context, PlayerData playerData, List<SubtitleStyle> subtitleStyles, OnSelectSubtitleStyle onSelectSubtitleStyle) {
private static List<OptionItem> fromSubtitleStyles(Context context, PlayerData playerData, List<SubtitleStyle> subtitleStyles) {
List<OptionItem> styleOptions = new ArrayList<>();
for (SubtitleStyle subtitleStyle : subtitleStyles) {
styleOptions.add(UiOptionItem.from(
context.getString(subtitleStyle.nameResId),
option -> {
playerData.setSubtitleStyle(subtitleStyle);
onSelectSubtitleStyle.onSelectSubtitleStyle(subtitleStyle);
},
option -> playerData.setSubtitleStyle(subtitleStyle),
subtitleStyle.equals(playerData.getSubtitleStyle())));
}

View File

@@ -0,0 +1,59 @@
package com.liskovsoft.smartyoutubetv2.common.utils;
import com.liskovsoft.sharedutils.helpers.Helpers;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
public class WeakHashSet<T> {
public interface OnItem<T> {
void onItem(T item);
}
private final List<WeakReference<T>> mWeakReferences = new ArrayList<>();
public boolean add(T t) {
if (t != null && !contains(t)) {
cleanup();
mWeakReferences.add(new WeakReference<>(t));
return true;
}
return false;
}
public void remove(T t) {
if (t != null) {
Helpers.removeIf(mWeakReferences, item -> t.equals(item.get()));
}
}
public int size() {
return mWeakReferences.size();
}
public void forEach(OnItem<T> onItem) {
for (WeakReference<T> reference : mWeakReferences) {
if (reference.get() != null) {
onItem.onItem(reference.get());
}
}
}
public boolean contains(T t) {
return Helpers.containsIf(mWeakReferences, item -> t.equals(item.get()));
}
public void clear() {
mWeakReferences.clear();
}
public boolean isEmpty() {
return mWeakReferences.isEmpty();
}
private void cleanup() {
Helpers.removeIf(mWeakReferences, item -> item.get() == null);
}
}