# webRTC 사용방법

webRTC를 사용하기 위해서는 vChatCloud, channel 객체 선언이 필요합니다.
이 문서를 읽기 전에 준비사항의 내용을 먼저 숙지하시고 진행하시기 바랍니다.

# webRTC Workflow

vchatCloud에서의 webRTC workflow입니다.
아래의 그림을 확인하시면 webRTC가 동작하는 순서와 어떤 코드를 작성해야 하는지 더 쉽게 이해하실 수 있습니다.

  1. 내가 영상 채팅방에 입장한다.
    • vChatCloud.joinChannel({ roomId, clientKey, nickName }, callback) 함수나
      예제코드에 정의된 joinRoom(roomId, clientKey, nickName, callback) 함수를 이용해서 서버에 접속합니다.
  2. 나의 입장하기 이벤트가 발생한다.
  3. 나의 마이크, 카메라 ON/OFF이벤트가 발생한다.
  4. 참여자가 서버에 입장한다.
  5. 참여자 입장하기 이벤트가 발생한다.
  6. 참여자의 마이크, 카메라 ON/OFF이벤트가 발생한다.
  7. 참여자가 나간다.
  8. 참여자 나가기 이벤트가 발생한다.
  9. 내가 영상 채팅방에서 나간다.
    • vChatCloud.disconnect() 함수나, 예제코드에 정의된 exit(p) 함수를 이용해 영상 채팅방에서 서버와 연결을 종료합니다.
  10. 나 나가기 이벤트가 발생한다.

# 이벤트 타입 종류

글씨를 눌러 해당하는 부분으로 이동하실 수 있습니다.

# 입장하기 (로컬 미디어 소스 추가 이벤트)

입장하기

내가 채팅방에 첫 입장 했을 때 발생하는 이벤트입니다.
해당 이벤트가 발생하면 자신의 미디어소스를 볼 수 있도록 미디어 스트림을 video태그의 srcObject에 설정해 주셔야 합니다.
아래의 예제 코드에서는 접속자의 비디오가 출력되는 video태그를 만들고,
해당 태그의 srcObject 속성에 event에서 받은 target(MediaStream)값을 설정하였습니다.
그 후 video의 자동재생 기능을 켜고 보여질 위치에 video태그를 삽입하여 출력하도록 되었습니다.
동작을 확인하고 싶으시면 아래에 있는 Run Pen을 클릭하시면 됩니다.

실행하신 후에 코드를 수정하고 반영된 결과물을 바로 확인하실 수 있으며,
다시 시작하고 싶으실 때에는 우측 하단의 Rerun을 클릭하시면 됩니다.

코드내용 상세 보기

 
 
 
 
 
 
 
 





















 






function videoInit() {
  channel.on("rtcLocalStreamAppend", function (event) {
    // 입장하기 이벤트 발생
    myVideo = document.createElement("video"); // video 태그 생성
    let stream = event.target; // event.target에 들어있는 미디어 스트림 정보 획득
    myVideo.srcObject = stream; // video의 srcObject 속성에 미디어 스트림 정보 입력
    myVideo.setAttribute("autoplay", true); // video에 자동재생 설정 (기본값이 멈춘 상태에서 시작함)
    myCam.append(myVideo); // cam
  });
}

let myCam;

window.addEventListener("load", function () {
  ...
  // 닉네임 입력 후 등록 버튼 클릭했을 때
  $('.login').submit(function (e) {
    myCam = $(".my_cam");
    ...
    joinRoom(
      channelKey, // CMS에서 발급받은 키 값
      clientKey, // 사용자의 고유 키 값
      userNick, // 유저 닉네임
      // 채널 생성 후 실행할 콜백 함수
      function (err, history) {
        if (err) {
          openError(err.code, function () {
            vChatCloud.disconnect(); // 오류 발생으로 인한 연결 종료
          });
        } else {
          videoInit(); // videoInit(); 실행
        }
      }
    );
  });
});
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

주의사항! 실행 후에는 아래 종료버튼을 클릭해서 연결을 끊지 않으면
페이지를 이동하거나 닫기 전까지 사용자의 카메라와 마이크가 공유될 수 있습니다.

현재는 카메라 끄기 버튼을 누르면 화면이 멈추고, 마이크 끄기 버튼을 눌러도 확인하기 어려운 이유는,
아직 해당 부분의 로직을 작성하지 않았기 때문입니다. 관련된 내용은 로컬 카메라 상태 변경 이벤트 에서 다룰 예정입니다.
또한 현재는 종료 후 재접속하면 비디오 영역이 여러개가 되는데 로컬 미디어 소스 제거 이벤트 에서 다룰 예정입니다.

# 이벤트 발생 시 데이터

{
  "type": "rtcLocalStreamAppend",
  "target": {...},
  "clientKey": "xxxxxxxx",
  "client": {
    "clientKey": "xxxxxxxx",
    "nickName": "e7works",
    "grade": "user"
  }
}
1
2
3
4
5
6
7
8
9
10
  • 이벤트 값
식별자 설명
type String 발생한 이벤트 타입
target MediaStream 추가된 미디어 스트림
clientKey String 접속 단말 설정 고유키 (여러 참여자 중 1명을 특정하기 위해 필요함)
client Object 접속 단말에 관한 정보 (clientKey, nickName, grade에 관한 정보)

# 나가기 (로컬 미디어 소스 제거 이벤트)

나가기

로컬 사용자가 접속 종료했을 때 발생하는 이벤트입니다.
접속 종료 후 채팅방을 초기화 하거나, 다른 페이지로 이동하는 등 필요한 로직을 작성하시면 됩니다.
아래의 예제 코드에서는 채팅방을 초기화하고, 다시 로그인화면이 출력하도록 작성되었습니다.
동작을 확인하고 싶으시면 아래에 있는 Run Pen을 클릭하시면 됩니다.

코드내용 상세 보기

 
 
 
 
 











function videoInit() {
  // 로컬 접속 종료 시
  channel.on('rtcLocalStreamRemove', function(event) {
    let html = $('.my_cam > video'); // 로컬 접속자를 표시하는 video태그를 감싸고 있는 태그
    html.remove(); // 태그를 삭제한다(움직이지 않는 비디오 태그 삭제)
  });
  // 로컬 접속 시
  channel.on('rtcLocalStreamAppend', function(event) {
    myVideo = document.createElement('video');
    let stream = event.target;
    myVideo.srcObject = stream;
    myVideo.setAttribute('autoplay', true);
    myCam.append(myVideo);
    channel.setRTCLocalMedia(myVideo);
  });
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

주의사항! 실행 후에는 아래 종료버튼을 클릭해서 연결을 끊지 않으면
페이지를 이동하거나 닫기 전까지 사용자의 카메라와 마이크가 공유될 수 있습니다.

# 이벤트 발생 시 데이터

{
  "type": "rtcLocalStreamRemove",
  "target": null,
  "clientKey": "xxxxxxxxx",
  "client": {
    "clientKey": "xxxxxxxxx",
    "nickName": "e7works",
    "grade": "user"
  }
}
1
2
3
4
5
6
7
8
9
10
  • 이벤트 값
식별자 설명
type String 발생한 이벤트 타입
target MediaStream 추가된 미디어 스트림
clientKey String 접속 단말 설정 고유키 (여러 참여자 중 1명을 특정하기 위해 필요함)
client Object 접속 단말에 관한 정보 (clientKey, nickName, grade에 관한 정보)

# 참여자 입장하기 (리모트 미디어 소스 추가 이벤트)

참여자 입장하기

리모트 사용자가 채팅방에 접속했을 때 발생하는 이벤트입니다.
해당 부분부터는 직접 채팅방에 접속한 유저 본인뿐만 아니라 다른 유저들과 영상 채팅을 할 수 있습니다.
해당 이벤트가 발생하면 외부 접속자의 미디어소스를 볼 수 있도록 미디어 스트림을 video태그의 srcObject에 설정해 주셔야 합니다.
예제코드에서는 리모트 사용자의 비디오를 로컬 사용자의 비디오 옆에 작게 인원수만큼 나오게 했습니다.

코드내용 상세 보기

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

















function videoInit() {
  // 리모트 유저 접속 이벤트
  channel.on('rtcRemoteStreamAppend', function(event) {
    let stream = event.target;
    // 이벤트에서 받은 접속 단말 설정 고유키 데이터를 이용하여 새 div 생성
    let html = $(`<div>`, {
      name: event.clientKey,
      class: 'remote_cam',
    });
    remoteCamList.append(html); // 감싸고 있는 태그에 html소스를 삽입
    let remoteVideo = document.createElement('video');
    remoteVideo.srcObject = stream; // HTMLVideoElement에 미디어소스 설정
    remoteVideo.setAttribute('autoplay', true); // 자동 재생
    $(html).append(remoteVideo);
    let userNick = $('<p>').text(event.client.nickName);
    $(html).append(userNick); // 리모트 접속자의 닉네임 설정
    $('.nocam').toggleClass('active', stream.getVideoTracks().length == 0); // 카메라의 상태에 따라 화면 변경
    $('.nomic').toggleClass('active', stream.getAudioTracks().length == 0); // 마이크의 상태에 따라 화면 변경
    channel.setRTCRemoteMedia(remoteVideo, event.clientKey); // 채널에 리모트 미디어 설정
  });

  // 로컬 접속 종료 시
  channel.on('rtcLocalStreamRemove', function(event) {
    let html = $('.my_cam > video'); // 로컬 접속자를 표시하는 video태그를 감싸고 있는 태그
    html.remove(); // 태그를 삭제한다(움직이지 않는 비디오 태그 삭제)
  });
  // 로컬 접속 시
  channel.on('rtcLocalStreamAppend', function(event) {
    myVideo = document.createElement('video');
    let stream = event.target;
    myVideo.srcObject = stream;
    myVideo.setAttribute('autoplay', true);
    myCam.append(myVideo);
    channel.setRTCLocalMedia(myVideo);
  });
}
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

주의사항! 실행 후에는 아래 종료버튼을 클릭해서 연결을 끊지 않으면
페이지를 이동하거나 닫기 전까지 사용자의 카메라와 마이크가 공유될 수 있습니다.

현재는 리모트 유저가 카메라 끄기 버튼을 누르면 화면이 멈추고, 마이크 끄기 버튼을 눌러도 확인하기 어려운 이유는
아직 해당 부분의 로직을 작성하지 않았기 때문입니다. 관련된 내용은 리모트 카메라 상태 변경 이벤트 에서 다룰 예정입니다.
또한 현재는 리모트 유저가 접속을 종료 하면 비디오 영역이 사라지지 않고 남아있는데, 이는 리모트 미디어 소스 제거 이벤트 에서 다룰 예정입니다.

# 이벤트 발생 시 데이터

{
  "type": "rtcRemoteStreamAppend",
  "target": {...},
  "clientKey": "xxxxxxxx",
  "client": {
    "clientKey": "xxxxxxxx",
    "nickName": "e7works",
    "grade": "user"
  }
}
1
2
3
4
5
6
7
8
9
10
  • 이벤트 값
식별자 설명
type String 발생한 이벤트 타입
target MediaStream 추가된 미디어 스트림
clientKey String 접속 단말 설정 고유키 (여러 참여자 중 1명을 특정하기 위해 필요함)
client Object 접속 단말에 관한 정보 (clientKey, nickName, grade에 관한 정보)

# 참여자 나가기 (리모트 접속 종료 이벤트)

참여자 나가기

리모트 사용자가 접속 종료했을 때 발생하는 이벤트입니다.
리모트 사용자의 접속 종료 후 해당 유저의 미디어 스트림을 출력하던 video태그나 감싸고 있던 div태그를 삭제하는 등
필요한 로직을 작성하시면 됩니다.
예제코드에서는 리모트 사용자의 video를 감싸고 있는 태그를 삭제해서 다시 없어지게 하였습니다.
동작을 확인하고 싶으시면 아래에 있는 Run Pen을 클릭하시면 됩니다.

코드내용 상세 보기

 
 
 
 
 
 
 



































function videoInit() {
  // 리모트 유저 접속 종료 이벤트
  channel.on('rtcRemoteStreamRemove', function(event) {
    let html = $(`.remote_cam_wrap div[name=${event.clientKey}]`); // 리모트 접속자를 표시하는 video태그를 감싸고 있는 태그
    if (html.length) {
      html.remove(); // 태그를 삭제한다 (비활성화)
    }
  });
  // 리모트 유저 접속 이벤트
  channel.on('rtcRemoteStreamAppend', function(event) {
    let stream = event.target;
    // 이벤트에서 받은 접속 단말 설정 고유키 데이터를 이용하여 새 div 생성
    let html = $(`<div>`, {
      name: event.clientKey,
      class: 'remote_cam',
    });
    remoteCamList.append(html); // 감싸고 있는 태그에 html소스를 삽입
    let remoteVideo = document.createElement('video');
    remoteVideo.srcObject = stream; // HTMLVideoElement에 미디어소스 설정
    remoteVideo.setAttribute('autoplay', true); // 자동 재생
    $(html).append(remoteVideo);
    let userNick = $('<p>').text(event.client.nickName);
    $(html).append(userNick); // 리모트 접속자의 닉네임 설정
    $('.nocam').toggleClass('active', stream.getVideoTracks().length == 0); // 카메라의 상태에 따라 화면 변경
    $('.nomic').toggleClass('active', stream.getAudioTracks().length == 0); // 마이크의 상태에 따라 화면 변경
    channel.setRTCRemoteMedia(remoteVideo, event.clientKey); // 채널에 리모트 미디어 설정
  });
  // 로컬 접속 종료 시
  channel.on('rtcLocalStreamRemove', function(event) {
    let html = $('.my_cam'); // 로컬 접속자를 표시하는 video태그를 감싸고 있는 태그
    html.html(''); // 태그를 삭제한다(움직이지 않는 비디오 태그 삭제)
  });
  // 로컬 접속 시
  channel.on('rtcLocalStreamAppend', function(event) {
    myVideo = document.createElement('video');
    let stream = event.target;
    myVideo.srcObject = stream;
    myVideo.setAttribute('autoplay', true);
    myCam.append(myVideo);
    channel.setRTCLocalMedia(myVideo);
  });
}
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

주의사항! 실행 후에는 아래 종료버튼을 클릭해서 연결을 끊지 않으면
페이지를 이동하거나 닫기 전까지 사용자의 카메라와 마이크가 공유될 수 있습니다.

# Event 데이터

{
  "client": undefined,
  "type": "rtcRemoteStreamRemove",
  "target": null,
  "clientKey": "xxxxxxxx"
}
1
2
3
4
5
6
  • 이벤트 값
식별자 설명
client undefined -
type String 발생한 이벤트 타입
target null -
clientKey String 접속 단말 설정 고유키 (여러 참여자 중 1명을 특정하기 위해 필요함)

# 내 카메라 ON/OFF 이벤트

내 카메라 ON/OFF

로컬 사용자의 미디어 스트림에서 영상 소스가 변경되었을 때 (카메라 ON/OFF) 발생하는 이벤트입니다.
해당 이벤트가 발생하면 미디어 스트림의 상태에 맞춰 카메라가 OFF되었을 때는 대체 이미지를 띄워 멈춘 화면을 보지 않게 해야 합니다.
예제 코드에서는 로컬 사용자가 카메라를 끌 경우 비디오를 숨기고, 대체 이미지를 표시하도록 하였습니다.
동작을 확인하고 싶으시면 아래에 있는 Run Pen을 클릭하시면 됩니다.

코드내용 상세 보기

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 










































function videoInit() {
  // 로컬 유저 비디오 소스 변경 이벤트
  channel.on('rtcLocalVideoChanged', function(event) {
    let is_cam = event.enable; // 로컬 접속자의 카메라 상태 체크
    $('.my_cam video').css('display', is_cam ? '' : 'none'); // 로컬 접속자의 카메라가 비활성화이면 video태그 숨김
    $('.my_cam .camera_off').css('display', !is_cam ? 'block' : 'none'); // 로컬 접속자의 카메라가 비활성화이면 대체 이미지 표시
    // 카메라 on/off버튼 상태를 재설정한다.
    $('.cam-footer .cam-btn .cam')
      .toggleClass('btn_on', is_cam)
      .toggleClass('btn_off', !is_cam);
    // is_cam 상태에 따라 on_cam.png를 보여줄 지 off_cam.png를 보여줄 지 설정한다.
    $('.cam-footer .cam-btn .cam img').attr(
      'src',
      is_cam
        ? '/img/webRTC/on_cam.png' // 카메라 on 아이콘 주소
        : '/img/webRTC/off_cam.png' // 카메라 off 아이콘 주소
    );
  });
  // 리모트 유저 접속 종료 이벤트
  channel.on('rtcRemoteStreamRemove', function(event) {
    let html = $(`.remote_cam_wrap div[name=${event.clientKey}]`); // 리모트 접속자를 표시하는 video태그를 감싸고 있는 태그
    if (html.length) {
      html.remove(); // 태그를 삭제한다 (비활성화)
    }
  });
  // 리모트 유저 접속 이벤트
  channel.on('rtcRemoteStreamAppend', function(event) {
    let stream = event.target;
    // 이벤트에서 받은 접속 단말 설정 고유키 데이터를 이용하여 새 div 생성
    let html = $(`<div>`, {
      name: event.clientKey,
      class: 'remote_cam',
    });
    remoteCamList.append(html); // 감싸고 있는 태그에 html소스를 삽입
    let remoteVideo = document.createElement('video');
    remoteVideo.srcObject = stream; // HTMLVideoElement에 미디어소스 설정
    remoteVideo.setAttribute('autoplay', true); // 자동 재생
    $(html).append(remoteVideo);
    let userNick = $('<p>').text(event.client.nickName);
    $(html).append(userNick); // 리모트 접속자의 닉네임 설정
    $('.nocam').toggleClass('active', stream.getVideoTracks().length == 0); // 카메라의 상태에 따라 화면 변경
    $('.nomic').toggleClass('active', stream.getAudioTracks().length == 0); // 마이크의 상태에 따라 화면 변경
    channel.setRTCRemoteMedia(remoteVideo, event.clientKey); // 채널에 리모트 미디어 설정
  });
  // 로컬 접속 종료 시
  channel.on('rtcLocalStreamRemove', function(event) {
    let html = $('.my_cam'); // 로컬 접속자를 표시하는 video태그를 감싸고 있는 태그
    html.html(''); // 태그를 삭제한다(움직이지 않는 비디오 태그 삭제)
  });
  // 로컬 접속 시
  channel.on('rtcLocalStreamAppend', function(event) {
    myVideo = document.createElement('video');
    let stream = event.target;
    myVideo.srcObject = stream;
    myVideo.setAttribute('autoplay', true);
    myCam.append(myVideo);
    channel.setRTCLocalMedia(myVideo);
  });
}
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

주의사항! 실행 후에는 아래 종료버튼을 클릭해서 연결을 끊지 않으면
페이지를 이동하거나 닫기 전까지 사용자의 카메라와 마이크가 공유될 수 있습니다.

# Event 데이터

{
  "type": "rtcLocalVideoChanged",
  "target": {
    "kind": "video", // 카메라: video, 마이크: audio
    ...
  },
  "stream": {},
  "clientKey": "xxxxxxxx",
  "enable": true,
}
1
2
3
4
5
6
7
8
9
10
  • 이벤트 값
식별자 설명
type String 발생한 이벤트 타입
target MediaStreamTrack 이벤트가 발생한 소스 (카메라: video, 마이크: audio)
stream MediaStream 실시간 동영상 스트림
clientKey String 접속 단말 설정 고유키 (여러 참여자 중 1명을 특정하기 위해 필요함)
enable Boolean 이벤트 발생 후 활성화 여부 ( 켜기: true, 끄기: false )

    # 내 마이크 ON/OFF 이벤트

    내 마이크 ON/OFF하기

    로컬 사용자의 미디어 스트림이 변경되었을 때 (마이크 ON/OFF) 발생하는 이벤트입니다.
    해당 이벤트가 발생하면 미디어 스트림의 상태에 맞춰 마이크가 OFF되었을 때 알기 쉽게 해야 합니다.
    예제 코드에서는 마이크가 OFF되었을 때 화면 우상단에 음소거 이미지를 보이게 했습니다.
    동작을 확인하고 싶으시면 아래에 있는 Run Pen을 클릭하시면 됩니다.

    코드내용 상세 보기

     
     
     
     
     
     
     
     
     
     
     
     
     
     



























































    function videoInit() {
      // 로컬 마이크 상태 변경 이벤트
      channel.on('rtcLocalAudioChanged', function(event) {
        let is_mic = event.enable;
        $('.mic_off').css('display', !is_mic ? 'block' : 'none');
        $('.cam-footer .cam-btn .mic')
          .toggleClass('btn_on', is_mic)
          .toggleClass('btn_off', !is_mic);
        $('.cam-footer .cam-btn .mic img').attr(
          'src',
          is_mic
            ? '/img/webRTC/on_mic.png' // 마이크 ON 이미지 주소
            : '/img/webRTC/off_mic.png' // 마이크 OFF 이미지 주소
        );
      });
      // 로컬 유저 비디오 소스 변경 이벤트
      channel.on('rtcLocalVideoChanged', function(event) {
        let is_cam = event.enable; // 로컬 접속자의 카메라 상태 체크
        $('.my_cam video').css('display', is_cam ? '' : 'none'); // 로컬 접속자의 카메라가 비활성화이면 video태그 숨김
        $('.my_cam .camera_off').css('display', !is_cam ? 'block' : 'none'); // 로컬 접속자의 카메라가 비활성화이면 대체 이미지 표시
        // 카메라 on/off버튼 상태를 재설정한다.
        $('.cam-footer .cam-btn .cam')
          .toggleClass('btn_on', is_cam)
          .toggleClass('btn_off', !is_cam);
        // is_cam 상태에 따라 on_cam.png를 보여줄 지 off_cam.png를 보여줄 지 설정한다.
        $('.cam-footer .cam-btn .cam img').attr(
          'src',
          is_cam
            ? '/img/webRTC/on_cam.png' // 카메라 on 아이콘 주소
            : '/img/webRTC/off_cam.png' // 카메라 off 아이콘 주소
        );
      });
      // 리모트 유저 접속 종료 이벤트
      channel.on('rtcRemoteStreamRemove', function(event) {
        let html = $(`.remote_cam_wrap div[name=${event.clientKey}]`); // 리모트 접속자를 표시하는 video태그를 감싸고 있는 태그
        if (html.length) {
          html.remove(); // 태그를 삭제한다 (비활성화)
        }
      });
      // 리모트 유저 접속 이벤트
      channel.on('rtcRemoteStreamAppend', function(event) {
        let stream = event.target;
        // 이벤트에서 받은 접속 단말 설정 고유키 데이터를 이용하여 새 div 생성
        let html = $(`<div>`, {
          name: event.clientKey,
          class: 'remote_cam',
        });
        remoteCamList.append(html); // 감싸고 있는 태그에 html소스를 삽입
        let remoteVideo = document.createElement('video');
        remoteVideo.srcObject = stream; // HTMLVideoElement에 미디어소스 설정
        remoteVideo.setAttribute('autoplay', true); // 자동 재생
        $(html).append(remoteVideo);
        let userNick = $('<p>').text(event.client.nickName);
        $(html).append(userNick); // 리모트 접속자의 닉네임 설정
        $('.nocam').toggleClass('active', stream.getVideoTracks().length == 0); // 카메라의 상태에 따라 화면 변경
        $('.nomic').toggleClass('active', stream.getAudioTracks().length == 0); // 마이크의 상태에 따라 화면 변경
        channel.setRTCRemoteMedia(remoteVideo, event.clientKey); // 채널에 리모트 미디어 설정
      });
      // 로컬 접속 종료 시
      channel.on('rtcLocalStreamRemove', function(event) {
        let html = $('.my_cam'); // 로컬 접속자를 표시하는 video태그를 감싸고 있는 태그
        html.html(''); // 태그를 삭제한다(움직이지 않는 비디오 태그 삭제)
      });
      // 로컬 접속 시
      channel.on('rtcLocalStreamAppend', function(event) {
        myVideo = document.createElement('video');
        let stream = event.target;
        myVideo.srcObject = stream;
        myVideo.setAttribute('autoplay', true);
        myCam.append(myVideo);
        channel.setRTCLocalMedia(myVideo);
      });
    }
    
    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

    주의사항! 실행 후에는 아래 종료버튼을 클릭해서 연결을 끊지 않으면
    페이지를 이동하거나 닫기 전까지 사용자의 카메라와 마이크가 공유될 수 있습니다.

    # Event 데이터

    {
      "type": "rtcLocalAudioChanged",
      "target": {
          "kind": "audio", // 카메라: video, 마이크: audio
           ...
      },
      "stream": {},
      "clientKey": "xxxxxxxx",
      "enable": false
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    • 이벤트 값
    식별자 설명
    type String 발생한 이벤트 타입
    target Object 이벤트가 발생한 소스 (카메라: video, 마이크: audio)
    stream MediaStream 실시간 동영상 스트림
    clientKey String 접속 단말 설정 고유키 (여러 참여자 중 1명을 특정하기 위해 필요함)
    enable Boolean 이벤트 발생 후 활성화 여부 ( 켜기: true, 끄기: false )

      # 참여자 카메라 ON/OFF 이벤트

      참여자 카메라 ON/OFF

      리모트 사용자의 미디어 스트림에서 영상 소스가 변경되었을 때 (카메라 ON/OFF, 화면공유 모드 등) 발생하는 이벤트입니다.
      해당 이벤트가 발생하면 미디어 스트림의 상태에 맞춰 카메라가 OFF되었을 때는 대체 이미지를 띄워 멈춘 화면을 보지 않게 해야 합니다.
      예제 코드에서는 리모트 사용자가 카메라를 끌 경우 비디오를 숨기고, 대체 이미지를 표시하도록 하였습니다.
      동작을 확인하고 싶으시면 아래에 있는 Run Pen을 클릭하시면 됩니다.

      코드내용 상세 보기

       
       
       
       
       
       









































































      function videoInit() {
        // 리모트 카메라 상태 변경 이벤트
        channel.on('rtcRemoteVideoChanged', function(event) {
          let is_cam = event.enable; // 리모트 접속자의 카메라 상태 체크
          $(`.remote_cam[name=${event.clientKey}] video`).css('display', is_cam ? '' : 'none'); // 리모트 접속자의 카메라가 비활성화이면 video태그 숨김
          $(`.remote_cam[name=${event.clientKey}] .camera_off`).css('display', !is_cam ? 'block' : 'none'); // 리모트 접속자의 카메라가 비활성화이면 대체 이미지 표시
        });
        // 로컬 마이크 상태 변경 이벤트
        channel.on('rtcLocalAudioChanged', function(event) {
          let is_mic = event.enable;
          $('.mic_off').css('display', !is_mic ? 'block' : 'none');
          $('.cam-footer .cam-btn .mic')
            .toggleClass('btn_on', is_mic)
            .toggleClass('btn_off', !is_mic);
          $('.cam-footer .cam-btn .mic img').attr(
            'src',
            is_mic
              ? '/img/webRTC/on_mic.png' // 마이크 ON 이미지 주소
              : '/img/webRTC/off_mic.png' // 마이크 OFF 이미지 주소
          );
        });
        // 로컬 유저 비디오 소스 변경 이벤트
        channel.on('rtcLocalVideoChanged', function(event) {
          let is_cam = event.enable; // 로컬 접속자의 카메라 상태 체크
          $('.my_cam video').css('display', is_cam ? '' : 'none'); // 로컬 접속자의 카메라가 비활성화이면 video태그 숨김
          $('.my_cam .camera_off').css('display', !is_cam ? 'block' : 'none'); // 로컬 접속자의 카메라가 비활성화이면 대체 이미지 표시
          // 카메라 on/off버튼 상태를 재설정한다.
          $('.cam-footer .cam-btn .cam')
            .toggleClass('btn_on', is_cam)
            .toggleClass('btn_off', !is_cam);
          // is_cam 상태에 따라 on_cam.png를 보여줄 지 off_cam.png를 보여줄 지 설정한다.
          $('.cam-footer .cam-btn .cam img').attr(
            'src',
            is_cam
              ? '/img/webRTC/on_cam.png' // 카메라 on 아이콘 주소
              : '/img/webRTC/off_cam.png' // 카메라 off 아이콘 주소
          );
        });
        // 리모트 유저 접속 종료 이벤트
        channel.on('rtcRemoteStreamRemove', function(event) {
          let html = $(`.remote_cam_wrap div[name=${event.clientKey}]`); // 리모트 접속자를 표시하는 video태그를 감싸고 있는 태그
          if (html.length) {
            html.remove(); // 태그를 삭제한다 (비활성화)
          }
        });
        // 리모트 유저 접속 이벤트
        channel.on('rtcRemoteStreamAppend', function(event) {
          let stream = event.target;
          // 이벤트에서 받은 접속 단말 설정 고유키 데이터를 이용하여 새 div 생성
          let html = $(`<div>`, {
            name: event.clientKey,
            class: 'remote_cam',
          });
          remoteCamList.append(html); // 감싸고 있는 태그에 html소스를 삽입
          let remoteVideo = document.createElement('video');
          remoteVideo.srcObject = stream; // HTMLVideoElement에 미디어소스 설정
          remoteVideo.setAttribute('autoplay', true); // 자동 재생
          $(html).append(remoteVideo);
          let userNick = $('<p>').text(event.client.nickName);
          $(html).append(userNick); // 리모트 접속자의 닉네임 설정
          $('.nocam').toggleClass('active', stream.getVideoTracks().length == 0); // 카메라의 상태에 따라 화면 변경
          $('.nomic').toggleClass('active', stream.getAudioTracks().length == 0); // 마이크의 상태에 따라 화면 변경
          channel.setRTCRemoteMedia(remoteVideo, event.clientKey); // 채널에 리모트 미디어 설정
        });
        // 로컬 접속 종료 시
        channel.on('rtcLocalStreamRemove', function(event) {
          let html = $('.my_cam'); // 로컬 접속자를 표시하는 video태그를 감싸고 있는 태그
          html.html(''); // 태그를 삭제한다(움직이지 않는 비디오 태그 삭제)
        });
        // 로컬 접속 시
        channel.on('rtcLocalStreamAppend', function(event) {
          myVideo = document.createElement('video');
          let stream = event.target;
          myVideo.srcObject = stream;
          myVideo.setAttribute('autoplay', true);
          myCam.append(myVideo);
          channel.setRTCLocalMedia(myVideo);
        });
      }
      
      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

      주의사항! 실행 후에는 아래 종료버튼을 클릭해서 연결을 끊지 않으면
      페이지를 이동하거나 닫기 전까지 사용자의 카메라와 마이크가 공유될 수 있습니다.

      # Event 데이터

      {
        "type": "rtcRemoteVideoChanged",
        "target": {
          "kind": "video", // 카메라: video, 마이크: audio
          ...
        },
        "stream": {},
        "clientKey": "xxxxxxxx",
        "enable": true,
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      • 이벤트 값
      식별자 설명
      type String 발생한 이벤트 타입
      target MediaStreamTrack 이벤트가 발생한 소스 (카메라: video, 마이크: audio)
      stream MediaStream 실시간 동영상 스트림
      clientKey String 접속 단말 설정 고유키 (여러 참여자 중 1명을 특정하기 위해 필요함)
      enable Boolean 이벤트 발생 후 활성화 여부 ( 켜기: true, 끄기: false )

      # 참여자 마이크 ON/OFF 이벤트

      참여자 마이크 ON/OFF

      사용자의 미디어 스트림이 변경되었을 때 (마이크 ON/OFF) 발생하는 이벤트입니다.
      해당 이벤트가 발생하면 미디어 스트림의 상태에 맞춰 마이크가 OFF되었을 때 알기 쉽게 해야 합니다.
      예제 코드에서는 마이크가 OFF되었을 때 화면 우상단에 음소거 이미지를 보이게 했습니다.
      동작을 확인하고 싶으시면 아래에 있는 Run Pen을 클릭하시면 됩니다.

      코드내용 상세 보기

       
       
       
       
       
       














































































      function videoInit() {
        // 리모트 마이크 상태 변경 이벤트
        channel.on('rtcRemoteAudioChanged', function(event) {
          let is_mic = event.enable;
          $(`.remote_cam[name=${event.clientKey}] .mic_off`).css('display', !is_mic ? 'block' : 'none'); // 참여자의 마이크 상태에 음소거 아이콘 출력/숨김
        });
        // 리모트 카메라 상태 변경 이벤트
        channel.on('rtcRemoteVideoChanged', function(event) {
          let is_cam = event.enable; // 리모트 접속자의 카메라 상태 체크
          $(`.remote_cam[name=${event.clientKey}] video`).css('display', is_cam ? '' : 'none'); // 리모트 접속자의 카메라가 비활성화이면 video태그 숨김
          $(`.remote_cam[name=${event.clientKey}] .camera_off`).css('display', !is_cam ? 'block' : 'none'); // 리모트 접속자의 카메라가 비활성화이면 대체 이미지 표시
        });
        // 로컬 마이크 상태 변경 이벤트
        channel.on('rtcLocalAudioChanged', function(event) {
          let is_mic = event.enable;
          $('.mic_off').css('display', !is_mic ? 'block' : 'none');
          $('.cam-footer .cam-btn .mic')
            .toggleClass('btn_on', is_mic)
            .toggleClass('btn_off', !is_mic);
          $('.cam-footer .cam-btn .mic img').attr(
            'src',
            is_mic
              ? '/img/webRTC/on_mic.png' // 마이크 ON 이미지 주소
              : '/img/webRTC/off_mic.png' // 마이크 OFF 이미지 주소
          );
        });
        // 로컬 유저 비디오 소스 변경 이벤트
        channel.on('rtcLocalVideoChanged', function(event) {
          let is_cam = event.enable; // 로컬 접속자의 카메라 상태 체크
          $('.my_cam video').css('display', is_cam ? '' : 'none'); // 로컬 접속자의 카메라가 비활성화이면 video태그 숨김
          $('.my_cam .camera_off').css('display', !is_cam ? 'block' : 'none'); // 로컬 접속자의 카메라가 비활성화이면 대체 이미지 표시
          // 카메라 on/off버튼 상태를 재설정한다.
          $('.cam-footer .cam-btn .cam')
            .toggleClass('btn_on', is_cam)
            .toggleClass('btn_off', !is_cam);
          // is_cam 상태에 따라 on_cam.png를 보여줄 지 off_cam.png를 보여줄 지 설정한다.
          $('.cam-footer .cam-btn .cam img').attr(
            'src',
            is_cam
              ? '/img/webRTC/on_cam.png' // 카메라 on 아이콘 주소
              : '/img/webRTC/off_cam.png' // 카메라 off 아이콘 주소
          );
        });
        // 리모트 유저 접속 종료 이벤트
        channel.on('rtcRemoteStreamRemove', function(event) {
          let html = $(`.remote_cam_wrap div[name=${event.clientKey}]`); // 리모트 접속자를 표시하는 video태그를 감싸고 있는 태그
          if (html.length) {
            html.remove(); // 태그를 삭제한다 (비활성화)
          }
        });
        // 리모트 유저 접속 이벤트
        channel.on('rtcRemoteStreamAppend', function(event) {
          let stream = event.target;
          // 이벤트에서 받은 접속 단말 설정 고유키 데이터를 이용하여 새 div 생성
          let html = $(`<div>`, {
            name: event.clientKey,
            class: 'remote_cam',
          });
          remoteCamList.append(html); // 감싸고 있는 태그에 html소스를 삽입
          let remoteVideo = document.createElement('video');
          remoteVideo.srcObject = stream; // HTMLVideoElement에 미디어소스 설정
          remoteVideo.setAttribute('autoplay', true); // 자동 재생
          $(html).append(remoteVideo);
          let userNick = $('<p>').text(event.client.nickName);
          $(html).append(userNick); // 리모트 접속자의 닉네임 설정
          $('.nocam').toggleClass('active', stream.getVideoTracks().length == 0); // 카메라의 상태에 따라 화면 변경
          $('.nomic').toggleClass('active', stream.getAudioTracks().length == 0); // 마이크의 상태에 따라 화면 변경
          channel.setRTCRemoteMedia(remoteVideo, event.clientKey); // 채널에 리모트 미디어 설정
        });
        // 로컬 접속 종료 시
        channel.on('rtcLocalStreamRemove', function(event) {
          let html = $('.my_cam'); // 로컬 접속자를 표시하는 video태그를 감싸고 있는 태그
          html.html(''); // 태그를 삭제한다(움직이지 않는 비디오 태그 삭제)
        });
        // 로컬 접속 시
        channel.on('rtcLocalStreamAppend', function(event) {
          myVideo = document.createElement('video');
          let stream = event.target;
          myVideo.srcObject = stream;
          myVideo.setAttribute('autoplay', true);
          myCam.append(myVideo);
          channel.setRTCLocalMedia(myVideo);
        });
      }
      
      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

      주의사항! 실행 후에는 아래 종료버튼을 클릭해서 연결을 끊지 않으면
      페이지를 이동하거나 닫기 전까지 사용자의 카메라와 마이크가 공유될 수 있습니다.

      # Event 데이터

      {
        "type": "rtcRemoteAudioChanged",
        "target": {
            "kind": "audio", // 카메라: video, 마이크: audio
              ...
        },
        "stream": {},
        "clientKey": "xxxxxxxx",
        "enable": false
      }
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      • 이벤트 값
      식별자 설명
      type String 발생한 이벤트 타입
      target Object 이벤트가 발생한 소스 (카메라: video, 마이크: audio)
      stream MediaStream 실시간 동영상 스트림
      clientKey String 접속 단말 설정 고유키 (여러 참여자 중 1명을 특정하기 위해 필요함)
      enable Boolean 이벤트 발생 후 활성화 여부 ( 켜기: true, 끄기: false )

      # 데모 확인

        Copyright 2022. E7Works Inc. & JOYTUNE Corp. All Rights Reserved.