mirror of
https://github.com/imsyy/SPlayer.git
synced 2025-11-25 03:14:57 +08:00
357 lines
12 KiB
Vue
357 lines
12 KiB
Vue
<!-- 播放设置 -->
|
||
<template>
|
||
<div class="setting-type">
|
||
<div class="set-list">
|
||
<n-h3 prefix="bar"> 歌曲播放 </n-h3>
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">自动播放</n-text>
|
||
<n-text v-if="isElectron" class="tip" :depth="3">启动时是否自动播放</n-text>
|
||
<n-text v-else class="tip" :depth="3">网页端不支持该功能</n-text>
|
||
</div>
|
||
<n-switch
|
||
v-model:value="settingStore.autoPlay"
|
||
class="set"
|
||
:round="false"
|
||
:disabled="!isElectron"
|
||
/>
|
||
</n-card>
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">记忆上次播放位置</n-text>
|
||
<n-text class="tip" :depth="3">程序启动时恢复上次播放位置</n-text>
|
||
</div>
|
||
<n-switch v-model:value="settingStore.memoryLastSeek" class="set" :round="false" />
|
||
</n-card>
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">音乐渐入渐出</n-text>
|
||
</div>
|
||
<n-switch v-model:value="settingStore.songVolumeFade" class="set" :round="false" />
|
||
</n-card>
|
||
<n-collapse-transition :show="settingStore.songVolumeFade">
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">渐入渐出时长</n-text>
|
||
<n-text class="tip" :depth="3">单位 ms,最小 200,最大 2000</n-text>
|
||
</div>
|
||
<n-input-number
|
||
v-model:value="settingStore.songVolumeFadeTime"
|
||
:min="200"
|
||
:max="2000"
|
||
:show-button="false"
|
||
class="set"
|
||
placeholder="请输入渐入渐出时长"
|
||
>
|
||
<template #suffix> ms </template>
|
||
</n-input-number>
|
||
</n-card>
|
||
</n-collapse-transition>
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">在线歌曲音质</n-text>
|
||
<n-text class="tip" :depth="3"> {{ songLevelData[settingStore.songLevel].tip }}</n-text>
|
||
</div>
|
||
<n-select
|
||
v-model:value="settingStore.songLevel"
|
||
:options="Object.values(songLevelData)"
|
||
:render-option="renderOption"
|
||
class="set"
|
||
/>
|
||
</n-card>
|
||
<n-card v-if="!isElectron" class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">播放试听</n-text>
|
||
<n-text class="tip" :depth="3">是否在非会员状态下播放试听歌曲</n-text>
|
||
</div>
|
||
<n-switch v-model:value="settingStore.playSongDemo" class="set" :round="false" />
|
||
</n-card>
|
||
<n-card v-if="isElectron" class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">音乐解锁</n-text>
|
||
<n-text class="tip" :depth="3">在无法正常播放时进行替换,可能会与原曲不符</n-text>
|
||
</div>
|
||
<n-switch v-model:value="settingStore.useSongUnlock" class="set" :round="false" />
|
||
</n-card>
|
||
<n-card v-if="isElectron" class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">音频输出设备</n-text>
|
||
<n-text class="tip" :depth="3">新增或移除音频设备后请重新打开设置</n-text>
|
||
</div>
|
||
<n-select
|
||
v-model:value="settingStore.playDevice"
|
||
class="set"
|
||
:options="outputDevices"
|
||
:render-option="renderOption"
|
||
@update:value="playDeviceChange"
|
||
/>
|
||
</n-card>
|
||
</div>
|
||
<div class="set-list">
|
||
<n-h3 prefix="bar"> 播放器 </n-h3>
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">播放器样式</n-text>
|
||
<n-text class="tip" :depth="3">播放器主体样式</n-text>
|
||
</div>
|
||
<n-select
|
||
v-model:value="settingStore.playerType"
|
||
:options="[
|
||
{
|
||
label: '封面模式',
|
||
value: 'cover',
|
||
},
|
||
{
|
||
label: '唱片模式',
|
||
value: 'record',
|
||
},
|
||
]"
|
||
class="set"
|
||
/>
|
||
</n-card>
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">播放器背景样式</n-text>
|
||
<n-text class="tip" :depth="3">切换播放器背景类型</n-text>
|
||
</div>
|
||
<n-select
|
||
v-model:value="settingStore.playerBackgroundType"
|
||
:options="[
|
||
{
|
||
label: '流体效果',
|
||
disabled: true,
|
||
value: 'animation',
|
||
},
|
||
{
|
||
label: '封面模糊',
|
||
value: 'blur',
|
||
},
|
||
{
|
||
label: '封面主色',
|
||
disabled: true,
|
||
value: 'color',
|
||
},
|
||
{
|
||
label: '无背景',
|
||
disabled: true,
|
||
value: 'none',
|
||
},
|
||
]"
|
||
class="set"
|
||
/>
|
||
</n-card>
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">全屏播放器留存</n-text>
|
||
<n-text class="tip" :depth="3">在播放器收起时是否销毁,开启将会增大内存占用</n-text>
|
||
</div>
|
||
<n-switch v-model:value="settingStore.fullPlayerCache" class="set" :round="false" />
|
||
</n-card>
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">显示前奏倒计时</n-text>
|
||
<n-text class="tip" :depth="3">部分歌曲前奏可能存在显示错误</n-text>
|
||
</div>
|
||
<n-switch v-model:value="settingStore.countDownShow" class="set" :round="false" />
|
||
</n-card>
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">底栏歌词显示</n-text>
|
||
<n-text class="tip" :depth="3">在播放时将歌手信息更改为歌词</n-text>
|
||
</div>
|
||
<n-switch v-model:value="settingStore.barLyricShow" class="set" :round="false" />
|
||
</n-card>
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">播放列表歌曲数量</n-text>
|
||
</div>
|
||
<n-switch v-model:value="settingStore.showPlaylistCount" class="set" :round="false" />
|
||
</n-card>
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">动态封面</n-text>
|
||
<n-text class="tip" :depth="3">可展示部分歌曲的动态封面,仅在封面模式有效</n-text>
|
||
</div>
|
||
<n-switch
|
||
v-model:value="settingStore.dynamicCover"
|
||
:disabled="isLogin() !== 1"
|
||
:round="false"
|
||
class="set"
|
||
/>
|
||
</n-card>
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">音乐频谱</n-text>
|
||
<n-text class="tip" :depth="3">
|
||
{{
|
||
isElectron
|
||
? "开启音乐频谱会影响性能或音频输出切换等功能,如遇问题请关闭"
|
||
: "开启可能会造成无法播放或其他问题,如遇任何问题请关闭"
|
||
}}
|
||
</n-text>
|
||
</div>
|
||
<n-switch
|
||
class="set"
|
||
:value="showSpectrums"
|
||
:round="false"
|
||
@update:value="showSpectrumsChange"
|
||
/>
|
||
</n-card>
|
||
</div>
|
||
<div class="set-list">
|
||
<n-h3 prefix="bar"> 系统集成 </n-h3>
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">开启 SMTC</n-text>
|
||
<n-text class="tip" :depth="3">与系统集成以显示媒体元数据</n-text>
|
||
</div>
|
||
<n-switch v-model:value="settingStore.smtcOpen" class="set" :round="false" />
|
||
</n-card>
|
||
<n-card class="set-item">
|
||
<div class="label">
|
||
<n-text class="name">输出高清封面</n-text>
|
||
<n-text class="tip" :depth="3">开启 SMTC 时是否输出高清封面</n-text>
|
||
</div>
|
||
<n-switch
|
||
v-model:value="settingStore.smtcOutputHighQualityCover"
|
||
class="set"
|
||
:round="false"
|
||
:disabled="!settingStore.smtcOpen || true"
|
||
/>
|
||
</n-card>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import type { SelectOption } from "naive-ui";
|
||
import { useSettingStore } from "@/stores";
|
||
import { isLogin } from "@/utils/auth";
|
||
import { isElectron, renderOption } from "@/utils/helper";
|
||
import { uniqBy } from "lodash";
|
||
import player from "@/utils/player";
|
||
|
||
const settingStore = useSettingStore();
|
||
|
||
// 输出设备数据
|
||
const outputDevices = ref<SelectOption[]>([]);
|
||
|
||
// 显示音乐频谱
|
||
const showSpectrums = ref<boolean>(settingStore.showSpectrums);
|
||
|
||
// 音质数据
|
||
const songLevelData = {
|
||
standard: {
|
||
label: "标准音质",
|
||
tip: "标准音质 128kbps",
|
||
value: "standard",
|
||
},
|
||
higher: {
|
||
label: "较高音质",
|
||
tip: "较高音质 328kbps",
|
||
value: "higher",
|
||
},
|
||
exhigh: {
|
||
label: "极高 HQ",
|
||
tip: "近 CD 品质的细节体验,最高 320kbps",
|
||
value: "exhigh",
|
||
},
|
||
lossless: {
|
||
label: "无损 SQ",
|
||
tip: "高保真无损音质,最高 48kHz/16bit",
|
||
value: "lossless",
|
||
},
|
||
hires: {
|
||
label: "高清臻音 Spatial Audio",
|
||
tip: "环绕声体验,声音听感增强,96kHz/24bit",
|
||
value: "hires",
|
||
},
|
||
jymaster: {
|
||
label: "超清母带 Master",
|
||
tip: "还原音频细节,192kHz/24bit",
|
||
value: "jymaster",
|
||
},
|
||
sky: {
|
||
label: "沉浸环绕声 Surround Audio",
|
||
tip: "沉浸式体验,最高 5.1 声道",
|
||
value: "sky",
|
||
},
|
||
};
|
||
|
||
// 获取全部输出设备
|
||
const getOutputDevices = async () => {
|
||
const allDevices = await navigator.mediaDevices.enumerateDevices();
|
||
// 过滤同一设备输出源
|
||
const devices = uniqBy(
|
||
allDevices.filter((device) => device.kind === "audiooutput" && device.deviceId),
|
||
"groupId",
|
||
);
|
||
const outputData = devices.filter((device) => device.kind === "audiooutput");
|
||
outputDevices.value = outputData.map((device) => ({
|
||
label: device.label,
|
||
value: device.deviceId,
|
||
}));
|
||
};
|
||
|
||
// 切换输出设备
|
||
const playDeviceChange = (deviceId: string, option: SelectOption) => {
|
||
if (settingStore.showSpectrums) {
|
||
window.$dialog.warning({
|
||
title: "音频通道占用",
|
||
content:
|
||
"由于系统限制,切换音频输出设备会导致音乐频谱失效,将会关闭音乐频谱,并将于热重载后生效( 请点击右上角的设置菜单中的热重载按钮 ),是否继续?",
|
||
positiveText: "继续",
|
||
negativeText: "取消",
|
||
closeOnEsc: false,
|
||
closable: false,
|
||
maskClosable: false,
|
||
autoFocus: false,
|
||
onPositiveClick: () => {
|
||
showSpectrums.value = false;
|
||
settingStore.showSpectrums = false;
|
||
player.toggleOutputDevice(deviceId);
|
||
window.$message.success(`已切换输出设备为 ${option.label}`);
|
||
},
|
||
onNegativeClick: () => {
|
||
settingStore.playDevice = "default";
|
||
},
|
||
});
|
||
} else {
|
||
player.toggleOutputDevice(deviceId);
|
||
window.$message.success(`已切换输出设备为 ${option.label}`);
|
||
}
|
||
};
|
||
|
||
// 显示音乐频谱更改
|
||
const showSpectrumsChange = (value: boolean) => {
|
||
if (value) {
|
||
if (settingStore.playDevice !== "default") {
|
||
window.$dialog.warning({
|
||
title: "音频通道占用",
|
||
content: "开启音乐频谱会导致自定义音频输出设备失效,将会恢复默认输出设备,是否继续开启?",
|
||
positiveText: "开启",
|
||
negativeText: "取消",
|
||
onPositiveClick: () => {
|
||
showSpectrums.value = true;
|
||
settingStore.showSpectrums = true;
|
||
settingStore.playDevice = "default";
|
||
player.toggleOutputDevice("default");
|
||
},
|
||
});
|
||
return;
|
||
}
|
||
showSpectrums.value = true;
|
||
settingStore.showSpectrums = true;
|
||
} else {
|
||
showSpectrums.value = false;
|
||
settingStore.showSpectrums = false;
|
||
}
|
||
};
|
||
|
||
onMounted(() => {
|
||
if (isElectron) {
|
||
getOutputDevices();
|
||
}
|
||
});
|
||
</script>
|