voice-changer/client/lib/src/hooks/useServerSetting.ts

275 lines
12 KiB
TypeScript
Raw Normal View History

2023-01-12 18:06:15 +09:00
import { useState, useMemo, useRef, useEffect } from "react"
2023-01-29 09:42:45 +09:00
import { VoiceChangerServerSetting, ServerInfo, Framework, OnnxExecutionProvider, DefaultVoiceChangerServerSetting, ServerSettingKey, INDEXEDDB_KEY_SERVER } from "../const"
2023-01-12 23:01:45 +09:00
import { VoiceChangerClient } from "../VoiceChangerClient"
2023-01-29 09:42:45 +09:00
import { useIndexedDB } from "./useIndexedDB"
2023-01-12 16:38:45 +09:00
export type FileUploadSetting = {
pyTorchModel: File | null
configFile: File | null
onnxModel: File | null
}
const InitialFileUploadSetting: FileUploadSetting = {
pyTorchModel: null,
configFile: null,
onnxModel: null,
}
export type UseServerSettingProps = {
voiceChangerClient: VoiceChangerClient | null
}
export type ServerSettingState = {
setting: VoiceChangerServerSetting;
2023-01-29 09:42:45 +09:00
clearSetting: () => Promise<void>
2023-01-12 16:38:45 +09:00
serverInfo: ServerInfo | undefined;
fileUploadSetting: FileUploadSetting
setFramework: (framework: Framework) => Promise<boolean>;
setOnnxExecutionProvider: (provider: OnnxExecutionProvider) => Promise<boolean>;
setSrcId: (num: number) => Promise<boolean>;
setDstId: (num: number) => Promise<boolean>;
setConvertChunkNum: (num: number) => Promise<boolean>;
2023-01-12 21:42:02 +09:00
setMinConvertSize: (num: number) => Promise<boolean>
2023-01-12 16:38:45 +09:00
setGpu: (num: number) => Promise<boolean>;
setCrossFadeOffsetRate: (num: number) => Promise<boolean>;
setCrossFadeEndRate: (num: number) => Promise<boolean>;
setCrossFadeOverlapRate: (num: number) => Promise<boolean>;
reloadServerInfo: () => Promise<void>;
setFileUploadSetting: (val: FileUploadSetting) => void
loadModel: () => Promise<void>
uploadProgress: number
isUploading: boolean
}
export const useServerSetting = (props: UseServerSettingProps): ServerSettingState => {
const settingRef = useRef<VoiceChangerServerSetting>(DefaultVoiceChangerServerSetting)
const [setting, _setSetting] = useState<VoiceChangerServerSetting>(settingRef.current)
const [serverInfo, _setServerInfo] = useState<ServerInfo>()
const [fileUploadSetting, setFileUploadSetting] = useState<FileUploadSetting>(InitialFileUploadSetting)
2023-01-29 09:42:45 +09:00
const { setItem, getItem, removeItem } = useIndexedDB()
// 初期化 その1 DBから取得
useEffect(() => {
const loadCache = async () => {
const setting = await getItem(INDEXEDDB_KEY_SERVER)
if (!setting) {
} else {
settingRef.current = setting as VoiceChangerServerSetting
}
_setSetting({ ...settingRef.current })
}
loadCache()
}, [])
// 初期化 その2 クライアントに設定
useEffect(() => {
if (!props.voiceChangerClient) return
2023-01-29 11:14:52 +09:00
props.voiceChangerClient.updateServerSettings(ServerSettingKey.framework, setting.framework)
props.voiceChangerClient.updateServerSettings(ServerSettingKey.onnxExecutionProvider, setting.onnxExecutionProvider)
props.voiceChangerClient.updateServerSettings(ServerSettingKey.srcId, "" + setting.srcId)
props.voiceChangerClient.updateServerSettings(ServerSettingKey.dstId, "" + setting.dstId)
props.voiceChangerClient.updateServerSettings(ServerSettingKey.convertChunkNum, "" + setting.convertChunkNum)
props.voiceChangerClient.updateServerSettings(ServerSettingKey.minConvertSize, "" + setting.minConvertSize)
props.voiceChangerClient.updateServerSettings(ServerSettingKey.gpu, "" + setting.gpu)
props.voiceChangerClient.updateServerSettings(ServerSettingKey.crossFadeOffsetRate, "" + setting.crossFadeOffsetRate)
props.voiceChangerClient.updateServerSettings(ServerSettingKey.crossFadeEndRate, "" + setting.crossFadeEndRate)
props.voiceChangerClient.updateServerSettings(ServerSettingKey.crossFadeOverlapRate, "" + setting.crossFadeOverlapRate)
2023-01-29 09:42:45 +09:00
// props.voiceChangerClient.setServerUrl(settingRef.current.mmvcServerUrl)
// props.voiceChangerClient.setInputChunkNum(settingRef.current.inputChunkNum)
// props.voiceChangerClient.setProtocol(settingRef.current.protocol)
// props.voiceChangerClient.setVoiceChangerMode(settingRef.current.voiceChangerMode)
}, [props.voiceChangerClient])
2023-01-12 16:38:45 +09:00
//////////////
// 設定
/////////////
//// サーバに設定後、反映された情報と照合して値が一致していることを確認。一致していない場合はalert
const _set_and_store = async (key: ServerSettingKey, newVal: string) => {
if (!props.voiceChangerClient) return false
const res = await props.voiceChangerClient.updateServerSettings(key, "" + newVal)
_setServerInfo(res)
if (newVal == res[key]) {
2023-01-29 09:42:45 +09:00
const newSetting: VoiceChangerServerSetting = {
2023-01-12 16:38:45 +09:00
...settingRef.current,
convertChunkNum: res.convertChunkNum,
2023-01-12 21:42:02 +09:00
minConvertSize: res.minConvertSize,
2023-01-12 16:38:45 +09:00
srcId: res.srcId,
dstId: res.dstId,
gpu: res.gpu,
crossFadeOffsetRate: res.crossFadeOffsetRate,
crossFadeEndRate: res.crossFadeEndRate,
crossFadeOverlapRate: res.crossFadeOverlapRate,
framework: res.framework,
onnxExecutionProvider: (!!res.onnxExecutionProvider && res.onnxExecutionProvider.length > 0) ? res.onnxExecutionProvider[0] as OnnxExecutionProvider : DefaultVoiceChangerServerSetting.onnxExecutionProvider
2023-01-29 09:42:45 +09:00
}
_setSetting(newSetting)
setItem(INDEXEDDB_KEY_SERVER, newSetting)
2023-01-12 16:38:45 +09:00
return true
} else {
2023-01-16 07:26:24 +09:00
alert(`[ServerSetting] 設定が反映されていません([key:${key}, new:${newVal}, res:${res[key]}])。モデルの切り替えの場合、処理が非同期で行われるため反映されていないように見える場合があります。サーバコントロールのリロードボタンを押すとGUIに反映されるます。`)
2023-01-12 16:38:45 +09:00
return false
}
}
const setFramework = useMemo(() => {
return async (framework: Framework) => {
return await _set_and_store(ServerSettingKey.framework, "" + framework)
}
}, [props.voiceChangerClient])
const setOnnxExecutionProvider = useMemo(() => {
return async (provider: OnnxExecutionProvider) => {
return await _set_and_store(ServerSettingKey.onnxExecutionProvider, "" + provider)
}
}, [props.voiceChangerClient])
const setSrcId = useMemo(() => {
return async (num: number) => {
return await _set_and_store(ServerSettingKey.srcId, "" + num)
}
}, [props.voiceChangerClient])
const setDstId = useMemo(() => {
return async (num: number) => {
return await _set_and_store(ServerSettingKey.dstId, "" + num)
}
}, [props.voiceChangerClient])
const setConvertChunkNum = useMemo(() => {
return async (num: number) => {
return await _set_and_store(ServerSettingKey.convertChunkNum, "" + num)
}
}, [props.voiceChangerClient])
2023-01-12 21:42:02 +09:00
const setMinConvertSize = useMemo(() => {
return async (num: number) => {
return await _set_and_store(ServerSettingKey.minConvertSize, "" + num)
}
}, [props.voiceChangerClient])
2023-01-12 16:38:45 +09:00
const setGpu = useMemo(() => {
return async (num: number) => {
return await _set_and_store(ServerSettingKey.gpu, "" + num)
}
}, [props.voiceChangerClient])
const setCrossFadeOffsetRate = useMemo(() => {
return async (num: number) => {
return await _set_and_store(ServerSettingKey.crossFadeOffsetRate, "" + num)
}
}, [props.voiceChangerClient])
const setCrossFadeEndRate = useMemo(() => {
return async (num: number) => {
return await _set_and_store(ServerSettingKey.crossFadeEndRate, "" + num)
}
}, [props.voiceChangerClient])
const setCrossFadeOverlapRate = useMemo(() => {
return async (num: number) => {
return await _set_and_store(ServerSettingKey.crossFadeOverlapRate, "" + num)
}
}, [props.voiceChangerClient])
2023-01-12 21:42:02 +09:00
2023-01-12 16:38:45 +09:00
//////////////
// 操作
/////////////
const [uploadProgress, setUploadProgress] = useState<number>(0)
const [isUploading, setIsUploading] = useState<boolean>(false)
// (e) モデルアップロード
const _uploadFile = useMemo(() => {
return async (file: File, onprogress: (progress: number, end: boolean) => void) => {
if (!props.voiceChangerClient) return
const num = await props.voiceChangerClient.uploadFile(file, onprogress)
const res = await props.voiceChangerClient.concatUploadedFile(file, num)
console.log("uploaded", num, res)
}
}, [props.voiceChangerClient])
const loadModel = useMemo(() => {
return async () => {
if (!fileUploadSetting.pyTorchModel && !fileUploadSetting.onnxModel) {
alert("PyTorchモデルとONNXモデルのどちらか一つ以上指定する必要があります。")
return
}
if (!fileUploadSetting.configFile) {
alert("Configファイルを指定する必要があります。")
return
}
if (!props.voiceChangerClient) return
setUploadProgress(0)
setIsUploading(true)
const models = [fileUploadSetting.pyTorchModel, fileUploadSetting.onnxModel].filter(x => { return x != null }) as File[]
for (let i = 0; i < models.length; i++) {
const progRate = 1 / models.length
const progOffset = 100 * i * progRate
2023-01-12 23:01:45 +09:00
await _uploadFile(models[i], (progress: number, _end: boolean) => {
2023-01-12 16:38:45 +09:00
// console.log(progress * progRate + progOffset, end, progRate,)
setUploadProgress(progress * progRate + progOffset)
})
}
await _uploadFile(fileUploadSetting.configFile, (progress: number, end: boolean) => {
console.log(progress, end)
})
2023-01-28 15:56:56 +09:00
await props.voiceChangerClient.loadModel(fileUploadSetting.configFile, fileUploadSetting.pyTorchModel, fileUploadSetting.onnxModel)
2023-01-12 16:38:45 +09:00
setUploadProgress(0)
setIsUploading(false)
2023-01-28 15:56:56 +09:00
reloadServerInfo()
2023-01-12 16:38:45 +09:00
}
}, [fileUploadSetting, props.voiceChangerClient])
const reloadServerInfo = useMemo(() => {
return async () => {
if (!props.voiceChangerClient) return
const res = await props.voiceChangerClient.getServerSettings()
_setServerInfo(res)
_setSetting({
...settingRef.current,
convertChunkNum: res.convertChunkNum,
srcId: res.srcId,
dstId: res.dstId,
gpu: res.gpu,
crossFadeOffsetRate: res.crossFadeOffsetRate,
crossFadeEndRate: res.crossFadeEndRate,
crossFadeOverlapRate: res.crossFadeOverlapRate,
framework: res.framework,
onnxExecutionProvider: (!!res.onnxExecutionProvider && res.onnxExecutionProvider.length > 0) ? res.onnxExecutionProvider[0] as OnnxExecutionProvider : DefaultVoiceChangerServerSetting.onnxExecutionProvider
})
}
}, [props.voiceChangerClient])
2023-01-29 09:42:45 +09:00
const clearSetting = async () => {
await removeItem(INDEXEDDB_KEY_SERVER)
}
2023-01-12 18:06:15 +09:00
2023-01-12 16:38:45 +09:00
return {
setting,
2023-01-29 09:42:45 +09:00
clearSetting,
2023-01-12 16:38:45 +09:00
serverInfo,
fileUploadSetting,
setFramework,
setOnnxExecutionProvider,
setSrcId,
setDstId,
setConvertChunkNum,
2023-01-12 21:42:02 +09:00
setMinConvertSize,
2023-01-12 16:38:45 +09:00
setGpu,
setCrossFadeOffsetRate,
setCrossFadeEndRate,
setCrossFadeOverlapRate,
reloadServerInfo,
setFileUploadSetting,
loadModel,
uploadProgress,
isUploading,
}
}