import { fileSelectorAsDataURL, createDummyMediaStream, SampleRate } from "@dannadori/voice-changer-client-js" import React, { useEffect, useMemo, useState } from "react" import { AUDIO_ELEMENT_FOR_PLAY_RESULT, AUDIO_ELEMENT_FOR_TEST_CONVERTED, AUDIO_ELEMENT_FOR_TEST_ORIGINAL } from "./const" const reloadDevices = async () => { try { await navigator.mediaDevices.getUserMedia({ video: true, audio: true }); } catch (e) { console.warn("Enumerate device error::", e) } const mediaDeviceInfos = await navigator.mediaDevices.enumerateDevices(); const audioInputs = mediaDeviceInfos.filter(x => { return x.kind == "audioinput" }) audioInputs.push({ deviceId: "none", groupId: "none", kind: "audioinput", label: "none", toJSON: () => { } }) audioInputs.push({ deviceId: "file", groupId: "file", kind: "audioinput", label: "file", toJSON: () => { } }) const audioOutputs = mediaDeviceInfos.filter(x => { return x.kind == "audiooutput" }) return [audioInputs, audioOutputs] } export type DeviceSettingState = { deviceSetting: JSX.Element; audioInput: string | MediaStream; sampleRate: SampleRate; } export const useDeviceSetting = (audioContext: AudioContext | null): DeviceSettingState => { const [inputAudioDeviceInfo, setInputAudioDeviceInfo] = useState([]) const [outputAudioDeviceInfo, setOutputAudioDeviceInfo] = useState([]) const [audioInputForGUI, setAudioInputForGUI] = useState("none") const [audioInput, setAudioInput] = useState("none") const [audioOutputForGUI, setAudioOutputForGUI] = useState("none") const [sampleRate, setSampleRate] = useState(48000) useEffect(() => { const initialize = async () => { const audioInfo = await reloadDevices() setInputAudioDeviceInfo(audioInfo[0]) setOutputAudioDeviceInfo(audioInfo[1]) // if (CHROME_EXTENSION) { // //@ts-ignore // const storedOptions = await chrome.storage.local.get("microphoneOptions") // if (storedOptions) { // setOptions(storedOptions) // } // } } initialize() }, []) const audioInputRow = useMemo(() => { return (
AudioInput
) }, [inputAudioDeviceInfo, audioInputForGUI]) useEffect(() => { console.log("iiiiinnnppu1") if (!audioContext) { console.log("iiiiinnnppu2") return } console.log("iiiiinnnppu3") if (audioInputForGUI == "none") { const ms = createDummyMediaStream(audioContext) setAudioInput(ms) } else if (audioInputForGUI == "file") { // file selector (audioMediaInputRow) } else { setAudioInput(audioInputForGUI) } }, [audioContext, audioInputForGUI]) const audioMediaInputRow = useMemo(() => { if (audioInputForGUI != "file") { return <> } const onFileLoadClicked = async () => { const url = await fileSelectorAsDataURL("") // input stream for client. const audio = document.getElementById(AUDIO_ELEMENT_FOR_TEST_CONVERTED) as HTMLAudioElement audio.src = url await audio.play() const src = audioContext!.createMediaElementSource(audio); const dst = audioContext!.createMediaStreamDestination() src.connect(dst) setAudioInput(dst.stream) // original stream to play. const audio_org = document.getElementById(AUDIO_ELEMENT_FOR_TEST_ORIGINAL) as HTMLAudioElement audio_org.src = url audio_org.pause() // audio_org.onplay = () => { // console.log(audioOutputRef.current) // // @ts-ignore // audio_org.setSinkId(audioOutputRef.current) // } } return (
org:
cnv:
load
) }, [audioInputForGUI]) const audioOutputRow = useMemo(() => { return (
AudioOutput
) }, [outputAudioDeviceInfo, audioOutputForGUI]) useEffect(() => { [AUDIO_ELEMENT_FOR_PLAY_RESULT, AUDIO_ELEMENT_FOR_TEST_ORIGINAL].forEach(x => { const audio = document.getElementById(x) as HTMLAudioElement if (audio) { // @ts-ignore audio.setSinkId(audioOutputForGUI) } }) }, [audioOutputForGUI]) const sampleRateRow = useMemo(() => { return (
Sample Rate
) }, [sampleRate]) const deviceSetting = useMemo(() => { return ( <>
Device Setting
{audioInputRow} {audioMediaInputRow} {sampleRateRow} {audioOutputRow} ) }, [audioInputRow, audioMediaInputRow, sampleRateRow, audioOutputRow]) return { deviceSetting, audioInput, sampleRate, } }