mirror of
https://github.com/w-okada/voice-changer.git
synced 2025-01-23 21:45:00 +03:00
WIP: slot manager
This commit is contained in:
parent
16598b3034
commit
bc5fd76cc2
6
client/demo/dist/index.js
vendored
6
client/demo/dist/index.js
vendored
File diff suppressed because one or more lines are too long
@ -28,6 +28,10 @@ export const ModelSlotManagerDialog = () => {
|
|||||||
const [lang, setLang] = useState<string>("All")
|
const [lang, setLang] = useState<string>("All")
|
||||||
const [sampleId, setSampleId] = useState<string>("")
|
const [sampleId, setSampleId] = useState<string>("")
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
// Slot Manager
|
||||||
|
/////////////////////////////////////////
|
||||||
const localFileContent = useMemo(() => {
|
const localFileContent = useMemo(() => {
|
||||||
if (mode != "localFile") {
|
if (mode != "localFile") {
|
||||||
return <></>
|
return <></>
|
||||||
@ -125,39 +129,71 @@ export const ModelSlotManagerDialog = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const isRegisterd = modelFileName.length > 0 ? true : false
|
||||||
|
const name = x.name && x.name.length > 0 ? x.name : isRegisterd ? modelFileName : "blank"
|
||||||
const termOfUseUrlLink = x.termsOfUseUrl.length > 0 ? <a href={x.termsOfUseUrl} target="_blank" rel="noopener noreferrer" className="body-item-text-small">[terms of use]</a> : <></>
|
const termOfUseUrlLink = x.termsOfUseUrl.length > 0 ? <a href={x.termsOfUseUrl} target="_blank" rel="noopener noreferrer" className="body-item-text-small">[terms of use]</a> : <></>
|
||||||
|
|
||||||
const fileValueClass = (uploadData?.slot == index) ? "model-slot-detail-row-value-edit" : "model-slot-detail-row-value"
|
const nameValueClass = isRegisterd ? "model-slot-detail-row-value-pointable" : "model-slot-detail-row-value"
|
||||||
|
const nameValueAction = isRegisterd ? async (index: number) => {
|
||||||
|
const name = window.prompt("input new name", "");
|
||||||
|
if (!name) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await serverSetting.updateModelInfo(index, "name", name)
|
||||||
|
console.log(name)
|
||||||
|
} : async (_index: number) => { }
|
||||||
|
const iconClass = isRegisterd ? "model-slot-icon-pointable" : "model-slot-icon"
|
||||||
|
const iconAction = isRegisterd ? async (index: number) => {
|
||||||
|
const file = await fileSelector("")
|
||||||
|
if (checkExtention(file.name, ["png", "jpg", "jpeg", "gif"]) == false) {
|
||||||
|
alert(`モデルファイルの拡張子は".png", ".jpg", ".jpeg", ".gif"である必要があります。`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
await serverSetting.uploadAssets(index, "iconFile", file)
|
||||||
|
} : async (_index: number) => { }
|
||||||
|
|
||||||
|
const fileValueClass = (uploadData?.slot == index) ? "model-slot-detail-row-value-edit" : isRegisterd ? "model-slot-detail-row-value-download" : "model-slot-detail-row-value"
|
||||||
|
const fileValueAction = (uploadData?.slot == index) ? (url: string) => {
|
||||||
|
} : (url: string) => {
|
||||||
|
const link = document.createElement("a")
|
||||||
|
link.href = url
|
||||||
|
link.download = url.replace(/^.*[\\\/]/, '')
|
||||||
|
link.click()
|
||||||
|
}
|
||||||
|
|
||||||
const iconUrl = x.modelFile && x.modelFile.length > 0 ? (x.iconFile && x.iconFile.length > 0 ? x.iconFile : "/assets/icons/noimage.png") : "/assets/icons/blank.png"
|
const iconUrl = x.modelFile && x.modelFile.length > 0 ? (x.iconFile && x.iconFile.length > 0 ? x.iconFile : "/assets/icons/noimage.png") : "/assets/icons/blank.png"
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div key={index} className="model-slot">
|
<div key={index} className="model-slot">
|
||||||
<img src={iconUrl} className="model-slot-icon"></img>
|
<img src={iconUrl} className={iconClass} onClick={() => { iconAction(index) }}></img>
|
||||||
<div className="model-slot-detail">
|
<div className="model-slot-detail">
|
||||||
<div className="model-slot-detail-row">
|
<div className="model-slot-detail-row">
|
||||||
<div className="model-slot-detail-row-label">[{index}]</div>
|
<div className="model-slot-detail-row-label">[{index}]</div>
|
||||||
<div className="model-slot-detail-row-value">{x.name}</div>
|
<div className={nameValueClass} onClick={() => { nameValueAction(index) }}>{name}</div>
|
||||||
<div className="">{termOfUseUrlLink}</div>
|
<div className="">{termOfUseUrlLink}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="model-slot-detail-row">
|
<div className="model-slot-detail-row">
|
||||||
<div className="model-slot-detail-row-label">model:</div>
|
<div className="model-slot-detail-row-label">model:</div>
|
||||||
<div className={fileValueClass}>{modelFileName}</div>
|
<div className={fileValueClass} onClick={() => { fileValueAction(x.modelFile) }}>{modelFileName}</div>
|
||||||
<div className="model-slot-button model-slot-detail-row-button" onClick={() => { onRVCModelLoadClicked(index) }}>select</div>
|
<div className="model-slot-button model-slot-detail-row-button" onClick={() => { onRVCModelLoadClicked(index) }}>select</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="model-slot-detail-row">
|
<div className="model-slot-detail-row">
|
||||||
<div className="model-slot-detail-row-label">index:</div>
|
<div className="model-slot-detail-row-label">index:</div>
|
||||||
<div className={fileValueClass}>{indexFileName}</div>
|
<div className={fileValueClass} onClick={() => { fileValueAction(x.indexFile) }}>{indexFileName}</div>
|
||||||
<div className="model-slot-button model-slot-detail-row-button" onClick={() => { onRVCIndexLoadClicked(index) }}>select</div>
|
<div className="model-slot-button model-slot-detail-row-button" onClick={() => { onRVCIndexLoadClicked(index) }}>select</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="model-slot-detail-row">
|
<div className="model-slot-detail-row">
|
||||||
<div className="model-slot-detail-row-label">info: </div>
|
<div className="model-slot-detail-row-label">info: </div>
|
||||||
<div className="model-slot-detail-row-value">f0, 40k, 768, onnx, tune, i-rate, p-rate</div>
|
<div className="model-slot-detail-row-value">{x.f0 ? "f0" : "nof0"}, {x.samplingRate}, {x.embChannels}, {x.modelType}, {x.defaultTune}, {x.defaultIndexRatio}, {x.defaultProtect}</div>
|
||||||
<div className=""></div>
|
<div className=""></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="model-slot-buttons">
|
<div className="model-slot-buttons">
|
||||||
<div className="model-slot-button" onClick={() => { onOpenSampleDownloadDialog(index) }}>from net</div>
|
{(uploadData?.slot == index) && (uploadData.model != null) ?
|
||||||
|
<div></div> :
|
||||||
|
<div className="model-slot-button" onClick={() => { onOpenSampleDownloadDialog(index) }}>DL sample>> </div>
|
||||||
|
}
|
||||||
|
|
||||||
{(uploadData?.slot == index) && (uploadData.model != null) ?
|
{(uploadData?.slot == index) && (uploadData.model != null) ?
|
||||||
<div className="model-slot-button" onClick={onUploadClicked}>upload</div> : <div></div>
|
<div className="model-slot-button" onClick={onUploadClicked}>upload</div> : <div></div>
|
||||||
@ -166,7 +202,7 @@ export const ModelSlotManagerDialog = () => {
|
|||||||
<div className="model-slot-button" onClick={onClearClicked}>clear</div> : <div></div>
|
<div className="model-slot-button" onClick={onClearClicked}>clear</div> : <div></div>
|
||||||
}
|
}
|
||||||
{(uploadData?.slot == index) && (uploadData.model != null) ?
|
{(uploadData?.slot == index) && (uploadData.model != null) ?
|
||||||
<div>%</div> : <div></div>
|
<div>{serverSetting.uploadProgress.toFixed(1)}%</div> : <div></div>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -185,14 +221,16 @@ export const ModelSlotManagerDialog = () => {
|
|||||||
mode,
|
mode,
|
||||||
serverSetting.serverSetting.modelSlots,
|
serverSetting.serverSetting.modelSlots,
|
||||||
serverSetting.fileUploadSettings,
|
serverSetting.fileUploadSettings,
|
||||||
|
serverSetting.uploadProgress,
|
||||||
serverSetting.setFileUploadSetting,
|
serverSetting.setFileUploadSetting,
|
||||||
serverSetting.loadModel,
|
serverSetting.loadModel,
|
||||||
uploadData
|
uploadData
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
/////////////////////////////////////////
|
||||||
|
// Sample Downloader
|
||||||
|
/////////////////////////////////////////
|
||||||
const fromNetContent = useMemo(() => {
|
const fromNetContent = useMemo(() => {
|
||||||
if (mode != "fromNet") {
|
if (mode != "fromNet") {
|
||||||
return <></>
|
return <></>
|
||||||
@ -236,7 +274,7 @@ export const ModelSlotManagerDialog = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="model-slot-detail-row">
|
<div className="model-slot-detail-row">
|
||||||
<div className="model-slot-detail-row-label">info: </div>
|
<div className="model-slot-detail-row-label">info: </div>
|
||||||
<div className="model-slot-detail-row-value">f0, 40k, 768, onnx, tune, i-rate, p-rate</div>
|
<div className="model-slot-detail-row-value">{x.modelType},{x.f0 ? "f0" : "nof0"},{x.sampleRate}</div>
|
||||||
<div className=""></div>
|
<div className=""></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -249,8 +287,8 @@ export const ModelSlotManagerDialog = () => {
|
|||||||
)
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="">
|
||||||
<div>Select Sample for Slot[{fromNetTargetIndex}] <span onClick={() => { setMode("localFile") }}>back</span></div>
|
<div className="model-slot-header">Select Sample for Slot[{fromNetTargetIndex}] <span onClick={() => { setMode("localFile") }} className="model-slot-header-button"><<back</span></div>
|
||||||
<div>Lang:
|
<div>Lang:
|
||||||
<select value={lang} onChange={(e) => { setLang(e.target.value) }}>
|
<select value={lang} onChange={(e) => { setLang(e.target.value) }}>
|
||||||
{langOptions}
|
{langOptions}
|
||||||
|
@ -726,6 +726,23 @@ body {
|
|||||||
.dialog-fixed-size-content {
|
.dialog-fixed-size-content {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
max-height: 70vh;
|
max-height: 70vh;
|
||||||
|
.model-slot-header {
|
||||||
|
font-weight: 700;
|
||||||
|
.model-slot-header-button {
|
||||||
|
font-weight: 400;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
user-select: none;
|
||||||
|
border: solid 1px #999;
|
||||||
|
border-radius: 2px;
|
||||||
|
cursor: pointer;
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: center;
|
||||||
|
padding: 1px;
|
||||||
|
&:hover {
|
||||||
|
border: solid 1px #000;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
.model-slot-container {
|
.model-slot-container {
|
||||||
max-height: 60vh;
|
max-height: 60vh;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
@ -738,6 +755,11 @@ body {
|
|||||||
width: 5rem;
|
width: 5rem;
|
||||||
height: 5rem;
|
height: 5rem;
|
||||||
}
|
}
|
||||||
|
.model-slot-icon-pointable {
|
||||||
|
width: 5rem;
|
||||||
|
height: 5rem;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
.model-slot-detail {
|
.model-slot-detail {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -754,6 +776,16 @@ body {
|
|||||||
width: 60%;
|
width: 60%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
.model-slot-detail-row-value-download {
|
||||||
|
width: 60%;
|
||||||
|
white-space: nowrap;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.model-slot-detail-row-value-pointable {
|
||||||
|
width: 60%;
|
||||||
|
white-space: nowrap;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
.model-slot-detail-row-value-edit {
|
.model-slot-detail-row-value-edit {
|
||||||
width: 60%;
|
width: 60%;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
@ -188,6 +188,22 @@ export class ServerConfigurator {
|
|||||||
return await info
|
return await info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uploadAssets = async (params: string) => {
|
||||||
|
const url = this.serverUrl + "/upload_model_assets"
|
||||||
|
const info = new Promise<ServerInfo>(async (resolve) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("params", params);
|
||||||
|
|
||||||
|
const request = new Request(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
});
|
||||||
|
const res = await (await fetch(request)).json() as ServerInfo
|
||||||
|
resolve(res)
|
||||||
|
})
|
||||||
|
return await info
|
||||||
|
}
|
||||||
|
|
||||||
switchModelType = async (clinetType: ClientType) => {
|
switchModelType = async (clinetType: ClientType) => {
|
||||||
const url = this.serverUrl + "/model_type"
|
const url = this.serverUrl + "/model_type"
|
||||||
const info = new Promise<ServerInfo>(async (resolve) => {
|
const info = new Promise<ServerInfo>(async (resolve) => {
|
||||||
@ -258,5 +274,23 @@ export class ServerConfigurator {
|
|||||||
return await info
|
return await info
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateModelInfo = async (slot: number, key: string, val: string) => {
|
||||||
|
const url = this.serverUrl + "/update_model_info"
|
||||||
|
const newData = { slot, key, val }
|
||||||
|
|
||||||
|
const info = new Promise<ServerInfo>(async (resolve) => {
|
||||||
|
const formData = new FormData();
|
||||||
|
formData.append("newData", JSON.stringify(newData));
|
||||||
|
|
||||||
|
const request = new Request(url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: formData,
|
||||||
|
});
|
||||||
|
const res = await (await fetch(request)).json() as ServerInfo
|
||||||
|
console.log("RESPONSE", res)
|
||||||
|
resolve(res)
|
||||||
|
})
|
||||||
|
return await info
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -279,6 +279,9 @@ export class VoiceChangerClient {
|
|||||||
updateModelDefault = async () => {
|
updateModelDefault = async () => {
|
||||||
return this.configurator.updateModelDefault()
|
return this.configurator.updateModelDefault()
|
||||||
}
|
}
|
||||||
|
updateModelInfo = async (slot: number, key: string, val: string) => {
|
||||||
|
return this.configurator.updateModelInfo(slot, key, val)
|
||||||
|
}
|
||||||
|
|
||||||
updateServerSettings = (key: ServerSettingKey, val: string) => {
|
updateServerSettings = (key: ServerSettingKey, val: string) => {
|
||||||
return this.configurator.updateSettings(key, val)
|
return this.configurator.updateSettings(key, val)
|
||||||
@ -299,6 +302,9 @@ export class VoiceChangerClient {
|
|||||||
) => {
|
) => {
|
||||||
return this.configurator.loadModel(slot, isHalf, params)
|
return this.configurator.loadModel(slot, isHalf, params)
|
||||||
}
|
}
|
||||||
|
uploadAssets = (params: string) => {
|
||||||
|
return this.configurator.uploadAssets(params)
|
||||||
|
}
|
||||||
|
|
||||||
//## Worklet ##//
|
//## Worklet ##//
|
||||||
configureWorklet = (setting: WorkletSetting) => {
|
configureWorklet = (setting: WorkletSetting) => {
|
||||||
|
@ -254,8 +254,11 @@ export type RVCSampleModel = {
|
|||||||
credit: string
|
credit: string
|
||||||
description: string
|
description: string
|
||||||
lang: string
|
lang: string
|
||||||
tag: string
|
tag: string[]
|
||||||
icon: string
|
icon: string
|
||||||
|
f0: boolean
|
||||||
|
sampleRate: number
|
||||||
|
modelType: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DefaultServerSetting: ServerInfo = {
|
export const DefaultServerSetting: ServerInfo = {
|
||||||
|
@ -10,6 +10,12 @@ type ModelData = {
|
|||||||
filename?: string
|
filename?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const ModelAssetName = {
|
||||||
|
iconFile: "iconFile"
|
||||||
|
} as const
|
||||||
|
export type ModelAssetName = typeof ModelAssetName[keyof typeof ModelAssetName]
|
||||||
|
|
||||||
|
|
||||||
export type FileUploadSetting = {
|
export type FileUploadSetting = {
|
||||||
isHalf: boolean
|
isHalf: boolean
|
||||||
uploaded: boolean
|
uploaded: boolean
|
||||||
@ -76,8 +82,12 @@ export const InitialFileUploadSetting: FileUploadSetting = {
|
|||||||
ddspSvcModelConfig: null,
|
ddspSvcModelConfig: null,
|
||||||
ddspSvcDiffusion: null,
|
ddspSvcDiffusion: null,
|
||||||
ddspSvcDiffusionConfig: null,
|
ddspSvcDiffusionConfig: null,
|
||||||
|
}
|
||||||
|
|
||||||
|
type AssetUploadSetting = {
|
||||||
|
slot: number
|
||||||
|
name: ModelAssetName
|
||||||
|
file: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type UseServerSettingProps = {
|
export type UseServerSettingProps = {
|
||||||
@ -100,7 +110,8 @@ export type ServerSettingState = {
|
|||||||
getOnnx: () => Promise<OnnxExporterInfo>
|
getOnnx: () => Promise<OnnxExporterInfo>
|
||||||
mergeModel: (request: MergeModelRequest) => Promise<ServerInfo>
|
mergeModel: (request: MergeModelRequest) => Promise<ServerInfo>
|
||||||
updateModelDefault: () => Promise<ServerInfo>
|
updateModelDefault: () => Promise<ServerInfo>
|
||||||
|
updateModelInfo: (slot: number, key: string, val: string) => Promise<ServerInfo>
|
||||||
|
uploadAssets: (slot: number, name: ModelAssetName, file: File) => Promise<void>
|
||||||
}
|
}
|
||||||
|
|
||||||
export const useServerSetting = (props: UseServerSettingProps): ServerSettingState => {
|
export const useServerSetting = (props: UseServerSettingProps): ServerSettingState => {
|
||||||
@ -501,6 +512,25 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
const uploadAssets = useMemo(() => {
|
||||||
|
return async (slot: number, name: ModelAssetName, file: File) => {
|
||||||
|
if (!props.voiceChangerClient) return
|
||||||
|
|
||||||
|
await _uploadFile2(file, (progress: number, _end: boolean) => {
|
||||||
|
console.log(progress, _end)
|
||||||
|
})
|
||||||
|
const assetUploadSetting: AssetUploadSetting = {
|
||||||
|
slot,
|
||||||
|
name,
|
||||||
|
file: file.name
|
||||||
|
}
|
||||||
|
await props.voiceChangerClient.uploadAssets(JSON.stringify(assetUploadSetting))
|
||||||
|
reloadServerInfo()
|
||||||
|
}
|
||||||
|
}, [fileUploadSettings, props.voiceChangerClient, props.clientType])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const reloadServerInfo = useMemo(() => {
|
const reloadServerInfo = useMemo(() => {
|
||||||
return async () => {
|
return async () => {
|
||||||
|
|
||||||
@ -538,6 +568,11 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
|||||||
setServerSetting(serverInfo)
|
setServerSetting(serverInfo)
|
||||||
return serverInfo
|
return serverInfo
|
||||||
}
|
}
|
||||||
|
const updateModelInfo = async (slot: number, key: string, val: string) => {
|
||||||
|
const serverInfo = await props.voiceChangerClient!.updateModelInfo(slot, key, val)
|
||||||
|
setServerSetting(serverInfo)
|
||||||
|
return serverInfo
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
serverSetting,
|
serverSetting,
|
||||||
@ -553,5 +588,7 @@ export const useServerSetting = (props: UseServerSettingProps): ServerSettingSta
|
|||||||
getOnnx,
|
getOnnx,
|
||||||
mergeModel,
|
mergeModel,
|
||||||
updateModelDefault,
|
updateModelDefault,
|
||||||
|
updateModelInfo,
|
||||||
|
uploadAssets
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -43,6 +43,12 @@ class MMVC_Rest_Fileuploader:
|
|||||||
self.router.add_api_route(
|
self.router.add_api_route(
|
||||||
"/update_model_default", self.post_update_model_default, methods=["POST"]
|
"/update_model_default", self.post_update_model_default, methods=["POST"]
|
||||||
)
|
)
|
||||||
|
self.router.add_api_route(
|
||||||
|
"/update_model_info", self.post_update_model_info, methods=["POST"]
|
||||||
|
)
|
||||||
|
self.router.add_api_route(
|
||||||
|
"/upload_model_assets", self.post_upload_model_assets, methods=["POST"]
|
||||||
|
)
|
||||||
|
|
||||||
def post_upload_file(self, file: UploadFile = File(...), filename: str = Form(...)):
|
def post_upload_file(self, file: UploadFile = File(...), filename: str = Form(...)):
|
||||||
res = upload_file(UPLOAD_DIR, file, filename)
|
res = upload_file(UPLOAD_DIR, file, filename)
|
||||||
@ -128,3 +134,13 @@ class MMVC_Rest_Fileuploader:
|
|||||||
info = self.voiceChangerManager.update_model_default()
|
info = self.voiceChangerManager.update_model_default()
|
||||||
json_compatible_item_data = jsonable_encoder(info)
|
json_compatible_item_data = jsonable_encoder(info)
|
||||||
return JSONResponse(content=json_compatible_item_data)
|
return JSONResponse(content=json_compatible_item_data)
|
||||||
|
|
||||||
|
def post_update_model_info(self, newData: str = Form(...)):
|
||||||
|
info = self.voiceChangerManager.update_model_info(newData)
|
||||||
|
json_compatible_item_data = jsonable_encoder(info)
|
||||||
|
return JSONResponse(content=json_compatible_item_data)
|
||||||
|
|
||||||
|
def post_upload_model_assets(self, params: str = Form(...)):
|
||||||
|
info = self.voiceChangerManager.upload_model_assets(params)
|
||||||
|
json_compatible_item_data = jsonable_encoder(info)
|
||||||
|
return JSONResponse(content=json_compatible_item_data)
|
||||||
|
@ -478,3 +478,44 @@ class RVC:
|
|||||||
|
|
||||||
json.dump(params, open(os.path.join(slotDir, "params.json"), "w"))
|
json.dump(params, open(os.path.join(slotDir, "params.json"), "w"))
|
||||||
self.loadSlots()
|
self.loadSlots()
|
||||||
|
|
||||||
|
def update_model_info(self, newData: str):
|
||||||
|
print("[Voice Changer] UPDATE MODEL INFO", newData)
|
||||||
|
newDataDict = json.loads(newData)
|
||||||
|
try:
|
||||||
|
slotDir = os.path.join(
|
||||||
|
self.params.model_dir, RVC_MODEL_DIRNAME, str(newDataDict["slot"])
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
print("Exception::::", e)
|
||||||
|
params = json.load(
|
||||||
|
open(os.path.join(slotDir, "params.json"), "r", encoding="utf-8")
|
||||||
|
)
|
||||||
|
params[newDataDict["key"]] = newDataDict["val"]
|
||||||
|
json.dump(params, open(os.path.join(slotDir, "params.json"), "w"))
|
||||||
|
self.loadSlots()
|
||||||
|
|
||||||
|
def upload_model_assets(self, params: str):
|
||||||
|
print("[Voice Changer] UPLOAD ASSETS", params)
|
||||||
|
paramsDict = json.loads(params)
|
||||||
|
uploadPath = os.path.join(UPLOAD_DIR, paramsDict["file"])
|
||||||
|
storeDir = os.path.join(
|
||||||
|
self.params.model_dir, RVC_MODEL_DIRNAME, str(paramsDict["slot"])
|
||||||
|
)
|
||||||
|
storePath = os.path.join(
|
||||||
|
storeDir,
|
||||||
|
paramsDict["file"],
|
||||||
|
)
|
||||||
|
storeJson = os.path.join(
|
||||||
|
storeDir,
|
||||||
|
"params.json",
|
||||||
|
)
|
||||||
|
try:
|
||||||
|
shutil.move(uploadPath, storePath)
|
||||||
|
params = json.load(open(storeJson, "r", encoding="utf-8"))
|
||||||
|
params[paramsDict["name"]] = storePath
|
||||||
|
json.dump(params, open(storeJson, "w"))
|
||||||
|
except Exception as e:
|
||||||
|
print("Exception::::", e)
|
||||||
|
|
||||||
|
self.loadSlots()
|
||||||
|
@ -608,6 +608,20 @@ class VoiceChanger:
|
|||||||
self.voiceChanger.update_model_default()
|
self.voiceChanger.update_model_default()
|
||||||
return self.get_info()
|
return self.get_info()
|
||||||
|
|
||||||
|
def update_model_info(self, newData: str):
|
||||||
|
if self.voiceChanger is None:
|
||||||
|
print("[Voice Changer] Voice Changer is not selected.")
|
||||||
|
return
|
||||||
|
self.voiceChanger.update_model_info(newData)
|
||||||
|
return self.get_info()
|
||||||
|
|
||||||
|
def upload_model_assets(self, params: str):
|
||||||
|
if self.voiceChanger is None:
|
||||||
|
print("[Voice Changer] Voice Changer is not selected.")
|
||||||
|
return
|
||||||
|
self.voiceChanger.upload_model_assets(params)
|
||||||
|
return self.get_info()
|
||||||
|
|
||||||
|
|
||||||
PRINT_CONVERT_PROCESSING: bool = False
|
PRINT_CONVERT_PROCESSING: bool = False
|
||||||
# PRINT_CONVERT_PROCESSING = True
|
# PRINT_CONVERT_PROCESSING = True
|
||||||
|
@ -69,3 +69,9 @@ class VoiceChangerManager(object):
|
|||||||
|
|
||||||
def update_model_default(self):
|
def update_model_default(self):
|
||||||
return self.voiceChanger.update_model_default()
|
return self.voiceChanger.update_model_default()
|
||||||
|
|
||||||
|
def update_model_info(self, newData: str):
|
||||||
|
return self.voiceChanger.update_model_info(newData)
|
||||||
|
|
||||||
|
def upload_model_assets(self, params: str):
|
||||||
|
return self.voiceChanger.upload_model_assets(params)
|
||||||
|
Loading…
Reference in New Issue
Block a user