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

262 lines
12 KiB
TypeScript
Raw Normal View History

import { useState, useMemo, useEffect } from "react"
2023-03-19 01:43:36 +09:00
import { VoiceChangerServerSetting, ServerInfo, ServerSettingKey, INDEXEDDB_KEY_SERVER, INDEXEDDB_KEY_MODEL_DATA, ClientType, DefaultServerSetting_MMVCv13, DefaultServerSetting_MMVCv15, DefaultServerSetting_so_vits_svc_40v2, DefaultServerSetting_so_vits_svc_40 } 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
2023-01-29 14:41:44 +09:00
type ModelData = {
2023-01-29 15:25:44 +09:00
file?: File
data?: ArrayBuffer
filename?: string
2023-01-29 14:41:44 +09:00
}
2023-01-12 16:38:45 +09:00
export type FileUploadSetting = {
2023-01-29 14:41:44 +09:00
pyTorchModel: ModelData | null
onnxModel: ModelData | null
configFile: ModelData | null
clusterTorchModel: ModelData | null
hubertTorchModel: ModelData | null // !! 注意!! hubertTorchModelは固定値で上書きされるため、設定しても効果ない。
2023-01-12 16:38:45 +09:00
}
2023-01-29 14:41:44 +09:00
2023-01-12 16:38:45 +09:00
const InitialFileUploadSetting: FileUploadSetting = {
pyTorchModel: null,
configFile: null,
onnxModel: null,
clusterTorchModel: null,
hubertTorchModel: null,
2023-01-12 16:38:45 +09:00
}
2023-01-29 14:41:44 +09:00
2023-01-12 16:38:45 +09:00
export type UseServerSettingProps = {
2023-03-09 06:47:11 +09:00
clientType: ClientType
2023-01-12 16:38:45 +09:00
voiceChangerClient: VoiceChangerClient | null
}
export type ServerSettingState = {
serverSetting: ServerInfo
updateServerSettings: (setting: ServerInfo) => Promise<void>
2023-01-29 09:42:45 +09:00
clearSetting: () => Promise<void>
2023-01-12 16:38:45 +09:00
reloadServerInfo: () => Promise<void>;
fileUploadSetting: FileUploadSetting
2023-01-12 16:38:45 +09:00
setFileUploadSetting: (val: FileUploadSetting) => void
loadModel: () => Promise<void>
uploadProgress: number
isUploading: boolean
2023-01-12 16:38:45 +09:00
}
export const useServerSetting = (props: UseServerSettingProps): ServerSettingState => {
// const settingRef = useRef<VoiceChangerServerSetting>(DefaultVoiceChangerServerSetting)
2023-03-09 06:55:57 +09:00
const defaultServerSetting = useMemo(() => {
if (props.clientType == "MMVCv13") {
return DefaultServerSetting_MMVCv13
} else if (props.clientType == "MMVCv15") {
return DefaultServerSetting_MMVCv15
2023-03-19 01:43:36 +09:00
} else if (props.clientType == "so_vits_svc_40") {
return DefaultServerSetting_so_vits_svc_40
2023-03-15 22:43:59 +09:00
} else if (props.clientType == "so_vits_svc_40v2" || props.clientType == "so_vits_svc_40v2_tsukuyomi") {
2023-03-11 08:37:41 +09:00
return DefaultServerSetting_so_vits_svc_40v2
2023-03-09 06:55:57 +09:00
} else {
return DefaultServerSetting_MMVCv15
}
}, [])
const [serverSetting, setServerSetting] = useState<ServerInfo>(defaultServerSetting)
2023-01-12 16:38:45 +09:00
const [fileUploadSetting, setFileUploadSetting] = useState<FileUploadSetting>(InitialFileUploadSetting)
2023-03-09 06:47:11 +09:00
const { setItem, getItem, removeItem } = useIndexedDB({ clientType: props.clientType })
2023-01-29 09:42:45 +09:00
// DBから設定取得キャッシュによる初期化
2023-01-29 09:42:45 +09:00
useEffect(() => {
const loadCache = async () => {
const setting = await getItem(INDEXEDDB_KEY_SERVER)
if (!setting) {
} else {
setServerSetting(setting as ServerInfo)
2023-01-29 09:42:45 +09:00
}
2023-01-29 15:25:44 +09:00
const fileuploadSetting = await getItem(INDEXEDDB_KEY_MODEL_DATA)
if (!fileuploadSetting) {
} else {
setFileUploadSetting(fileuploadSetting as FileUploadSetting)
}
2023-01-29 09:42:45 +09:00
}
loadCache()
}, [])
// クライアントへ設定反映 (キャッシュ反映)
2023-01-29 09:42:45 +09:00
useEffect(() => {
if (!props.voiceChangerClient) return
for (let i = 0; i < Object.values(ServerSettingKey).length; i++) {
const k = Object.values(ServerSettingKey)[i] as keyof VoiceChangerServerSetting
const v = serverSetting[k]
if (v) {
props.voiceChangerClient.updateServerSettings(k, "" + v)
}
}
reloadServerInfo()
}, [props.voiceChangerClient])
2023-01-12 16:38:45 +09:00
//////////////
// 設定
/////////////
const updateServerSettings = useMemo(() => {
return async (setting: ServerInfo) => {
if (!props.voiceChangerClient) return
for (let i = 0; i < Object.values(ServerSettingKey).length; i++) {
const k = Object.values(ServerSettingKey)[i] as keyof VoiceChangerServerSetting
const cur_v = serverSetting[k]
const new_v = setting[k]
if (cur_v != new_v) {
const res = await props.voiceChangerClient.updateServerSettings(k, "" + new_v)
2023-02-21 17:54:02 +09:00
if (res.onnxExecutionProviders.length > 0) {
res.onnxExecutionProvider = res.onnxExecutionProviders[0]
} else {
res.onnxExecutionProvider = "CPUExecutionProvider"
}
setServerSetting(res)
2023-02-20 07:46:33 +09:00
const storeData = { ...res }
storeData.recordIO = 0
setItem(INDEXEDDB_KEY_SERVER, storeData)
}
2023-01-29 09:42:45 +09:00
}
2023-01-12 16:38:45 +09:00
}
}, [props.voiceChangerClient, serverSetting])
2023-01-12 16:38:45 +09:00
//////////////
// 操作
/////////////
const [uploadProgress, setUploadProgress] = useState<number>(0)
const [isUploading, setIsUploading] = useState<boolean>(false)
// (e) モデルアップロード
const _uploadFile = useMemo(() => {
2023-01-29 14:41:44 +09:00
return async (modelData: ModelData, onprogress: (progress: number, end: boolean) => void) => {
2023-01-12 16:38:45 +09:00
if (!props.voiceChangerClient) return
2023-01-29 15:25:44 +09:00
const num = await props.voiceChangerClient.uploadFile(modelData.data!, modelData.filename!, onprogress)
const res = await props.voiceChangerClient.concatUploadedFile(modelData.filename!, num)
2023-01-12 16:38:45 +09:00
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.clientType == "so_vits_svc_40v2c" && !fileUploadSetting.hubertTorchModel) {
// alert("content vecのファイルを指定する必要があります。")
// return
// }
2023-01-12 16:38:45 +09:00
if (!props.voiceChangerClient) return
2023-01-29 14:41:44 +09:00
2023-01-12 16:38:45 +09:00
setUploadProgress(0)
setIsUploading(true)
2023-01-29 14:41:44 +09:00
2023-01-29 15:25:44 +09:00
// ファイルをメモリにロード
if (fileUploadSetting.onnxModel && !fileUploadSetting.onnxModel.data) {
fileUploadSetting.onnxModel.data = await fileUploadSetting.onnxModel.file!.arrayBuffer()
fileUploadSetting.onnxModel.filename = await fileUploadSetting.onnxModel.file!.name
}
if (fileUploadSetting.pyTorchModel && !fileUploadSetting.pyTorchModel.data) {
fileUploadSetting.pyTorchModel.data = await fileUploadSetting.pyTorchModel.file!.arrayBuffer()
fileUploadSetting.pyTorchModel.filename = await fileUploadSetting.pyTorchModel.file!.name
}
if (!fileUploadSetting.configFile.data) {
fileUploadSetting.configFile.data = await fileUploadSetting.configFile.file!.arrayBuffer()
fileUploadSetting.configFile.filename = await fileUploadSetting.configFile.file!.name
}
// if (props.clientType == "so_vits_svc_40v2c" && !fileUploadSetting.hubertTorchModel!.data) {
// fileUploadSetting.hubertTorchModel!.data = await fileUploadSetting.hubertTorchModel!.file!.arrayBuffer()
// fileUploadSetting.hubertTorchModel!.filename = await fileUploadSetting.hubertTorchModel!.file!.name
// }
2023-03-14 11:04:00 +09:00
if (fileUploadSetting.clusterTorchModel) {
2023-03-19 01:43:36 +09:00
if ((props.clientType == "so_vits_svc_40v2" || props.clientType == "so_vits_svc_40") && !fileUploadSetting.clusterTorchModel!.data) {
2023-03-14 11:04:00 +09:00
fileUploadSetting.clusterTorchModel!.data = await fileUploadSetting.clusterTorchModel!.file!.arrayBuffer()
fileUploadSetting.clusterTorchModel!.filename = await fileUploadSetting.clusterTorchModel!.file!.name
}
}
2023-03-15 22:43:59 +09:00
2023-01-29 15:25:44 +09:00
// ファイルをサーバにアップロード
const models = [fileUploadSetting.onnxModel, fileUploadSetting.pyTorchModel, fileUploadSetting.clusterTorchModel /*, fileUploadSetting.hubertTorchModel*/].filter(x => { return x != null }) as ModelData[]
2023-01-12 16:38:45 +09:00
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)
})
// !! 注意!! hubertTorchModelは固定値で上書きされるため、設定しても効果ない。
const loadPromise = props.voiceChangerClient.loadModel(fileUploadSetting.configFile.filename!, fileUploadSetting.pyTorchModel?.filename || null, fileUploadSetting.onnxModel?.filename || null, fileUploadSetting.clusterTorchModel?.filename || null, fileUploadSetting.hubertTorchModel?.filename || null)
2023-01-29 15:25:44 +09:00
// サーバでロード中にキャッシュにセーブ
try {
const saveData: FileUploadSetting = {
pyTorchModel: fileUploadSetting.pyTorchModel ? { data: fileUploadSetting.pyTorchModel.data, filename: fileUploadSetting.pyTorchModel.filename } : null,
onnxModel: fileUploadSetting.onnxModel ? { data: fileUploadSetting.onnxModel.data, filename: fileUploadSetting.onnxModel.filename } : null,
configFile: { data: fileUploadSetting.configFile.data, filename: fileUploadSetting.configFile.filename },
hubertTorchModel: fileUploadSetting.hubertTorchModel ? {
data: fileUploadSetting.hubertTorchModel.data, filename: fileUploadSetting.hubertTorchModel.filename
} : null,
clusterTorchModel: fileUploadSetting.clusterTorchModel ? {
data: fileUploadSetting.clusterTorchModel.data, filename: fileUploadSetting.clusterTorchModel.filename
} : null
}
setItem(INDEXEDDB_KEY_MODEL_DATA, saveData)
2023-03-13 21:07:35 +09:00
} catch (e) {
console.log("Excpetion:::::::::", e)
2023-01-29 15:25:44 +09:00
}
await loadPromise
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
}
2023-03-13 21:07:35 +09:00
}, [fileUploadSetting, props.voiceChangerClient, props.clientType])
2023-01-12 16:38:45 +09:00
const reloadServerInfo = useMemo(() => {
return async () => {
console.log("reload server info")
2023-01-12 16:38:45 +09:00
if (!props.voiceChangerClient) return
const res = await props.voiceChangerClient.getServerSettings()
setServerSetting(res)
2023-02-20 07:46:33 +09:00
const storeData = { ...res }
storeData.recordIO = 0
setItem(INDEXEDDB_KEY_SERVER, storeData)
2023-01-12 16:38:45 +09:00
}
}, [props.voiceChangerClient])
2023-01-29 09:42:45 +09:00
const clearSetting = async () => {
await removeItem(INDEXEDDB_KEY_SERVER)
2023-01-29 15:25:44 +09:00
await removeItem(INDEXEDDB_KEY_MODEL_DATA)
2023-01-29 09:42:45 +09:00
}
2023-01-12 18:06:15 +09:00
2023-01-12 16:38:45 +09:00
return {
serverSetting,
updateServerSettings,
2023-01-29 09:42:45 +09:00
clearSetting,
2023-01-12 16:38:45 +09:00
reloadServerInfo,
fileUploadSetting,
2023-01-12 16:38:45 +09:00
setFileUploadSetting,
loadModel,
uploadProgress,
isUploading,
}
}