본문 바로가기
기타

[webRTC] H264코덱을 사용해보자

by KBS 2022. 6. 9.
728x90
본 테스트는 Firefox와 Chrome을 기준으로 작성하였습니다. 

 

기본적으로 Chrome과 Firefox의 동영상 코덱은 VP8코덱을 디폴트 값으로 가지고 있다. 어떤 코덱을 디폴트로 가지고있는지는 sdp를 생성하고 그안의 정보를 확인하면 알 수 있는데

 

크롬의 localSdp 정보

 

firefox의 localSdp 정보

 

바로 이부분이다. m=video 9 UDP/TLS/RTP/SAVPF문우 뒤의 숫자 순서대로 우선순위를 가지며 사용가능한 코덱을 나열해 놓은 것이다. 해당 번호가 어떤 코덱인지는 스크롤을 내리면 아래쪽에 나와있다.

 

firefox의 localSdp

a=rtpmap 이라는 문구를 찾아서 보면 FF기준 제일 우선순위가 높던 120번이 VP8코덱임을 알 수 있었다(크롬도 마찬가지로 내려보면 96번은 VP8코덱으로 나와있다).

이제 우선순위가 높은 코덱을 H264로 변경해보자. 방법은 생각보다 매우 간단한데 생성한 피어커넥션에 getTransceivers()를 사용하면된다.

  const onChangeDefaultCodecs = (pc: RTCPeerConnection, value: string) => {
  	// 트랜시버 획득
    // 0 : 오디오
    // 1 : 비디오
    const tcvr = pc.getTransceivers()[1];
    // 현재 해당 브라우저에서 사용가능한 코덱종류
    const codecs = RTCRtpReceiver.getCapabilities("video")?.codecs || [];
    // 내가 새롭게 넣을 코덱 배열
    const changeCodec: RTCRtpCodecCapability[] = [];

	// 반복문을 돌면서 원하는 코덱의 이름 (예 : "video/H264")을 찾아 새롭게 넣을 코덱 배열에 추가
    for (let i = 0; i < codecs.length; i++) {
      if (codecs[i].mimeType === value) {
        changeCodec.push(codecs[i]);
      }
    }
	
    if (tcvr.setCodecPreferences !== undefined) {
      // 코덱 우선순위를 내가 새롭게 만든 배열로 설정해준다.
      tcvr.setCodecPreferences(changeCodec);
    }
  };

위의 함수를 PeerConnection을 만들고 sdp를 생성하기 전에 진행해주면 된다. 첫 번째 시도는 크롬에서 크롬브라우저와 크롬의 시크릿모드 2개의 브라우저에서 진행하였고 결과는 성공적이였다.

결과는 : chrome://webrtc-internals/ 에서 확인하면 된다

하지만 FF에서 실행해보니 작동하지 않았고, 원인을 찾아보니 getTransceivers가 ie와 FF를 지원하지 않았다. 

크롬과 파이어폭스 테스트시 VP8 코덱이 사용된 모습

 

 

이제 다른 방법을 사용해야 했다. sdp자체는 문자열이니 위에서 언급한 우선순위를 문자열을 쪼개어 조작을 하면 될것 같았다.  해당 유저가 어떤 브라우저를 사용하는지 체크를하고, 해당 브라우저에 h264 코덱 번호를 최우선순위로 설정을 해주는 시도를 해보았다.

 

- 유저의 브라우저 유형 체크 : https://github.com/faisalman/ua-parser-js

 

GitHub - faisalman/ua-parser-js: UAParser.js - Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supp

UAParser.js - Detect Browser, Engine, OS, CPU, and Device type/model from User-Agent data. Supports browser & node.js environment. - GitHub - faisalman/ua-parser-js: UAParser.js - Detect Browse...

github.com

- sdp 정보를 쉽게 수정할 수 있는 라이브러리: https://github.com/clux/sdp-transform#readme

 

GitHub - clux/sdp-transform: A simple parser/writer for the Session Description Protocol

A simple parser/writer for the Session Description Protocol - GitHub - clux/sdp-transform: A simple parser/writer for the Session Description Protocol

github.com

 

위의 두 라이브러리를 사용하였고, 내가 작성한 코드는 다음과 같다

// data.sdp : sdp정보가 담겨있으며, 문자열이다
// browerH264Codec : 특정 브라우저의 h264코덱 번호를 전달받는다.
const onChangeDefaultCodec = (
    data: RTCSessionDescriptionInit,
    browserH264Codec: number,
  ) => {
  	// sdp를 객체화 시키고
    const res = sdpTransform.parse(data.sdp || "");
	
    // 해당 sdp에서 우선순위가 담긴 배열을 뽑아 새롭게 우선순위를 정한 배열을 만들어준다.
    const setCodec = sdpTransform
      .parsePayloads(res.media[1].payloads || "")
      .reduce((acc, cur) => {
        if (cur === browserH264Codec) {
          acc.unshift(cur);
          return acc;
        }
        acc.push(cur);
        return acc;
      }, [] as number[]);
	
    // 해당 배열을 새로운 우선순위로 지정해주고
    res.media[1].payloads = setCodec.join(" ");
	
    // 다시 문자열화하여 리턴한다.
    return sdpTransform.write(res);
};

 

오 좋아 의식의 흐름대로 함수를 작성해였다. 한번 테스트를 해보자 크롬에서 접속을하고 파이어폭스도 크롬에서 접속한 방에 접속하였다.

 

 

결과는 성공적으로 H264로 서로 교환을 하고있었다.

728x90

'기타' 카테고리의 다른 글

[webRTC, React, TypeScript] 간단하게 1:1 화상 통화를 만들어보자  (1) 2022.05.27
MQTT  (0) 2022.05.19
소켓 통신 기본 개념 정리  (0) 2022.05.19
동영상 압축, MP4 와 H.264  (0) 2022.05.19
웹어셈블리 (WASM)?  (0) 2022.05.18

댓글