2023-01-07 14:07:39 +03:00
|
|
|
import { useEffect, useMemo, useRef, useState } from "react"
|
2023-01-12 17:01:45 +03:00
|
|
|
import { VoiceChangerClient } from "../VoiceChangerClient"
|
2023-02-19 08:20:37 +03:00
|
|
|
import { AudioStreamerSettingState, useAudioStreamerSetting } from "./useAudioStreamerSetting"
|
2023-01-12 10:38:45 +03:00
|
|
|
import { ClientSettingState, useClientSetting } from "./useClientSetting"
|
|
|
|
import { ServerSettingState, useServerSetting } from "./useServerSetting"
|
2023-01-11 22:52:01 +03:00
|
|
|
import { useWorkletSetting, WorkletSettingState } from "./useWorkletSetting"
|
2023-01-07 14:07:39 +03:00
|
|
|
|
|
|
|
export type UseClientProps = {
|
|
|
|
audioContext: AudioContext | null
|
|
|
|
audioOutputElementId: string
|
|
|
|
}
|
|
|
|
|
|
|
|
export type ClientState = {
|
2023-02-18 22:56:16 +03:00
|
|
|
// 各種設定I/Fへの参照
|
2023-01-12 10:38:45 +03:00
|
|
|
workletSetting: WorkletSettingState
|
|
|
|
clientSetting: ClientSettingState
|
2023-02-19 08:20:37 +03:00
|
|
|
streamerSetting: AudioStreamerSettingState
|
2023-01-12 10:38:45 +03:00
|
|
|
serverSetting: ServerSettingState
|
|
|
|
|
2023-02-18 22:56:16 +03:00
|
|
|
// モニタリングデータ
|
2023-01-07 14:07:39 +03:00
|
|
|
bufferingTime: number;
|
|
|
|
responseTime: number;
|
|
|
|
volume: number;
|
2023-02-18 22:56:16 +03:00
|
|
|
outputRecordData: Float32Array[] | null; // Serverから帰ってきたデータをレコードしたもの
|
2023-01-08 10:18:20 +03:00
|
|
|
|
2023-02-18 22:56:16 +03:00
|
|
|
// 情報取得
|
2023-01-08 10:18:20 +03:00
|
|
|
getInfo: () => Promise<void>
|
2023-02-18 22:56:16 +03:00
|
|
|
// 設定クリア
|
2023-01-29 03:42:45 +03:00
|
|
|
clearSetting: () => Promise<void>
|
2023-01-07 14:07:39 +03:00
|
|
|
}
|
2023-01-11 17:12:29 +03:00
|
|
|
|
|
|
|
|
|
|
|
|
2023-01-07 14:07:39 +03:00
|
|
|
export const useClient = (props: UseClientProps): ClientState => {
|
|
|
|
|
2023-01-12 10:38:45 +03:00
|
|
|
// (1-1) クライアント
|
2023-01-11 22:52:01 +03:00
|
|
|
const voiceChangerClientRef = useRef<VoiceChangerClient | null>(null)
|
|
|
|
const [voiceChangerClient, setVoiceChangerClient] = useState<VoiceChangerClient | null>(voiceChangerClientRef.current)
|
2023-01-12 10:38:45 +03:00
|
|
|
//// クライアント初期化待ち用フラグ
|
2023-01-08 14:28:57 +03:00
|
|
|
const initializedResolveRef = useRef<(value: void | PromiseLike<void>) => void>()
|
|
|
|
const initializedPromise = useMemo(() => {
|
|
|
|
return new Promise<void>((resolve) => {
|
|
|
|
initializedResolveRef.current = resolve
|
|
|
|
})
|
|
|
|
}, [])
|
2023-01-12 10:38:45 +03:00
|
|
|
|
|
|
|
|
2023-02-18 22:56:16 +03:00
|
|
|
// (1-2) 各種設定I/F
|
2023-01-12 10:38:45 +03:00
|
|
|
const clientSetting = useClientSetting({ voiceChangerClient, audioContext: props.audioContext })
|
2023-02-19 08:20:37 +03:00
|
|
|
const streamerSetting = useAudioStreamerSetting({ voiceChangerClient })
|
2023-01-12 10:38:45 +03:00
|
|
|
const workletSetting = useWorkletSetting({ voiceChangerClient })
|
|
|
|
const serverSetting = useServerSetting({ voiceChangerClient })
|
|
|
|
|
2023-02-18 22:56:16 +03:00
|
|
|
// (1-3) モニタリングデータ
|
2023-01-10 16:49:16 +03:00
|
|
|
const [bufferingTime, setBufferingTime] = useState<number>(0)
|
|
|
|
const [responseTime, setResponseTime] = useState<number>(0)
|
|
|
|
const [volume, setVolume] = useState<number>(0)
|
2023-02-12 11:07:28 +03:00
|
|
|
const [outputRecordData, setOutputRecordData] = useState<Float32Array[] | null>(null)
|
2023-01-08 14:28:57 +03:00
|
|
|
|
2023-01-16 02:09:53 +03:00
|
|
|
// (1-4) エラーステータス
|
|
|
|
const errorCountRef = useRef<number>(0)
|
|
|
|
|
2023-01-12 10:38:45 +03:00
|
|
|
// (2-1) 初期化処理
|
2023-01-07 14:07:39 +03:00
|
|
|
useEffect(() => {
|
|
|
|
const initialized = async () => {
|
|
|
|
if (!props.audioContext) {
|
|
|
|
return
|
|
|
|
}
|
2023-01-11 22:52:01 +03:00
|
|
|
const voiceChangerClient = new VoiceChangerClient(props.audioContext, true, {
|
2023-01-07 14:07:39 +03:00
|
|
|
notifySendBufferingTime: (val: number) => {
|
|
|
|
setBufferingTime(val)
|
|
|
|
},
|
|
|
|
notifyResponseTime: (val: number) => {
|
|
|
|
setResponseTime(val)
|
|
|
|
},
|
|
|
|
notifyException: (mes: string) => {
|
|
|
|
if (mes.length > 0) {
|
|
|
|
console.log(`error:${mes}`)
|
2023-01-16 02:09:53 +03:00
|
|
|
errorCountRef.current += 1
|
|
|
|
if (errorCountRef.current > 100) {
|
|
|
|
alert("エラーが頻発しています。対象としているフレームワークのモデルがロードされているか確認してください。")
|
|
|
|
errorCountRef.current = 0
|
|
|
|
}
|
2023-01-07 14:07:39 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}, {
|
|
|
|
notifyVolume: (vol: number) => {
|
|
|
|
setVolume(vol)
|
2023-02-12 11:07:28 +03:00
|
|
|
},
|
|
|
|
notifyOutputRecordData: (data: Float32Array[]) => {
|
|
|
|
setOutputRecordData(data)
|
2023-01-07 14:07:39 +03:00
|
|
|
}
|
|
|
|
})
|
2023-01-08 14:28:57 +03:00
|
|
|
|
2023-01-07 14:07:39 +03:00
|
|
|
await voiceChangerClient.isInitialized()
|
|
|
|
voiceChangerClientRef.current = voiceChangerClient
|
2023-01-11 22:52:01 +03:00
|
|
|
setVoiceChangerClient(voiceChangerClientRef.current)
|
2023-01-08 10:18:20 +03:00
|
|
|
console.log("[useClient] client initialized")
|
2023-01-07 14:07:39 +03:00
|
|
|
|
|
|
|
const audio = document.getElementById(props.audioOutputElementId) as HTMLAudioElement
|
|
|
|
audio.srcObject = voiceChangerClientRef.current.stream
|
|
|
|
audio.play()
|
2023-01-08 14:28:57 +03:00
|
|
|
initializedResolveRef.current!()
|
2023-01-07 14:07:39 +03:00
|
|
|
}
|
|
|
|
initialized()
|
|
|
|
}, [props.audioContext])
|
|
|
|
|
2023-01-08 10:18:20 +03:00
|
|
|
|
2023-01-12 10:38:45 +03:00
|
|
|
// (2-2) 情報リロード
|
2023-01-08 10:18:20 +03:00
|
|
|
const getInfo = useMemo(() => {
|
|
|
|
return async () => {
|
2023-01-08 14:28:57 +03:00
|
|
|
await initializedPromise
|
2023-02-19 00:25:22 +03:00
|
|
|
await clientSetting.reloadClientSetting() // 実質的な処理の意味はない
|
2023-01-12 10:38:45 +03:00
|
|
|
await serverSetting.reloadServerInfo()
|
2023-01-10 20:19:54 +03:00
|
|
|
}
|
2023-01-12 10:38:45 +03:00
|
|
|
}, [clientSetting, serverSetting])
|
2023-01-11 17:12:29 +03:00
|
|
|
|
|
|
|
|
2023-01-29 03:42:45 +03:00
|
|
|
const clearSetting = async () => {
|
|
|
|
await clientSetting.clearSetting()
|
|
|
|
await workletSetting.clearSetting()
|
|
|
|
await serverSetting.clearSetting()
|
|
|
|
}
|
2023-02-19 08:20:37 +03:00
|
|
|
console.log("AUDIO STREAMER SETTING USE CLIENT", clientSetting, streamerSetting)
|
2023-01-11 22:52:01 +03:00
|
|
|
|
2023-01-07 14:07:39 +03:00
|
|
|
return {
|
2023-02-18 22:56:16 +03:00
|
|
|
// 各種設定I/Fへの参照
|
|
|
|
clientSetting,
|
2023-02-19 08:20:37 +03:00
|
|
|
streamerSetting,
|
2023-02-18 22:56:16 +03:00
|
|
|
workletSetting,
|
|
|
|
serverSetting,
|
|
|
|
|
|
|
|
// モニタリングデータ
|
2023-01-07 14:07:39 +03:00
|
|
|
bufferingTime,
|
|
|
|
responseTime,
|
|
|
|
volume,
|
2023-02-12 11:07:28 +03:00
|
|
|
outputRecordData,
|
2023-01-07 14:07:39 +03:00
|
|
|
|
2023-02-18 22:56:16 +03:00
|
|
|
// 情報取得
|
2023-01-08 10:18:20 +03:00
|
|
|
getInfo,
|
2023-01-11 22:52:01 +03:00
|
|
|
|
2023-02-18 22:56:16 +03:00
|
|
|
// 設定クリア
|
2023-01-29 03:42:45 +03:00
|
|
|
clearSetting,
|
2023-01-07 14:07:39 +03:00
|
|
|
}
|
|
|
|
}
|