All files / src/components SelectDevice.tsx

0% Statements 0/31
0% Branches 0/12
0% Functions 0/10
0% Lines 0/31

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155                                                                                                                                                                                                                                                                                                                     
import React, {useState, useEffect} from 'react';
// import {} from '../utils/RTCGameUtils';
 
// HTMLMediaElement.setSinkId(sinkId).then(function() { ... })
 
// 1. 원하는 디바이스로 세팅하려면 HTMLMediaElement.setSinkId(sinkId).then(function() { ... })
// 2. 다바이스 리스트를 가져오려면 navigator.mediaDevices.enumerateDevices().then(gotDevices).catch(handleError); 여기서 gotDevices 함수에 매개변수로 리스트가 들어간다.
 
// 2번에서 리스트를 받아서 -> select 컴포넌트를 렌더링 하고, 그리고 셀렉트안에있는 옵션을 선택을 하면 해당 디바이스로 setSinkId 를 호출한다.
 
interface SelectDeviceOptionProps {
  deviceInfos: MediaDeviceInfo[] | null;
  changeEachAudio: (deviceId: string) => void;
  changeInputStream: (stream: MediaStream) => void;
  setSelectOutputDevice: React.Dispatch<React.SetStateAction<string>>;
  seletedOutputDevice: string;
  setSelectInputDevice: React.Dispatch<React.SetStateAction<string>>;
  seletedInputDevice: string;
}
 
interface SelectDeviceProps {
  changeEachAudio: (deviceId: string) => void;
  changeInputStream: (stream: MediaStream) => void;
  setSelectOutputDevice: React.Dispatch<React.SetStateAction<string>>;
  seletedOutputDevice: string;
  setSelectInputDevice: React.Dispatch<React.SetStateAction<string>>;
  seletedInputDevice: string;
}
 
// audioElement에 소리를
function SelectOption(props: SelectDeviceOptionProps): JSX.Element {
  const onChangeOutput: React.ReactEventHandler<HTMLSelectElement> = event => {
    const selectedOption = event.target as HTMLOptionElement;
    const deviceId = selectedOption.value;
    // eslint-disable-next-line
    props.setSelectOutputDevice(deviceId);
    props.changeEachAudio(deviceId);
  };
  const onChangeInput: React.ReactEventHandler<HTMLSelectElement> = event => {
    const selectedOption = event.target as HTMLOptionElement;
    const deviceId = selectedOption.value;
    props.setSelectInputDevice(deviceId);
    navigator.mediaDevices
      .getUserMedia({video: false, audio: {deviceId: deviceId}})
      .then(stream => {
        console.log(`onChangeInput 안에 input 스트림`);
        props.changeInputStream(stream);
      });
  };
  if (!props.deviceInfos) {
    return <></>;
  }
  return (
    <div>
      <div>출력</div>
      <div className="speaker_select_div">
        <select className="speaker_select" onChange={onChangeOutput}>
          {props.deviceInfos.map(deviceInfo => {
            if (deviceInfo.kind === 'audiooutput') {
              // 선택한 deviceInfo이면 selected
              if (props.seletedOutputDevice === deviceInfo.deviceId) {
                return (
                  <option
                    key={deviceInfo.deviceId}
                    value={deviceInfo.deviceId}
                    selected
                  >
                    {deviceInfo.label}
                  </option>
                );
              } else {
                return (
                  <option key={deviceInfo.deviceId} value={deviceInfo.deviceId}>
                    {deviceInfo.label}
                  </option>
                );
              }
            } else {
              return;
            }
          })}
        </select>
        <img
          className="speaker_select_img"
          src="./assets/navigation/speaker.png"
        ></img>
      </div>
      <div>입력</div>
      <div className="mic_select_div">
        <select className="mic_select" onChange={onChangeInput}>
          {props.deviceInfos.map(deviceInfo => {
            if (deviceInfo.kind === 'audioinput') {
              // 선택한 deviceInfo이면 selected
              if (props.seletedInputDevice === deviceInfo.deviceId) {
                return (
                  <option
                    key={deviceInfo.deviceId}
                    value={deviceInfo.deviceId}
                    selected
                  >
                    {deviceInfo.label}
                  </option>
                );
              } else {
                return (
                  <option key={deviceInfo.deviceId} value={deviceInfo.deviceId}>
                    {deviceInfo.label}
                  </option>
                );
              }
            } else {
              return;
            }
          })}
        </select>
        <img className="mic_select_img" src="./assets/navigation/mic.png"></img>
      </div>
    </div>
  );
}
 
export default function SelectDevice(props: SelectDeviceProps): JSX.Element {
  const [deviceList, setDeviceList] = useState<MediaDeviceInfo[] | null>(null);
  useEffect(() => {
    navigator.mediaDevices
      .enumerateDevices()
      .then((deviceInfos: MediaDeviceInfo[]) => {
        setDeviceList(deviceInfos);
      })
      .catch(handleError);
  }, []);
 
  return (
    <>
      {deviceList ? (
        <SelectOption
          deviceInfos={deviceList}
          changeEachAudio={props.changeEachAudio}
          changeInputStream={props.changeInputStream}
          setSelectOutputDevice={props.setSelectOutputDevice}
          seletedOutputDevice={props.seletedOutputDevice}
          setSelectInputDevice={props.setSelectInputDevice}
          seletedInputDevice={props.seletedInputDevice}
        ></SelectOption>
      ) : (
        <div>loading...</div>
      )}
    </>
  );
}
 
function handleError() {
  console.error('deviceInfos를 못가지고 옴.');
}