Notice
Recent Posts
Recent Comments
Link
250x250
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 |
Tags
- 프론트엔드
- 코드테스트
- 자바
- jsp
- 스프링부트
- spring
- 정리
- 프런트엔드
- 스프링
- oracle
- 쿼리
- 자바스크립트
- 프로그래머스
- web
- 오라클
- 미니정리
- 알고리즘
- BACK-END
- Next.js
- 백엔드
- JavaScript
- 데이터베이스
- node.js
- SQL
- 디자인 패턴
- java
- 코드 테스트
- jpa
- MySQL
- 서버
Archives
- Today
- Total
참치코더의 꿈 메모장
나만의 홈 스쿨 개발해보기~~ (3일차) 본문
728x90

25.12.01
프로젝트 3일차
Socket.io를 이용해서 웹 서버랑 메일을 주고받는 통신은 어느정도 끝냈고, SpringSecurity를 이용하여 백단을 만들고 있는데...
컨트롤러를 만들다가 어떤 기능을 줘야 할까? 하는 생각에 다시 프론트 단으로 돌아왔다. 웹 화상 통신을 하려면 일단 로컬에서
카메라 등 하드웨어를 제어를 해야하는데 이러한 방법을 몰라서 책을 보며 열심히 한번 만들어 보았다. 일단 기본적인 조작감을
익힌 후 사용자 끼리 통신하는 peer-to-peer 를 사용하며 데이터를 본격적으로 보낼 예정이다.
(이것도 공부를 해야한다.... 화이팅!)
1) 가지고 있는 카메라가 없기에 OBS Studio로 가상 카메라 코덱을 설치한후 해당 카메라 정보를 이용하는 것으로 목표로 삼았다.
2) 기본적인 조작하는법은 자바스크립트 코드가 관련 기능을 제공하기 때문에 해당 기능을 적극 사용하였다.

|
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
|
// 중요 기능 정리
// 상태 관리 (useState)
const [muted, setMuted] = useState(false); // 음소거 작동시키는 코드
const [cameraOn, setCameraOn] = useState(true); // 비디오 작동시키는 코드
const [cameraList, setCameraList] = useState<MediaDeviceInfo[]>([]); // 현재 시스템에 연결된 카메라 목록
// useState를 통해 상태를 관리하고, 상태가 바뀌면 React가 UI를 자동으로 업데이트 합니다.
// DOM 참조 (useRef)
const videoRef = useRef<HTMLVideoElement | null>(null);
// <video> 엘리먼트를 직접 참조하기 위해 사용
// videoRef.current를 통해 실제 DOM 노드에 접근 가능
// 초기값은 null이고, 렌더 후 React가 <video>를 할당
// 마이크 on/off 버튼
const handleMuteClick = () => {
if(videoRef.current && videoRef.current.srcObject instanceof MediaStream){
const stream = videoRef.current.srcObject as MediaStream;
stream.getAudioTracks().forEach(track => track.enable = muted);
setMuted(!muted);
}
}
// videoRef.current.srcObject가 MediaStream인지 확인
// 오디오 트랙들의 enabled 값을 토글한다.
// 상태 muted를 반전시켜서 버튼 UI도 갱신하도록 만들었습니다.
const handleCameraClick = () => {
if(videoRef.current && videoRef.current.srcObject instanceof MediaStream){
const stream = videoRef.current.srcObject as MediaStream;
stream.getVideoTracks().forEach(track => track.enabled = !cameraOn);
setCameraOn(!cameraOn);
}
}
// 오디오 트랙과 동일한 방식
// cameraOn 상태를 반전시켜 버튼 UI 생성
|
cs |
|
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
|
// 카메라 선택 드롭다운
const handleCameraChange = async(event: React.ChangeEvent<HTMLSelectEvent>) => {
const selectDeviceId = event.target.value;
try {
const newStream = await navigator.mediaDevices.getUserMedia({
video: {deviceId: {exact: selectDeviceId}},
audio: true,
});
if(videoRef.current){
const oldStream = videoRef.current.srcObject as MediaStream | null;
if(oldStream){
oldStream.getTracks().forEach(tracl => track.stop());
}
videoRef.current.srcObject = newStream;
}
}catch (error) {
console.log(error);
}
}
// 사용자가 드롭다운에서 선택한 카메라로 새 MediaStream를 생성한다.
// 기존 스트림 트랙을 모두 stop() -> 기존 실행중인 영상 스트림을 끈다.
// 새 스트림을 <video>에 연결한다. -> 화면을 전환한다.
// 카메라 목록 가져오기
const getCameras = async() => {
try {
const devices = await navigator.mediaDevices.enumerateDevices();
const cameras = devices.filter((device) => device.kind === "videoinput");
setCameraList(cameras);
} catch (error) {
console.log(error);
}
}
// navigator.mediaDevices.enurateDevices()로 시스템에 연결된 미디어 장치를 조회한다.
// kind === "videoinput" 으로 카메라만 필터링한다.
// 상태 cameraList에 저장해서 <select> 옵션을 렌더링한다.
|
cs |
|
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
|
// 초기 MediaStream 설정
const getMedia = async() => {
try {
const myStream = await navigator.mediaDevices.getUserMedia({
audio: true,
video: true,
});
if(videoRef.current){
videoRef.current.srcObject = myStream;
await getCameras();
}
}catch (error) {
console.log(error);
}
}
// 페이지 로드 시 내 카메라/마이크 접근을 요청한다.
// 비디오 화면을 연결한다.
// 사용 가능한 카메라 목록을 가지고 온다.
// useEffect로 초기화
useEffect(() => {
getMedia();
}, []);
// 컴포넌트가 처음 렌더링될 때 한 번만 getMedia()를 호출한다.
// [] -> 의존성 배열이 비어 있으므로, 최초 1번만 실행한다.
|
cs |
728x90
'프로젝트' 카테고리의 다른 글
| 웹 프로젝트 / 강아지 산책 서비스 (최종 정리) -완- (0) | 2025.12.30 |
|---|---|
| 웹 프로젝트 / 나만의 홈 스쿨 개발해보기~~ (한달치 한번에 정리) -완- (0) | 2025.12.23 |
| 나만의 홈 스쿨 개발해보기~~ (2일차) (0) | 2025.11.28 |
| 나만의 홈 스쿨 개발해보기~~ (1일차) (0) | 2025.11.26 |
Comments