TEST: screen capture

This commit is contained in:
w-okada 2023-07-19 18:49:50 +09:00
parent 72702ee70a
commit ba9b5de461
5 changed files with 119 additions and 12 deletions

File diff suppressed because one or more lines are too long

View File

@ -64,12 +64,14 @@ type GuiStateAndMethod = {
audioInputForGUI: string; audioInputForGUI: string;
audioOutputForGUI: string; audioOutputForGUI: string;
fileInputEchoback: boolean | undefined; fileInputEchoback: boolean | undefined;
shareScreenEnabled: boolean;
audioOutputForAnalyzer: string; audioOutputForAnalyzer: string;
setInputAudioDeviceInfo: (val: MediaDeviceInfo[]) => void; setInputAudioDeviceInfo: (val: MediaDeviceInfo[]) => void;
setOutputAudioDeviceInfo: (val: MediaDeviceInfo[]) => void; setOutputAudioDeviceInfo: (val: MediaDeviceInfo[]) => void;
setAudioInputForGUI: (val: string) => void; setAudioInputForGUI: (val: string) => void;
setAudioOutputForGUI: (val: string) => void; setAudioOutputForGUI: (val: string) => void;
setFileInputEchoback: (val: boolean) => void; setFileInputEchoback: (val: boolean) => void;
setShareScreenEnabled: (val: boolean) => void;
setAudioOutputForAnalyzer: (val: string) => void; setAudioOutputForAnalyzer: (val: string) => void;
modelSlotNum: number; modelSlotNum: number;
@ -105,6 +107,7 @@ export const GuiStateProvider = ({ children }: Props) => {
const [audioInputForGUI, setAudioInputForGUI] = useState<string>("none"); const [audioInputForGUI, setAudioInputForGUI] = useState<string>("none");
const [audioOutputForGUI, setAudioOutputForGUI] = useState<string>("none"); const [audioOutputForGUI, setAudioOutputForGUI] = useState<string>("none");
const [fileInputEchoback, setFileInputEchoback] = useState<boolean>(false); //最初のmuteが有効になるように。undefined <-- ??? falseしておけばよさそう。undefinedだとwarningがでる。 const [fileInputEchoback, setFileInputEchoback] = useState<boolean>(false); //最初のmuteが有効になるように。undefined <-- ??? falseしておけばよさそう。undefinedだとwarningがでる。
const [shareScreenEnabled, setShareScreenEnabled] = useState<boolean>(false);
const [audioOutputForAnalyzer, setAudioOutputForAnalyzer] = useState<string>("default"); const [audioOutputForAnalyzer, setAudioOutputForAnalyzer] = useState<string>("default");
const [textInputResolve, setTextInputResolve] = useState<TextInputResolveType | null>(null); const [textInputResolve, setTextInputResolve] = useState<TextInputResolveType | null>(null);
@ -137,6 +140,13 @@ export const GuiStateProvider = ({ children }: Props) => {
label: "file", label: "file",
toJSON: () => {}, toJSON: () => {},
}); });
audioInputs.push({
deviceId: "screen",
groupId: "screen",
kind: "audioinput",
label: "screen",
toJSON: () => {},
});
const audioOutputs = mediaDeviceInfos.filter((x) => { const audioOutputs = mediaDeviceInfos.filter((x) => {
return x.kind == "audiooutput"; return x.kind == "audiooutput";
}); });
@ -261,12 +271,14 @@ export const GuiStateProvider = ({ children }: Props) => {
audioInputForGUI, audioInputForGUI,
audioOutputForGUI, audioOutputForGUI,
fileInputEchoback, fileInputEchoback,
shareScreenEnabled,
audioOutputForAnalyzer, audioOutputForAnalyzer,
setInputAudioDeviceInfo, setInputAudioDeviceInfo,
setOutputAudioDeviceInfo, setOutputAudioDeviceInfo,
setAudioInputForGUI, setAudioInputForGUI,
setAudioOutputForGUI, setAudioOutputForGUI,
setFileInputEchoback, setFileInputEchoback,
setShareScreenEnabled,
setAudioOutputForAnalyzer, setAudioOutputForAnalyzer,
modelSlotNum, modelSlotNum,

View File

@ -30,8 +30,8 @@ export const ConvertArea = (props: ConvertProps) => {
memory: 0, memory: 0,
}); });
const onClassName = serverSetting.serverSetting.gpu == 0 ? "config-sub-area-button-active" : "config-sub-area-button"; // const onClassName = serverSetting.serverSetting.gpu == 0 ? "config-sub-area-button-active" : "config-sub-area-button";
const offClassName = serverSetting.serverSetting.gpu == 0 ? "config-sub-area-button" : "config-sub-area-button-active"; // const offClassName = serverSetting.serverSetting.gpu == 0 ? "config-sub-area-button" : "config-sub-area-button-active";
const cpuClassName = serverSetting.serverSetting.gpu == -1 ? "config-sub-area-button-active" : "config-sub-area-button"; const cpuClassName = serverSetting.serverSetting.gpu == -1 ? "config-sub-area-button-active" : "config-sub-area-button";
const gpu0ClassName = serverSetting.serverSetting.gpu == 0 ? "config-sub-area-button-active" : "config-sub-area-button"; const gpu0ClassName = serverSetting.serverSetting.gpu == 0 ? "config-sub-area-button-active" : "config-sub-area-button";

View File

@ -8,11 +8,12 @@ export type DeviceAreaProps = {};
export const DeviceArea = (_props: DeviceAreaProps) => { export const DeviceArea = (_props: DeviceAreaProps) => {
const { setting, serverSetting, audioContext, setAudioOutputElementId, initializedRef, setVoiceChangerClientSetting, startOutputRecording, stopOutputRecording } = useAppState(); const { setting, serverSetting, audioContext, setAudioOutputElementId, initializedRef, setVoiceChangerClientSetting, startOutputRecording, stopOutputRecording } = useAppState();
const { isConverting, audioInputForGUI, inputAudioDeviceInfo, setAudioInputForGUI, fileInputEchoback, setFileInputEchoback, setAudioOutputForGUI, audioOutputForGUI, outputAudioDeviceInfo } = useGuiState(); const { isConverting, audioInputForGUI, inputAudioDeviceInfo, setAudioInputForGUI, fileInputEchoback, setFileInputEchoback, setAudioOutputForGUI, audioOutputForGUI, outputAudioDeviceInfo, shareScreenEnabled, setShareScreenEnabled } = useGuiState();
const [inputHostApi, setInputHostApi] = useState<string>("ALL"); const [inputHostApi, setInputHostApi] = useState<string>("ALL");
const [outputHostApi, setOutputHostApi] = useState<string>("ALL"); const [outputHostApi, setOutputHostApi] = useState<string>("ALL");
const [monitorHostApi, setMonitorHostApi] = useState<string>("ALL"); const [monitorHostApi, setMonitorHostApi] = useState<string>("ALL");
const audioSrcNode = useRef<MediaElementAudioSourceNode>(); const audioSrcNode = useRef<MediaElementAudioSourceNode>();
const displayMediaStream = useRef<MediaStream | null>(null);
const { getItem, setItem } = useIndexedDB({ clientType: null }); const { getItem, setItem } = useIndexedDB({ clientType: null });
const [outputRecordingStarted, setOutputRecordingStarted] = useState<boolean>(false); const [outputRecordingStarted, setOutputRecordingStarted] = useState<boolean>(false);
@ -97,7 +98,7 @@ export const DeviceArea = (_props: DeviceAreaProps) => {
value={audioInputForGUI} value={audioInputForGUI}
onChange={async (e) => { onChange={async (e) => {
setAudioInputForGUI(e.target.value); setAudioInputForGUI(e.target.value);
if (e.target.value != "file") { if (e.target.value != "file" && e.target.value != "screen") {
try { try {
await setVoiceChangerClientSetting({ ...setting.voiceChangerClientSetting, audioInput: e.target.value }); await setVoiceChangerClientSetting({ ...setting.voiceChangerClientSetting, audioInput: e.target.value });
} catch (e) { } catch (e) {
@ -132,7 +133,7 @@ export const DeviceArea = (_props: DeviceAreaProps) => {
const hostAPIs = new Set( const hostAPIs = new Set(
devices.map((x) => { devices.map((x) => {
return x.hostAPI; return x.hostAPI;
}) }),
); );
const hostAPIOptions = Array.from(hostAPIs).map((x, index) => { const hostAPIOptions = Array.from(hostAPIs).map((x, index) => {
return ( return (
@ -275,6 +276,74 @@ export const DeviceArea = (_props: DeviceAreaProps) => {
); );
}, [audioInputForGUI, fileInputEchoback, setting, serverSetting.serverSetting]); }, [audioInputForGUI, fileInputEchoback, setting, serverSetting.serverSetting]);
const audioInputScreenRow = useMemo(() => {
if (audioInputForGUI != "screen" || serverSetting.serverSetting.enableServerAudio == 1) {
return <></>;
}
const onSelectScreenClicked = async () => {
// 既存msをクローズ
if (displayMediaStream.current) {
displayMediaStream.current.getTracks().forEach((x) => {
x.stop();
});
displayMediaStream.current = null;
}
// 共有ストップ
if (shareScreenEnabled == true) {
setShareScreenEnabled(false);
return;
}
// 共有スタート
try {
displayMediaStream.current = await navigator.mediaDevices.getDisplayMedia({
video: true,
audio: true,
});
} catch (e) {
return;
}
if (!displayMediaStream.current) {
return;
}
if (displayMediaStream.current?.getAudioTracks().length == 0) {
displayMediaStream.current.getTracks().forEach((x) => {
x.stop();
});
displayMediaStream.current = null;
}
try {
setVoiceChangerClientSetting({ ...setting.voiceChangerClientSetting, audioInput: displayMediaStream.current });
} catch (e) {
console.error(e);
}
setShareScreenEnabled(!shareScreenEnabled);
};
const echobackClass = shareScreenEnabled ? "config-sub-area-control-field-screen-select-button-active" : "config-sub-area-control-field-screen-select-button";
return (
<div className="config-sub-area-control">
<div className="config-sub-area-control-title left-padding-1"></div>
<div className="config-sub-area-control-field">
<div className="config-sub-area-control-field-screen-select">
<div
className={echobackClass}
onClick={() => {
onSelectScreenClicked();
}}
>
capture
</div>
</div>
</div>
</div>
);
}, [audioInputForGUI, setting, serverSetting.serverSetting, shareScreenEnabled, setShareScreenEnabled]);
// (3) Audio Output // (3) Audio Output
useEffect(() => { useEffect(() => {
const loadCache = async () => { const loadCache = async () => {
@ -375,7 +444,7 @@ export const DeviceArea = (_props: DeviceAreaProps) => {
const hostAPIs = new Set( const hostAPIs = new Set(
devices.map((x) => { devices.map((x) => {
return x.hostAPI; return x.hostAPI;
}) }),
); );
const hostAPIOptions = Array.from(hostAPIs).map((x, index) => { const hostAPIOptions = Array.from(hostAPIs).map((x, index) => {
return ( return (
@ -516,7 +585,7 @@ export const DeviceArea = (_props: DeviceAreaProps) => {
const hostAPIs = new Set( const hostAPIs = new Set(
devices.map((x) => { devices.map((x) => {
return x.hostAPI; return x.hostAPI;
}) }),
); );
const hostAPIOptions = Array.from(hostAPIs).map((x, index) => { const hostAPIOptions = Array.from(hostAPIs).map((x, index) => {
return ( return (
@ -541,7 +610,7 @@ export const DeviceArea = (_props: DeviceAreaProps) => {
filteredDevice.unshift( filteredDevice.unshift(
<option value={-1} key={-1}> <option value={-1} key={-1}>
none none
</option> </option>,
); );
const currentValue = devices.find((x) => { const currentValue = devices.find((x) => {
@ -591,6 +660,7 @@ export const DeviceArea = (_props: DeviceAreaProps) => {
{clientAudioInputRow} {clientAudioInputRow}
{serverAudioInputRow} {serverAudioInputRow}
{audioInputMediaRow} {audioInputMediaRow}
{audioInputScreenRow}
{clientAudioOutputRow} {clientAudioOutputRow}
{serverAudioOutputRow} {serverAudioOutputRow}
{serverMonitorRow} {serverMonitorRow}

View File

@ -1455,6 +1455,31 @@ audio::-webkit-media-controls-overlay-enclosure{
max-width: 70%; max-width: 70%;
} }
} }
.config-sub-area-control-field-screen-select {
display: flex;
flex-direction: row-reverse;
gap: 5px;
.config-sub-area-control-field-screen-select-button-active {
font-size: 0.8rem;
border: solid 1px #333;
border-radius: 5px;
background: #ada;
height: 1.2rem;
padding-left: 2px;
padding-right: 2px;
cursor: pointer;
}
.config-sub-area-control-field-screen-select-button {
border: solid 1px #333;
background: #fff;
font-size: 0.8rem;
border-radius: 5px;
height: 1.2rem;
padding-left: 2px;
padding-right: 2px;
cursor: pointer;
}
}
.config-sub-area-control-field-wav-file { .config-sub-area-control-field-wav-file {
display: flex; display: flex;
flex-direction: row; flex-direction: row;