feat: 支持设置 画质、音质、编码 的优先级

This commit is contained in:
lanyeeee
2025-09-05 05:06:38 +08:00
parent ae73e474c7
commit 5ed41ef7b6
10 changed files with 219 additions and 277 deletions
+1 -4
View File
@@ -247,7 +247,7 @@ export type CntInfo = { collect: number; play: number; thumb_up: number; share:
export type CntInfoInMedia = { collect: number; play: number; danmaku: number; vt: number; play_switch: number; reply: number; view_text_1: string }
export type CodecType = "Unknown" | "Audio" | "AVC" | "HEVC" | "AV1"
export type CommandError = { err_title: string; err_message: string }
export type Config = { download_dir: string; enable_file_logger: boolean; sessdata: string; prefer_video_quality: PreferVideoQuality; prefer_codec_type: PreferCodecType; prefer_audio_quality: PreferAudioQuality; download_video: boolean; download_audio: boolean; auto_merge: boolean; embed_chapter: boolean; embed_skip: boolean; download_xml_danmaku: boolean; download_ass_danmaku: boolean; download_json_danmaku: boolean; download_subtitle: boolean; download_cover: boolean; download_nfo: boolean; download_json: boolean; dir_fmt: string; dir_fmt_for_part: string; time_fmt: string; proxy_mode: ProxyMode; proxy_host: string; proxy_port: number; task_concurrency: number; task_download_interval_sec: number; chunk_concurrency: number; chunk_download_interval_sec: number; danmaku_config: CanvasConfig }
export type Config = { download_dir: string; enable_file_logger: boolean; sessdata: string; video_quality_priority: VideoQuality[]; codec_type_priority: CodecType[]; audio_quality_priority: AudioQuality[]; download_video: boolean; download_audio: boolean; auto_merge: boolean; embed_chapter: boolean; embed_skip: boolean; download_xml_danmaku: boolean; download_ass_danmaku: boolean; download_json_danmaku: boolean; download_subtitle: boolean; download_cover: boolean; download_nfo: boolean; download_json: boolean; dir_fmt: string; dir_fmt_for_part: string; time_fmt: string; proxy_mode: ProxyMode; proxy_host: string; proxy_port: number; task_concurrency: number; task_download_interval_sec: number; chunk_concurrency: number; chunk_download_interval_sec: number; danmaku_config: CanvasConfig }
export type Consulting = { consulting_flag: boolean; consulting_url: string }
export type ContentAttr = { text: string; bg_color: string; bg_color_night: string; img: string; multi_img: MultiImg }
export type ContentList = { bold: boolean; content: string; number: string }
@@ -331,9 +331,6 @@ export type PendantInCheese = { image: string; name: string; pid: number }
export type PendantInUserInfo = { pid: number; name: string; image: string; expire: number; image_enhance: string; image_enhance_frame: string; n_pid: number }
export type PlayStrategy = { strategies: string[] }
export type Positive = { id: number; title: string }
export type PreferAudioQuality = "Best" | "64K" | "132K" | "192K" | "Dolby" | "HiRes"
export type PreferCodecType = "Unknown" | "AVC" | "HEVC" | "AV1"
export type PreferVideoQuality = "Best" | "240P" | "360P" | "480P" | "720P" | "720P60" | "1080P" | "AiRepair" | "1080P+" | "1080P60" | "4K" | "HDR" | "Dolby" | "8K"
export type PreviewedPurchaseNote = { long_watch_text: string; pay_text: string; price_format: string; watch_text: string; watching_text: string }
export type Producer = { mid: number; type: number; is_contribute: number | null; title: string }
export type ProxyMode = "NoProxy" | "System" | "Custom"
@@ -1,34 +1,40 @@
<script setup lang="ts">
import { SelectBaseOption } from 'naive-ui/es/select/src/interface'
import { PreferAudioQuality, PreferVideoQuality } from '../../../bindings.ts'
import { AudioQuality, VideoQuality, CodecType } from '../../../bindings.ts'
import { useStore } from '../../../store.ts'
import { VueDraggable } from 'vue-draggable-plus'
import ColorfulTag from '../../../components/ColorfulTag.vue'
const store = useStore()
const videoQualitySelectOptions: SelectBaseOption<PreferVideoQuality>[] = [
{ label: '最高', value: 'Best' },
{ label: '240P', value: '240P' },
{ label: '360P', value: '360P' },
{ label: '480P', value: '480P' },
{ label: '720P', value: '720P' },
{ label: '720P 60帧', value: '720P60' },
{ label: '1080P', value: '1080P' },
{ label: '智能修复', value: 'AiRepair' },
{ label: '1080P 高码率', value: '1080P+' },
{ label: '1080P 60帧', value: '1080P60' },
{ label: '4K', value: '4K' },
{ label: 'HDR', value: 'HDR' },
{ label: '杜比视界', value: 'Dolby' },
{ label: '8K', value: '8K' },
]
const audioQualitySelectOptions: SelectBaseOption<PreferAudioQuality>[] = [
{ label: '最高', value: 'Best' },
{ label: '64K', value: '64K' },
{ label: '132K', value: '132K' },
{ label: '192K', value: '192K' },
{ label: '杜比全景声', value: 'Dolby' },
{ label: 'Hi-Res', value: 'HiRes' },
]
const videoQualityNameMap: Map<VideoQuality, string> = new Map([
['240P', '240P 极速'],
['360P', '360P 流畅'],
['480P', '480P 标清'],
['720P', '720P 准高清'],
['720P60', '720P 60帧'],
['1080P', '1080P 高清'],
['AiRepair', 'AI智能修复'],
['1080P+', '1080P 高码率'],
['1080P60', '1080P 60帧'],
['4K', '4K 超高清'],
['HDR', 'HDR 真彩色'],
['Dolby', '杜比视界'],
['8K', '8K 超高清'],
])
const audioQualityNameMap: Map<AudioQuality, string> = new Map([
['64K', '64K'],
['132K', '132K'],
['192K', '192K'],
['Dolby', '杜比全景声'],
['HiRes', 'Hi-Res 无损'],
])
const codecTypeNameMap: Map<CodecType, string> = new Map([
['AVC', 'AVC (H.264)'],
['HEVC', 'HEVC (H.265)'],
['AV1', 'AV1'],
])
</script>
<template>
@@ -87,44 +93,71 @@ const audioQualitySelectOptions: SelectBaseOption<PreferAudioQuality>[] = [
<n-checkbox class="w-22" v-model:checked="store.config.download_json">json刮削</n-checkbox>
</div>
<n-tooltip placement="left" trigger="hover" class="w-20vw">
<div>如果视频有对应的画质则使用对应的画质否则选择最高画质</div>
<template #trigger>
<div class="flex items-center">
<span class="mr-2 whitespace-nowrap font-bold">优先画质</span>
<n-select
size="small"
v-model:value="store.config.prefer_video_quality"
:options="videoQualitySelectOptions" />
<div class="flex flex-justify-between">
<div>
<span class="whitespace-nowrap font-bold">画质优先级</span>
<div class="overflow-auto overflow-x-hidden h-36">
<VueDraggable
:force-fallback="true"
:fallback-on-body="true"
:animation="300"
v-model="store.config.video_quality_priority"
ghostClass="draggable-ghost"
class="select-none flex flex-col gap-2">
<ColorfulTag
class="whitespace-nowrap cursor-move"
color="blue"
v-for="videoQuality in store.config.video_quality_priority"
:key="videoQuality">
{{ videoQualityNameMap.get(videoQuality) || videoQuality }}
</ColorfulTag>
</VueDraggable>
</div>
</template>
</n-tooltip>
</div>
<n-tooltip placement="left" trigger="hover" class="w-20vw">
<div>如果视频有对应的音质则使用对应的音质否则选择最高音质</div>
<template #trigger>
<div class="flex items-center">
<span class="mr-2 whitespace-nowrap font-bold">优先音质</span>
<n-select
size="small"
v-model:value="store.config.prefer_audio_quality"
:options="audioQualitySelectOptions" />
</div>
</template>
</n-tooltip>
<div>
<span class="whitespace-nowrap font-bold">音质优先级</span>
<VueDraggable
:force-fallback="true"
:fallback-on-body="true"
v-model="store.config.audio_quality_priority"
:animation="300"
ghostClass="draggable-ghost"
class="select-none flex flex-col gap-2">
<ColorfulTag
class="whitespace-nowrap cursor-move"
color="blue"
v-for="audioQuality in store.config.audio_quality_priority"
:key="audioQuality">
{{ audioQualityNameMap.get(audioQuality) || audioQuality }}
</ColorfulTag>
</VueDraggable>
</div>
<n-tooltip placement="left" trigger="hover" class="w-20vw">
<div>如果视频有对应的编码则使用对应的编码否则按照 AVC > HEVC > AV1 的顺序选择编码</div>
<template #trigger>
<div>
<span class="mr-2 font-bold">优先编码</span>
<n-radio-group v-model:value="store.config.prefer_codec_type" size="small">
<n-radio-button value="AVC">AVC</n-radio-button>
<n-radio-button value="HEVC">HEVC</n-radio-button>
<n-radio-button value="AV1">AV1</n-radio-button>
</n-radio-group>
</div>
</template>
</n-tooltip>
<div>
<span class="whitespace-nowrap font-bold">编码优先级</span>
<VueDraggable
:force-fallback="true"
:fallback-on-body="true"
v-model="store.config.codec_type_priority"
:animation="300"
ghostClass="draggable-ghost"
class="select-none flex flex-col gap-2">
<ColorfulTag
class="whitespace-nowrap cursor-move"
color="blue"
v-for="codecType in store.config.codec_type_priority"
:key="codecType">
{{ codecTypeNameMap.get(codecType) || codecType }}
</ColorfulTag>
</VueDraggable>
</div>
</div>
</div>
</template>
<style scoped>
.draggable-ghost {
opacity: 0.5;
}
</style>