Files
FileHost/app/composables/useTranscodeSettings.ts
T

128 lines
3.6 KiB
TypeScript

interface TranscodeSettingsResponse {
concurrency: number
threads: number
preset: string
bitratePercent: number
maxConcurrency: number
maxThreads: number
minBitratePercent: number
maxBitratePercent: number
presets: string[]
memoryBytes: number
lowMemoryThresholdBytes: number
lowMemory: boolean
}
/** 服务端转码参数:并发任务数与单任务 CPU 核心数(仅管理员可改) */
export function useTranscodeSettings() {
const { isAuthenticated, isAdmin, handleAuthError } = useAuth()
const toast = useToast()
const { t } = useI18n()
const concurrency = ref(1)
const threads = ref(1)
const maxConcurrency = ref(8)
const maxThreads = ref(64)
const preset = ref('veryfast')
const presets = ref<string[]>(['veryfast', 'medium', 'slow'])
const bitratePercent = ref(80)
const minBitratePercent = ref(10)
const maxBitratePercent = ref(100)
const loaded = ref(false)
const hydrated = ref(false)
const memoryBytes = ref(0)
const lowMemoryThresholdBytes = ref(2 * 1024 * 1024 * 1024)
const lowMemory = ref(false)
let saveTimer: ReturnType<typeof setTimeout> | null = null
function apply(data: TranscodeSettingsResponse) {
hydrated.value = false
concurrency.value = data.concurrency
threads.value = data.threads
preset.value = data.preset
bitratePercent.value = data.bitratePercent
minBitratePercent.value = data.minBitratePercent ?? 10
maxBitratePercent.value = data.maxBitratePercent ?? 100
if (data.presets?.length) presets.value = data.presets
maxConcurrency.value = data.maxConcurrency
maxThreads.value = data.maxThreads
memoryBytes.value = data.memoryBytes ?? 0
lowMemoryThresholdBytes.value = data.lowMemoryThresholdBytes
?? 2 * 1024 * 1024 * 1024
lowMemory.value = data.lowMemory === true
loaded.value = true
nextTick(() => {
hydrated.value = true
})
}
async function load() {
if (!isAuthenticated.value) return
try {
apply(await $fetch<TranscodeSettingsResponse>('/api/videos/transcode-settings', {
credentials: 'include'
}))
} catch (error: unknown) {
handleAuthError(error)
if (isAuthenticated.value) {
toast.add({ title: t('preferences.transcodeLoadFailed'), color: 'error' })
}
}
}
async function save() {
if (!hydrated.value || !isAdmin.value) return
try {
const data = await $fetch<TranscodeSettingsResponse>('/api/videos/transcode-settings', {
method: 'PATCH',
credentials: 'include',
body: {
concurrency: concurrency.value,
threads: threads.value,
preset: preset.value,
bitratePercent: bitratePercent.value
}
})
hydrated.value = false
concurrency.value = data.concurrency
threads.value = data.threads
preset.value = data.preset
bitratePercent.value = data.bitratePercent
nextTick(() => {
hydrated.value = true
})
} catch (error: unknown) {
handleAuthError(error)
if (isAuthenticated.value) {
toast.add({ title: t('preferences.transcodeSaveFailed'), color: 'error' })
}
}
}
watch([concurrency, threads, preset, bitratePercent], () => {
if (!hydrated.value || !isAdmin.value) return
if (saveTimer) clearTimeout(saveTimer)
saveTimer = setTimeout(() => {
void save()
}, 600)
})
return {
concurrency,
threads,
preset,
bitratePercent,
minBitratePercent,
maxBitratePercent,
presets,
maxConcurrency,
maxThreads,
memoryBytes,
lowMemoryThresholdBytes,
lowMemory,
loaded,
load
}
}