[WebRTC] Kurento를 사용하여 실시간 스트리밍하기
Kurento client를 활용하여 one2many call의 흐름을 익혀보자
대략적인 그림으로 그려보면, 1명의 스트리머가 있고 N명의 Viewer들이 존재하는 아래와 같은 그림일 것이다.
대략적인 서버의 구성은 아래의 그림과 같다.
이제 본격적으로 어떤 흐름으로 1:N 스트리밍을 할 수 있는지 알아보자
Presenter가 방송 켰을 때
1. Client가 웹에 들어오면 웹소켓으로 시그널링 서버와 연결을 한다.
2. 스트리머가 스트리밍 시작 버튼을 누르면, JSON형태로 id와 sdpOffer정보를 시그널링서버에 보낸다.
-
스트리머가 다른 방송을 보고 있는지 또는 다른 방송을 키고 있는지 여부를 파악해야 함
-
id는 WebSocket통신을 할 때, 어떤 메세지를 담고 있는지 구별해주는 id 이다.
-
Presenter, Viewer, IceCandidate와 같이..
-
-
sdpOffer는 어떤 방식으로 연결이 될 지 공유하기 위해 필요한 것이다.
3. 시그널링 서버는 id가 Presenter인 JSON Message를 받았다면, Kurento에게 미디어 파이프라인을 생성하라고 한다.
-
Kurento Media Server에서 정상적으로 MediaPipeline을 만들었다면 pipeline의 정보를 줄 것이다.
-
그렇다면, Presenter는 Kurento Media Server를 통해 받은 Pipeline정보를 통해 Endpoint를 만든다.
pipeLine 정보 : [RemoteObject: type=MediaPipeline remoteRef=f134ae10-ca18-4e3e-8d9b-d8886ebefe81_kurento.MediaPipeline]
WebRtcEndPoint 정보 : [RemoteObject: type=WebRtcEndpoint remoteRef=f134ae10-ca18-4e3e-8d9b-d8886ebefe81_kurento.MediaPipeline/7de16550-801e-4938-ac61-d0b3b3f93a94_kurento.WebRtcEndpoint]
4. Kurento가 미디어 파이프라인을 성공적으로 만들었다면 파이프라인 정보를 줄 것이고 해당 User는 PipeLine의 정보를 저장하고, WebRTCEndpoint에 dataChannel을 사용할 수 있도록 설정한다.
//userDataChannel을 써줘야 dataChannel을 사용할 수 있다.
new WebRtcEndpoint.Builder(pipeline).useDataChannels().build()
5. 실제 Presenter와 Kurneto가 생성한 미디어 파이프라인 사이에 연결을 시켜줘야 한다.
-
addIceCandidateFoundListener 를 사용하여 Candidate를 찾는과정이 이루어진다.
presenterWebRtc.addIceCandidateFoundListener(new EventListener<IceCandidateFoundEvent>() {
@Override
public void onEvent(IceCandidateFoundEvent event) {
JsonObject response = new JsonObject();
response.addProperty("id", "iceCandidate");
response.add("candidate", JsonUtils.toJsonObject(event.getCandidate()));
try {
synchronized (session) {
session.sendMessage(new TextMessage(response.toString()));
}
} catch (IOException e) {
log.debug(e.getMessage());
}
}
});
6. 성공적으로 KMS의 EndPoint와 연결이 되었다면, dataChannel이 open되었다는 것을 확인할 수 있다.
Viewer가 스트리머의 방송에 들어왔을 때
viewer도 presenter와 비슷한 과정을 거친다.
다만, 다른 점이 있다면, 이미 만들어진 파이프라인(Presenter에 의해 생성된 KMS의 파이프라인)을 가져와서 WebRtcEndpoint를 만들어서 연결해준다.
WebRtcEndpoint nextWebRtc = new WebRtcEndpoint.Builder(pipeline).useDataChannels().build();
viewer.setWebRtcEndpoint(nextWebRtc);
presenterUserSession.getWebRtcEndpoint().connect(nextWebRtc);
스트리머의 WebRtcEndpoint를 알고 있기 때문에 스트리머가 송출하고 있는 미디어를 볼 수 있다.