Skip to content

Commit

Permalink
✨ Save player settings (in local storage)
Browse files Browse the repository at this point in the history
Also put the ProgressRing in the center of the video, otherwise users may not notice it on mobile devices when the controller is visible.
  • Loading branch information
Aira-Sakuranomiya committed Mar 26, 2024
1 parent 52e69a3 commit c14cba7
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 11 deletions.
43 changes: 35 additions & 8 deletions components/Player/PlayerVideo/PlayerVideo.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
const playing = ref(false);
const playbackRate = ref(1);
const preservesPitch = ref(false);
const steplessRate = ref(false);
const continuousRateControl = ref(false);
const volume = ref(1);
const muted = ref(false);
const currentTime = ref(NaN);
Expand Down Expand Up @@ -96,6 +96,7 @@
const playerVideoControllerMouseDown = ref(false);
const fullscreenColorClass = computed(() => ({ [`force-color dark ${useCookie(COOKIE_KEY.themeColorCookieKey, DEFAULT_COOKIE_OPTION).value || THEME_ENV.DEFAULT_THEME_COLOR}`]: fullscreen.value }));
type MediaInfo = Record<string, Record<string, unknown>>;
const playerConfig = useAppSettingsStore().player;
/**
* 显示视频详细信息。
Expand Down Expand Up @@ -147,6 +148,11 @@
watch(preservesPitch, preservesPitch => {
if (!video.value) return;
video.value.preservesPitch = preservesPitch;
playerConfig.rate.preservesPitch = preservesPitch;
});
watch(continuousRateControl, continuousRateControl => {
playerConfig.rate.continuousControl = continuousRateControl;
});
watch(playbackRate, playbackRate => {
Expand All @@ -157,11 +163,21 @@
watch(volume, volume => {
if (!video.value) return;
video.value.volume = volume ** 2; // 使用对数音量。
playerConfig.audio.volume = volume;
});
watch(muted, muted => {
if (!video.value) return;
video.value.muted = muted;
playerConfig.audio.muted = muted;
});
watch(() => settings.danmaku.opacity, opacity => {
playerConfig.danmaku.opacity = opacity;
});
watch(() => settings.danmaku.fontSizeScale, size => {
playerConfig.danmaku.fontSizeScale = size;
});
watch(fullscreen, fullscreen => {
Expand Down Expand Up @@ -274,6 +290,14 @@
// BUG: Dash.js will raise an error: [614][FragmentController] TypeError: Cannot read properties of undefined (reading 'append')
}
// 从 Pinia 中取出保存的设置。
volume.value = playerConfig.audio.volume;
muted.value = playerConfig.audio.muted;
preservesPitch.value = playerConfig.rate.preservesPitch;
continuousRateControl.value = playerConfig.rate.continuousControl;
settings.danmaku.opacity = playerConfig.danmaku.opacity;
settings.danmaku.fontSizeScale = playerConfig.danmaku.fontSizeScale;
});
/**
Expand Down Expand Up @@ -438,7 +462,9 @@
:style="{ opacity: settings.danmaku.opacity }"
/>
<!-- TODO: ProgressRing 改成卡住(开屏加载不包含在内)一秒后再显示,防止出现过于频繁。 -->
<ProgressRing v-if="waiting" class="waiting" />
<div v-if="waiting" class="waiting">
<ProgressRing class="force-color light" />
</div>
<PlayerVideoAbout v-model="showAboutPlayer" :playing />
</Contents>
<PlayerVideoTitle
Expand All @@ -456,7 +482,7 @@
v-model:volume="volume"
v-model:muted="muted"
v-model:resample="resample"
v-model:steplessRate="steplessRate"
v-model:continuousRateControl="continuousRateControl"
v-model:showDanmaku="showDanmaku"
v-model:quality="quality"
v-model:waiting="waiting"
Expand Down Expand Up @@ -560,12 +586,13 @@
}
.waiting {
position: absolute;
inset: unset;
bottom: 8px;
left: 8px;
color: c(gray-20);
@include flex-center;
pointer-events: none;
.progress-ring {
--size: 56px;
--thickness: 6px;
}
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions components/Player/PlayerVideo/PlayerVideoController.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
const model = defineModel<number>("currentTime", { default: NaN });
const fullscreen = defineModel<boolean>("fullscreen", { default: false });
const resample = defineModel<boolean>("resample", { default: true });
const steplessRate = defineModel<boolean>("steplessRate", { default: false });
const continuousRateControl = defineModel<boolean>("continuousRateControl", { default: false });
const showDanmaku = defineModel<boolean>("showDanmaku", { default: false });
const waiting = defineModel<boolean>("waiting", { default: false });
const ended = defineModel<boolean>("ended", { default: false });
Expand All @@ -55,7 +55,7 @@
get: () => Math.log2(playbackRate.value),
set: value => {
value = 2 ** value;
if (!steplessRate.value) {
if (!continuousRateControl.value) {
const variances = stepedPlaybackRates.map(rate => (value - rate) ** 2);
const minimum = Math.min(...variances);
value = stepedPlaybackRates[variances.indexOf(minimum)];
Expand Down Expand Up @@ -213,7 +213,7 @@
</PlayerVideoMenu>
<PlayerVideoMenu v-model="rateMenu">
<ToggleSwitch v-model="resample" v-ripple.overlay icon="tunning">{{ t.player.speed.resample }}</ToggleSwitch>
<ToggleSwitch v-model="steplessRate" v-ripple.overlay icon="speed">{{ t.player.speed.continuous }}</ToggleSwitch>
<ToggleSwitch v-model="continuousRateControl" v-ripple.overlay icon="speed">{{ t.player.speed.continuous }}</ToggleSwitch>
<template #slider>
<CapsuleSlider v-model="playbackRateLinear" :min="-2" :max="2" :displayValue="playbackRateText" :defaultValue="0" />
</template>
Expand Down
14 changes: 14 additions & 0 deletions stores/app-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,20 @@ export const useAppSettingsStore = defineStore("app-settings", {

/** 已登录用户是否允许在多设备上同步主题设置 */
isAllowSyncThemeSettings: false,
player: {
audio: {
volume: 1,
muted: false,
},
rate: {
preservesPitch: false,
continuousControl: false,
},
danmaku: {
opacity: 1,
fontSizeScale: 1,
},
},
}),
getters: {
getExitSettingRoute: state => {
Expand Down

0 comments on commit c14cba7

Please sign in to comment.