다음도 참조하십시오: 번역.
Initial Author of this Specification was Ian Hickson, Google Inc., with
the following copyright statement:
© Copyright 2004-2011 Apple Computer, Inc., Mozilla Foundation, and Opera
Software ASA. You are granted a license to use, reproduce and create
derivative works of this document. All subsequent changes since 26 July
2011 done by the W3C WebRTC Working Group are under the following
Copyright:
Copyright © 2011-2025 World Wide Web Consortium. W3C® liability, trademark and permissive document license rules apply.
이 문서는 미디어 및 일반 애플리케이션 데이터를 적절한 실시간 프로토콜 집합을 구현하는 다른 브라우저 또는 장치로 보내고 받을 수 있도록 WebIDL로 작성된 ECMAScript API 집합을 정의한다. 이 명세는 IETF RTCWEB 그룹에서 개발한 프로토콜 명세 및 로컬 미디어 장치에 접근하기 위한 API 명세와 함께 개발되고 있다.
이 절에서는 이 문서가 발행된 시점의 상태를 설명한다. 현재 W3C 간행물 목록과 이 기술 보고서의 최신 개정판은 https://www.w3.org/TR/의 W3C 기술 보고서 색인에서 확인할 수 있다.
이 문서에는 후보 수정안이 포함되어 있다.
이 문서의 관련 테스트 스위트는 API가 권고안으로 처음 발행될 당시의 구현 보고서를 작성하는 데 사용되었다. 그 이후 식별된 제안 수정안과 후보 수정안을 통합하도록 이 테스트 스위트가 업데이트되었으며, 이러한 수정안의 구현 상태에 중점을 둔 업데이트된 구현 보고서는 두 개의 구현이 있는 기능을 제안 수정안으로 선택하는 데 사용되었고, 이제 이 권고안 버전에 완전히 통합되었다.
이 문서는 웹 실시간 통신 워킹 그룹에서 권고안 트랙을 사용하여 권고안으로 발행했다. 이 문서에는 이전 권고안 이후의 실질적인 변경 사항과 새로운 기능을 도입하는 후보 수정안이 포함되어 있다.
W3C는 이 명세를 웹의 표준으로 널리 배포할 것을 권고한다.
W3C 권고안은 광범위한 합의 형성 후 W3C와 그 회원들이 승인하고, 워킹 그룹 회원들이 구현에 대한 로열티 없는 라이선스를 약속한 명세이다. 이 권고안의 향후 업데이트에는 새로운 기능이 포함될 수 있다.
후보 추가 사항은 문서에 표시되어 있다.
후보 수정 사항은 문서에 표시되어 있다.
이 문서는 W3C 특허 정책에 따라 운영되는 그룹에서 작성했다. W3C는 이 그룹의 산출물과 관련하여 이루어진 모든 특허 공개의 공개 목록을 유지한다. 해당 페이지에는 특허 공개 지침도 포함되어 있다. 자신이 실제로 알고 있는 특허에 필수 청구항이 포함되어 있다고 믿는 개인은 W3C 특허 정책 제6절에 따라 해당 정보를 공개해야 한다.
이 문서는 2023년 11월 3일 W3C 프로세스 문서의 적용을 받는다.
이 절은 비규범적이다.
이 명세에서는 HTML의 피어 투 피어 통신 및 화상 회의와 관련된 다음과 같은 여러 측면을 다룬다.
이 문서는 이러한 기능에 사용되는 API를 정의한다. 이 명세는 IETF RTCWEB 그룹에서 개발한 프로토콜 명세 및 WebRTC 워킹 그룹에서 개발한 로컬 미디어 장치에 접근하기 위한 API 명세 [GETUSERMEDIA]와 함께 개발되고 있다. 시스템에 대한 개요는 [RFC8825] 및 [RFC8826]에서 확인할 수 있다.
비규범적이라고 표시된 절뿐만 아니라 이 명세의 모든 작성 지침, 다이어그램, 예제 및 참고 사항은 비규범적이다. 이 명세의 그 밖의 모든 내용은 규범적이다.
이 문서에서 할 수 있다, 해야 한다, 해서는 안 된다 및 하는 것이 좋다라는 핵심어는 여기에 표시된 것처럼 모두 대문자로 나타나는 경우에만 BCP 14 [RFC2119] [RFC8174]에 설명된 대로 해석해야 한다.
이 명세는 하나의 제품, 즉 이 명세에 포함된 인터페이스를 구현하는 사용자 에이전트에 적용되는 적합성 기준을 정의한다.
알고리즘이나 특정 단계로 표현된 적합성 요구 사항은 최종 결과가 동등하다면 어떤 방식으로든 구현할 수 있다. (특히 이 명세에서 정의하는 알고리즘은 쉽게 따라갈 수 있도록 작성되었으며, 성능 향상을 목적으로 하지 않는다.)
ECMAScript를 사용하여 이 명세에서 정의한 API를 구현하는 구현은 Web IDL 명세 [WEBIDL]에서 정의한 ECMAScript 바인딩과 일관된 방식으로 이를 구현해야 한다. 이 명세에서는 해당 명세와 용어를 사용하기 때문이다.
이벤트 처리기에 사용되는 콜백을 나타내는
EventHandler
인터페이스는 [HTML]에서
정의한다.
작업을 큐에 넣기 및 네트워킹 작업 소스 개념은 [HTML]에서 정의한다.
이벤트, 이벤트 처리기 및 이벤트 처리기 이벤트 타입이라는 용어는 [HTML]에서 정의한다.
Performance.timeOrigin 및 Performance.now()는
[hr-time]에서
정의한다.
직렬화 가능한 객체, 직렬화 단계 및 역직렬화 단계라는 용어는 [HTML]에서 정의한다.
MediaStream,
MediaStreamTrack
및
MediaStreamConstraints라는 용어는 [GETUSERMEDIA]에서
정의한다. 이 문서에서
MediaStream은
9.2
MediaStream에서 확장되고, MediaStreamTrack은 이 문서의 9.3
MediaStreamTrack에서 확장된다는 점에 유의한다.
미디어 설명이라는 용어는 [RFC4566]에서 정의한다.
미디어 전송이라는 용어는 [RFC7656]에서 정의한다.
세대라는 용어는 [RFC8838] 제2절에서 정의한다.
통계 객체 및 모니터링되는 객체라는 용어는 [WEBRTC-STATS]에서 정의한다.
예외를 참조할 때 사용하는 던지기 및 생성됨이라는 용어는 [WEBIDL]에서 정의한다.
VoidFunction 콜백은
[WEBIDL]에서
정의한다.
“예외를 던진다”라는 용어는 [INFRA]에 명시된 대로 사용한다. 즉, 현재 처리 단계를 종료한다.
Promise의 문맥에서 사용하는 이행됨, 거부됨, 결정됨 및 확정됨이라는 용어는 [ECMASCRIPT-6.0]에서 정의한다.
AlgorithmIdentifier는 [WebCryptoAPI]에서 정의한다.
완료될 때까지 실행
원칙과 [API-DESIGN-PRINCIPLES]에서 정의한 데이터 경합 없음 원칙을 포함하여
JavaScript API의 일반 원칙이 적용된다. 즉,
작업이 실행되는 동안 외부 이벤트는 JavaScript 애플리케이션에
표시되는 내용에 영향을 주지 않는다. 예를 들어 JavaScript가 실행되는 동안
“send” 호출로 인해 데이터 채널에 버퍼링된 데이터의 양은 증가하며,
패킷 전송으로 인한 감소는 작업 체크포인트 이후 표시된다.
애플리케이션에 제공되는 값의 집합이 일관되도록 보장하는 것은
사용자 에이전트의 책임이다. 예를 들어 getContributingSources()는
동기식이며, 동일한 시점에 측정된 모든 소스의 값을 반환해야 한다.
이 절은 비규범적이다.
RTCPeerConnection 인스턴스를
사용하면
애플리케이션이 다른 브라우저에 있는 또 다른
RTCPeerConnection
인스턴스 또는 필수 프로토콜을 구현하는 다른 엔드포인트와
피어 투 피어 통신을 설정할 수 있다. 통신은 지정되지 않은
방식으로 제공되지만 일반적으로 서버를 경유하는 페이지의
스크립트에서 제공하는 시그널링 채널을 통해 제어 메시지
(시그널링 프로토콜이라고 함)를 교환하여 조정된다. 예를 들어 WebSocket 또는
XMLHttpRequest를
사용한다.
RTCConfiguration은
RTCPeerConnection을 통해 설정되는
피어 투 피어 통신을 설정하거나
다시 설정하는 방법을 구성하는 매개변수 집합을 정의한다.
WebIDLdictionary RTCConfiguration {
sequence<RTCIceServer> iceServers = [];
RTCIceTransportPolicy iceTransportPolicy = "all";
RTCBundlePolicy bundlePolicy = "balanced";
RTCRtcpMuxPolicy rtcpMuxPolicy = "require";
sequence<RTCCertificate> certificates = [];
[EnforceRange] octet iceCandidatePoolSize = 0;
};
RTCConfiguration 멤버
iceServers의 타입은 sequence<RTCIceServer>이며,
기본값은 []이다.
STUN 및 TURN 서버와 같이 ICE에서 사용할 수 있는 서버를 설명하는 객체 배열이다. ICE 서버 수가 구현에서 정의한 제한을 초과하면 임계값을 넘는 ICE 서버를 무시한다. 구현에서 정의한 이 제한은 최소 32여야 한다.
iceTransportPolicy의 타입은
RTCIceTransportPolicy이며,
기본값은 "all"이다.
ICE 에이전트가 사용할 수 있는 후보를 나타낸다.
bundlePolicy의 타입은 RTCBundlePolicy이며,
기본값은
"balanced"이다.
ICE 후보를 수집할 때 사용할 미디어 번들링 정책을 나타낸다.
rtcpMuxPolicy의 타입은 RTCRtcpMuxPolicy이며,
기본값은
"require"이다.
ICE 후보를 수집할 때 사용할 rtcp-mux 정책을 나타낸다.
certificates의 타입은 sequence<RTCCertificate>이며,
기본값은 []이다.
RTCPeerConnection이
인증에 사용하는 인증서 집합이다.
이 매개변수에 유효한 값은
generateCertificate()
함수를 호출하여 생성한다.
주어진 DTLS 연결은 하나의 인증서만 사용하지만
이 속성을 사용하면 호출자가 서로 다른 알고리즘을 지원하는
여러 인증서를 제공할 수 있다. 최종 인증서는
허용되는 인증서를 설정하는 DTLS 핸드셰이크를
기반으로 선택한다. RTCPeerConnection
구현은 주어진 연결에 사용할
인증서를 선택한다. 인증서 선택 방법은
이 명세의 범위를 벗어난다.
기존 구현은 제공된 첫 번째 인증서만 사용하며 나머지는 무시한다.
이 값이 없으면 각 RTCPeerConnection
인스턴스에 대해 기본 인증서 집합을 생성한다.
이 옵션을 사용하면 애플리케이션이 키
연속성을 설정할 수 있다. RTCCertificate는
[INDEXEDDB]에 영구 저장하고 재사용할 수 있다. 영구 저장과
재사용은 키 생성 비용도
방지한다.
이 구성 옵션의 값은 처음 선택된 후에는 변경할 수 없다.
iceCandidatePoolSize의 타입은
octet이며, 기본값은
0이다.
RTCIceServer 딕셔너리는
ICE 에이전트가 피어와
연결을 설정하는 데 사용할 수 있는 STUN 및
TURN 서버를 설명하는 데 사용된다.
WebIDLdictionary RTCIceServer {
required (DOMString or sequence<DOMString>) urls;
DOMString username;
DOMString credential;
};
RTCIceServer 멤버
urls의 타입은 (DOMString or
sequence<DOMString>)이며, 필수이다.
username의 타입은 DOMString이다.
이 RTCIceServer 객체가
TURN 서버를 나타내는 경우
이 속성은 해당 TURN 서버에 사용할 사용자 이름을
지정한다.
credential의 타입은 DOMString이다.
이 RTCIceServer 객체가
TURN 서버를 나타내는 경우
이 속성은 해당 TURN 서버에 사용할 자격 증명을
지정한다.
credential은
[RFC5389]
제10.2절에 설명된 장기 인증
비밀번호를 나타낸다.
RTCIceServer 객체 배열의 예는 다음과
같다.
[
{urls: 'stun:stun1.example.net'},
{urls: ['turns:turn.example.org', 'turn:turn.example.net'],
username: 'user',
credential: 'myPassword',
];
[RFC9429] (제4.1.1절)에
설명된 대로 iceTransportPolicy
멤버가
RTCConfiguration에 지정되면
브라우저가 허용된 후보를 애플리케이션에 노출하는 데 사용하는
ICE 후보 정책 [RFC9429] (제3.5.3절)을 정의한다.
연결성 검사에는 이러한 후보만
사용된다.
WebIDLenum RTCIceTransportPolicy {
"relay",
"all"
};
| 열거형 값 | 설명 |
|---|---|
relay
|
ICE 에이전트는 TURN 서버를 통과하는 후보와 같은 미디어 릴레이 후보만 사용한다.
참고
특정 사용 사례에서 필요할 수 있는 사용자 IP 주소를
원격 엔드포인트가 알아내지 못하도록 하는 데 사용할 수
있다. 예를 들어 “통화” 기반 애플리케이션에서는
수신자가 어떤 방식으로든 동의할 때까지 알 수 없는
발신자가 수신자의 IP 주소를 알아내지 못하도록
할 수 있다.
|
all
|
이 값을 지정하면 ICE 에이전트가 모든 타입의 후보를 사용할 수 있다.
참고
구현은
RTCIceCandidate.address의
설명에 언급된 것처럼 애플리케이션에 노출되는
IP 주소를 제한하기 위해 자체 후보
필터링 정책을 계속 사용할 수 있다.
|
[RFC9429] (제4.1.1절)에 설명된 대로 원격 엔드포인트가 번들을 인식하지 못하는 경우 번들 정책은 협상되는 미디어 트랙과 수집되는 ICE 후보에 영향을 준다. 원격 엔드포인트가 번들을 인식하면 모든 미디어 트랙과 데이터 채널을 동일한 전송에 번들로 묶는다.
WebIDLenum RTCBundlePolicy {
"balanced",
"max-compat",
"max-bundle"
};
| 열거형 값 | 설명 |
|---|---|
balanced
|
사용 중인 각 미디어 타입(오디오, 비디오 및 데이터)에 대해 ICE 후보를 수집한다. 원격 엔드포인트가 번들을 인식하지 못하면 별도의 전송에서 오디오 트랙 하나와 비디오 트랙 하나만 협상한다. |
max-compat
|
각 트랙에 대해 ICE 후보를 수집한다. 원격 엔드포인트가 번들을 인식하지 못하면 별도의 전송에서 모든 미디어 트랙을 협상한다. |
max-bundle
|
하나의 트랙에 대해서만 ICE 후보를 수집한다. 원격 엔드포인트가 번들을 인식하지 못하면 미디어 트랙 하나만 협상한다. |
[RFC9429] (제4.1.1절)에
설명된 대로 RTCRtcpMuxPolicy는 다중화되지 않은
RTCP를 지원하기 위해 수집되는 ICE 후보에
영향을 준다. 이 명세에서 정의하는 유일한 값은
"require"이다.
WebIDLenum RTCRtcpMuxPolicy {
"require"
};
| 열거형 값 | 설명 |
|---|---|
require
|
RTP에 대해서만 ICE 후보를 수집하고 RTP 후보에서 RTCP를 다중화한다. 원격 엔드포인트가 rtcp-mux를 지원하지 않으면 세션 협상이 실패한다. |
이 딕셔너리들은 제안/응답 생성 프로세스를 제어하는 데 사용할 수 있는 옵션을 설명한다.
WebIDLdictionary RTCOfferAnswerOptions {};
WebIDLdictionary RTCOfferOptions : RTCOfferAnswerOptions {
boolean iceRestart = false;
};
iceRestart의 타입은 boolean이며, 기본값은
false이다.
이 딕셔너리 멤버의 값이
true이거나 관련 RTCPeerConnection
객체의 [[LocalIceCredentialsToReplace]]
슬롯이
비어 있지 않으면 생성된 설명에는 현재 자격 증명
(currentLocalDescription
속성의 SDP에
표시됨)과 다른 ICE 자격 증명이 포함된다. 생성된 설명을
적용하면 [RFC5245]
제9.1.1.1절에 설명된 대로 ICE가 다시 시작된다.
이 딕셔너리 멤버의 값이
false이고 관련 RTCPeerConnection
객체의 [[LocalIceCredentialsToReplace]]
슬롯이
비어 있으며
currentLocalDescription
속성에
유효한 ICE 자격 증명이 있으면 생성된 설명에는
currentLocalDescription
속성의 현재 값과 동일한 ICE 자격 증명이
포함된다.
iceConnectionState가
"failed"로
전이될 때 ICE를 다시 시작하는 것이 좋다.
애플리케이션은 추가로
iceConnectionState가
"disconnected"로
전이되는 것을 수신 대기한 다음
다른 정보 소스(예:
getStats를
사용하여 다음 몇 초 동안 송수신된
바이트 수가 증가하는지 측정)를 이용해 ICE를
다시 시작하는 것이 적절한지 판단할 수 있다.
RTCAnswerOptions 딕셔너리는
"answer"
타입의 세션 설명에 특정된 옵션을 설명한다
(이 명세 버전에는 없음).
WebIDLdictionary RTCAnswerOptions : RTCOfferAnswerOptions {};
WebIDLenum RTCSignalingState {
"stable",
"have-local-offer",
"have-remote-offer",
"have-local-pranswer",
"have-remote-pranswer",
"closed"
};
| 열거형 값 | 설명 |
|---|---|
stable
|
진행 중인 제안/응답 교환이 없다. 이는 로컬 및 원격 설명이 비어 있는 초기 상태이기도 하다. |
have-local-offer
|
"offer" 타입의
로컬 설명이 성공적으로 적용되었다.
|
have-remote-offer
|
"offer" 타입의
원격 설명이 성공적으로 적용되었다.
|
have-local-pranswer
|
"offer" 타입의 원격 설명이
성공적으로 적용되었으며
"pranswer" 타입의
로컬 설명이 성공적으로 적용되었다.
|
have-remote-pranswer
|
"offer" 타입의 로컬 설명이
성공적으로 적용되었으며
"pranswer" 타입의
원격 설명이 성공적으로 적용되었다.
|
closed
|
RTCPeerConnection이
닫혔으며 그
[[IsClosed]] 슬롯은
true이다.
|
전이 집합의 예는 다음과 같다.
stable"
have-local-offer"
have-remote-pranswer"
stable"
stable"
have-remote-offer"
have-local-pranswer"
stable"
WebIDLenum RTCIceGatheringState {
"new",
"gathering",
"complete"
};
| 열거형 값 | 설명 |
|---|---|
new
|
RTCIceTransport 중 하나가
"new" 수집
상태이고 어떤 전송도
"gathering"
상태가 아니거나
전송이 없다.
|
gathering
|
RTCIceTransport 중 하나가
"gathering"
상태이다.
|
complete
|
하나 이상의 RTCIceTransport가
존재하며 모든
RTCIceTransport가
"complete"
수집 상태이다.
|
고려되는 전송 집합은 현재
RTCPeerConnection의
트랜시버 집합에서 참조하는 전송과 RTCPeerConnection의
[[SctpTransport]]
내부 슬롯이 null이 아닌 경우 그 슬롯에서 참조하는 전송이다.
WebIDLenum RTCPeerConnectionState {
"closed",
"failed",
"disconnected",
"new",
"connecting",
"connected"
};
| 열거형 값 | 설명 |
|---|---|
closed
|
[[IceConnectionState]]가
"closed"이다.
|
failed
|
이전 상태가 적용되지 않으며
[[IceConnectionState]]가
"failed"이거나
RTCDtlsTransport 중
하나가
"failed"
상태이다.
|
disconnected
|
이전 상태 중 어느 것도 적용되지 않으며
[[IceConnectionState]]가
"disconnected"이다.
|
new
|
이전 상태 중 어느 것도 적용되지 않고
[[IceConnectionState]]가
"new"이며 모든
RTCDtlsTransport가
"new" 또는
"closed"
상태이거나
전송이 없다.
|
connected
|
이전 상태 중 어느 것도 적용되지 않고
[[IceConnectionState]]가
"connected"이며
모든
RTCDtlsTransport가
"connected"
또는
"closed"
상태이다.
|
connecting
|
이전 상태 중 어느 것도 적용되지 않는다. |
"connecting"
상태에서는 하나 이상의
RTCIceTransport가 "new"
또는 "checking" 상태이거나
하나 이상의
RTCDtlsTransport가
"new"
또는 "connecting"
상태이다.
고려되는 전송 집합은 현재
RTCPeerConnection의
트랜시버 집합에서 참조하는 전송과 RTCPeerConnection의
[[SctpTransport]]
내부 슬롯이 null이 아닌 경우 그 슬롯에서 참조하는 전송이다.
WebIDLenum RTCIceConnectionState {
"closed",
"failed",
"disconnected",
"new",
"checking",
"completed",
"connected"
};
| 열거형 값 | 설명 |
|---|---|
closed
|
RTCPeerConnection
객체의 [[IsClosed]]
슬롯이 true이다.
|
failed
|
이전 상태가 적용되지 않고
RTCIceTransport 중
하나가
"failed"
상태이다.
|
disconnected
|
이전 상태 중 어느 것도 적용되지 않고
RTCIceTransport 중
하나가
"disconnected"
상태이다.
|
new
|
이전 상태 중 어느 것도 적용되지 않고 모든
RTCIceTransport가
"new" 또는
"closed"
상태이거나
전송이 없다.
|
checking
|
이전 상태 중 어느 것도 적용되지 않고
RTCIceTransport 중
하나가
"new" 또는
"checking"
상태이다.
|
completed
|
이전 상태 중 어느 것도 적용되지 않고 모든
RTCIceTransport가
"completed"
또는
"closed"
상태이다.
|
connected
|
이전 상태 중 어느 것도 적용되지 않고 모든
RTCIceTransport가
"connected",
"completed"
또는
"closed"
상태이다.
|
고려되는 전송 집합은 현재
RTCPeerConnection의
트랜시버 집합에서 참조하는 전송과 RTCPeerConnection의
[[SctpTransport]]
내부 슬롯이 null이 아닌 경우 그 슬롯에서 참조하는 전송이다.
시그널링의 결과(예: RTCP 다중화 또는 번들링)로
RTCIceTransport가 폐기되거나
시그널링의 결과(예: 새 미디어 설명 추가)로 생성되면 상태가
한 상태에서 다른 상태로 직접 진행될 수 있다는 점에 유의한다.
[RFC9429] 명세는 전체적으로
RTCPeerConnection의 작동 방식에
관한 세부 사항을 설명한다.
[RFC9429]의 특정
하위 절에 대한 참조는 적절한 곳에 제공된다.
다음을 호출하면
new
RTCPeerConnection(configuration)RTCPeerConnection 객체가 생성된다.
configuration.iceServers에는
ICE에서 사용하는 서버를 찾고 접근하는 데 쓰이는 정보가 포함된다.
애플리케이션은 각 유형의 서버를 여러 개 제공할 수 있으며, 모든 TURN
서버를 서버 반사 후보를
수집하기 위한 STUN 서버로도 사용할 수 있다.
RTCPeerConnection 객체에는
[[SignalingState]]와
집계된 상태인
[[ConnectionState]],
[[IceGatheringState]],
그리고
[[IceConnectionState]]가 있다.
이러한 상태는 객체가 생성될 때 초기화된다.
RTCPeerConnection의 ICE 프로토콜 구현은
ICE 에이전트로 표현된다
[RFC5245].
일부
RTCPeerConnection 메서드는
ICE 에이전트와 상호 작용하며, 해당 메서드는 addIceCandidate, setConfiguration,
setLocalDescription, setRemoteDescription 및
close이다.
이러한 상호 작용은 이 문서의 관련 절과
[RFC9429]에 설명되어 있다. 또한 ICE 에이전트는
RTCIceTransport의 내부 표현
상태가 변경될 때
사용자 에이전트에 알림을 제공한다. 이는
5.6
RTCIceTransport 인터페이스에 설명되어 있다.
이 절에 나열된 태스크의 태스크 소스는 네트워킹 태스크 소스이다.
SDP 협상의 상태는 내부 변수
[[SignalingState]],
[[CurrentLocalDescription]],
[[CurrentRemoteDescription]],
[[PendingLocalDescription]] 및
[[PendingRemoteDescription]]로
표현된다.
이들은
setLocalDescription
및 setRemoteDescription
작업 내부에서만 설정되며,
addIceCandidate 작업과
후보를 노출하는
절차에 의해 수정된다. 각각의 경우
다섯 변수 모두에 대한 모든 수정은 해당 절차가 이벤트를 발생시키거나
콜백을 호출하기 전에 완료되므로,
수정 사항은 단일 시점에 표시된다.
문서 언로드 정리 단계 중 하나로 다음 단계를 실행한다:
window를 document의 관련 전역 객체로 둔다.
관련 전역 객체가 window인 각
RTCPeerConnection 객체
connection에 대해,
connection 및 값 true를 사용하여
연결을 닫는다.
RTCPeerConnection.constructor()가
호출되면 사용자 에이전트는 다음 단계를 반드시 실행해야 한다:
아래에 열거된 단계 중 하나라도 여기에
명시되지 않은 이유로 실패하면, 적절한 설명으로
message
속성이 설정된
UnknownError를 던진다.
connection을 새로 생성된
RTCPeerConnection 객체로 둔다.
connection에 [[DocumentOrigin]] 내부 슬롯을 두고, 관련 설정 객체의 출처로 초기화한다.
configuration의
certificates 값이
비어 있지 않으면 certificates의 각 certificate에 대해 다음
단계를 실행한다:
certificate.expires 값이
현재 시간보다 작으면
InvalidAccessError를 던진다.
certificate.[[Origin]]이
connection.[[DocumentOrigin]]과
동일 출처가
아니면
InvalidAccessError를 던진다.
certificate를 저장한다.
그렇지 않으면 이 RTCPeerConnection 인스턴스로
하나 이상의 새 RTCCertificate 인스턴스를
생성하여 저장한다. 이는 비동기적으로
수행될 수 있으며, 이후 단계에서
certificates의
값은
undefined로 유지된다. [RFC8826]의
4.3.2.3절에 언급된 것처럼 WebRTC는 공개 키 기반 구조(PKI)
인증서가 아닌 자체 서명 인증서를 사용한다. 따라서 만료 검사는
키가 무기한 사용되지 않도록 하기 위한 것이며 추가 인증서
검사는 필요하지 않다.
connection의 ICE 에이전트를 초기화한다.
connection에
[[Configuration]]
내부 슬롯을 두고 null로 초기화한다.
configuration으로 지정된 구성을 설정한다.
connection에 [[IsClosed]]
내부 슬롯을 두고 false로 초기화한다.
connection에
[[NegotiationNeeded]] 내부 슬롯을 두고
false로 초기화한다.
connection에
[[SctpTransport]] 내부 슬롯을 두고
null로 초기화한다.
connection에 [[DataChannels]] 내부 슬롯을 두고 빈 순서 있는 집합으로 초기화한다.
connection에 [[Operations]] 내부 슬롯을 둔다. 이 슬롯은 작업 체인을 나타내며 빈 목록으로 초기화한다.
connection에
[[UpdateNegotiationNeededFlagOnEmptyChain]]
내부 슬롯을 두고 false로 초기화한다.
connection에
[[LastCreatedOffer]] 내부 슬롯을 두고
""로 초기화한다.
connection에
[[LastCreatedAnswer]] 내부 슬롯을 두고
""로 초기화한다.
connection에 [[EarlyCandidates]] 내부 슬롯을 두고 빈 목록으로 초기화한다.
connection에
[[SignalingState]]
내부 슬롯을 두고 "stable"로 초기화한다.
connection에
[[IceConnectionState]]
내부 슬롯을 두고 "new"로 초기화한다.
connection에
[[IceGatheringState]]
내부 슬롯을 두고 "new"로 초기화한다.
connection에
[[ConnectionState]]
내부 슬롯을 두고 "new"로 초기화한다.
connection에
[[PendingLocalDescription]] 내부 슬롯을 두고
null로 초기화한다.
connection에
[[CurrentLocalDescription]] 내부 슬롯을 두고
null로 초기화한다.
connection에
[[PendingRemoteDescription]] 내부 슬롯을 두고
null로 초기화한다.
connection에
[[CurrentRemoteDescription]] 내부 슬롯을 두고
null로 초기화한다.
connection에 [[LocalIceCredentialsToReplace]] 내부 슬롯을 두고 빈 집합으로 초기화한다.
connection을 반환한다.
RTCPeerConnection 객체에는 작업
체인인 [[Operations]]이 있으며, 이는 체인에서
하나의 비동기 작업만 동시에 실행되도록 한다. 이전 호출이 반환한
프로미스가 아직 확정되지 않은 동안
후속 호출이 이루어지면 해당 호출은 체인에 추가되고,
모든 이전 호출의 실행이 완료되고 그 프로미스가
확정된 후 실행된다.
RTCPeerConnection 객체의
작업 체인에 작업을
연결하려면 다음 단계를 실행한다:
connection을 해당
RTCPeerConnection
객체로 둔다.
connection.[[IsClosed]]가
true이면, 새로 생성된 InvalidStateError로
거부된
프로미스를 반환한다.
operation을 연결할 작업으로 둔다.
p를 새 프로미스로 둔다.
operation을 [[Operations]]에 추가한다.
[[Operations]]의 길이가 정확히
1이면 operation을 실행한다.
operation이 반환한 프로미스가 이행되거나 거부되면 다음 단계를 실행한다:
connection.[[IsClosed]]가
true이면 이 단계를 중단한다.
connection.[[IsClosed]]가
true이면 이 단계를 중단한다.
[[Operations]]의
첫 번째 요소를 제거한다.
[[Operations]]가
비어 있지 않으면
[[Operations]]의
첫 번째 요소가 나타내는 작업을 실행하고
이 단계를 중단한다.
connection.[[UpdateNegotiationNeededFlagOnEmptyChain]]이
false이면 이 단계를 중단한다.
connection.[[UpdateNegotiationNeededFlagOnEmptyChain]]을
false로 설정한다.
connection에 대해 협상 필요 플래그를 업데이트한다.
p를 반환한다.
RTCPeerConnection 객체에는 집계된
[[ConnectionState]]가
있다.
RTCDtlsTransport의 상태가 변경될 때마다
사용자 에이전트는 다음 단계를 실행하는 태스크를 반드시 큐에 넣어야 한다:
connection을 상태가 변경된
RTCDtlsTransport 객체와
연결된 이 RTCPeerConnection
객체로 둔다.
connection.[[IsClosed]]가
true이면 이 단계를 중단한다.
newState를
RTCPeerConnectionState
열거형에 설명된 방식으로 새 상태 값을 도출한 결과로 둔다.
connection.[[ConnectionState]]이
newState와 같으면 이 단계를 중단한다.
connection.[[ConnectionState]]을
newState로 설정한다.
connection에서 connectionstatechange라는
이름의 이벤트를 발생시킨다.
RTCPeerConnection 객체
connection에 description을
로컬 세션 설명으로 설정하려면, 추가 값
false를 사용하여 connection에
description을 세션
설명으로 설정한다.
RTCPeerConnection 객체
connection에 description을
원격 세션 설명으로 설정하려면, 추가 값
true를 사용하여 connection에
description을 세션
설명으로 설정한다.
불리언 remote가 주어진 경우,
RTCPeerConnection 객체
connection에 description을
세션
설명으로 설정하려면 다음 단계를 실행한다:
p를 새 프로미스로 둔다.
description.type이
"rollback"이고
connection.[[SignalingState]]이
"stable",
"have-local-pranswer",
또는
"have-remote-pranswer"
중 하나이면, 새로 생성된
InvalidStateError로
p를 거부하고 이
단계를 중단한다.
jsepSetOfTransceivers를 connection의 트랜시버 집합의 얕은 복사본으로 둔다.
[RFC9429] (5.5절 및 5.6절)에 설명된 대로 description을 적용하는 프로세스를 병렬로 시작하되, 다음 추가 제한 사항을 적용한다:
어떤 "RtpTransceivers"가 존재하는지를 판단하는
기준 정보로 jsepSetOfTransceivers를 사용하고,
해당 트랜시버의 [[JsepMid]] 내부 슬롯을
해당 트랜시버의 "mid
속성"으로 사용한다.
remote가 false이고 이로 인해
[RFC9429]
(5.9절)의
ICE 후보 수집 프로세스가 시작되면, ICE 에이전트는
관리상
금지되는 후보를 수집해서는 안 된다.
remote가 true이고 이로 인해
[RFC9429]
(5.10절)의
ICE 연결성 검사가 시작되면,
ICE 에이전트는
관리상
금지된 후보에 연결을 시도해서는 안 된다.
remote가 true이면,
연속된 제안 사이에 응답이 적용된 것처럼,
후속 제안에 대한 검사를 안정 상태에서 수행하는 것처럼 실행하여
연속된 제안을 검증한다.
description을 적용하여 트랜시버 transceiver가 수정되고, transceiver.[[Sender]].[[SendEncodings]]가 비어 있지 않으며 description 처리의 결과로 생성될 인코딩과 같지 않으면, description 적용 프로세스가 실패한다. 이 명세는 원격에서 시작된 RID 재협상을 허용하지 않는다.
어떤 이유로든 description 적용 프로세스가 실패하면 사용자 에이전트는 다음 단계를 실행하는 태스크를 반드시 큐에 넣어야 한다:
connection.[[IsClosed]]가
true이면 이 단계를 중단한다.
description.type이
[RFC9429]
(5.5절
및 5.6절)에
설명된 현재
connection.[[SignalingState]]에
유효하지 않으면, 새로 생성된 InvalidStateError로
p를 거부하고
이 단계를 중단한다.
description의 내용이 유효한
SDP 구문이 아니면 p를
RTCError로 거부한다(
errorDetail을
"sdp-syntax-error"로
설정하고,
sdpLineNumber
속성을 구문 오류가 감지된
SDP의 줄 번호로
설정한다). 그런 다음 이 단계를 중단한다.
remote가 true이고,
connection의 RTCRtcpMuxPolicy가
require이며
설명에서 RTCP mux를
사용하지 않으면, 새로 생성된
InvalidAccessError로
p를 거부하고 이
단계를 중단한다.
위에서 설명한 대로 설명에서 RID 재협상을
시도했으면, 새로 생성된
InvalidAccessError로
p를 거부하고 이
단계를 중단한다.
description의 내용이 유효하지 않으면,
새로 생성된 InvalidAccessError로
p를 거부하고
이
단계를 중단한다.
다른 모든 오류의 경우 새로 생성된 OperationError로
p를 거부한다.
description이 성공적으로 적용되면 사용자 에이전트는 다음 단계를 실행하는 태스크를 반드시 큐에 넣어야 한다:
connection.[[IsClosed]]가
true이면 이 단계를 중단한다.
remote가 true이고
description이
"offer" 유형이며,
description을 적용하는 프로세스 중
connection의
addTrack()
메서드 중 하나라도 성공한 경우,
이 단계를 중단하고 해당 메서드가 이전에
성공한 것처럼 프로세스를 다시 시작하여 추가
트랜시버를 프로세스에 포함한다.
connection과 연결된
RTCRtpSender의
setParameters
메서드에서 반환된 프로미스 중 하나라도
확정되지 않았으면,
이 단계를 중단하고 프로세스를 다시 시작한다.
description이
"offer" 유형이고
connection.[[SignalingState]]이
"stable"이면,
connection의 트랜시버
집합에 있는 각 transceiver에 대해 다음 단계를 실행한다:
transceiver.[[Sender]].[[LastStableStateSenderTransport]]를
transceiver.[[Sender]].[[SenderTransport]]로
설정한다.
transceiver.[[Sender]].[[SendEncodings]].length가
1이고 유일한 인코딩에
rid
멤버가 포함되어 있지 않으면,
transceiver.[[Sender]].[[LastStableRidlessSendEncodings]]를
transceiver.[[Sender]].[[SendEncodings]]로
설정한다.
그렇지 않으면,
transceiver.[[Sender]].[[LastStableRidlessSendEncodings]]를
null로 설정한다.
transceiver.[[Receiver]].[[LastStableStateReceiverTransport]]를
transceiver.[[Receiver]].[[ReceiverTransport]]로
설정한다.
transceiver.[[Receiver]].[[LastStableStateAssociatedRemoteMediaStreams]]를
transceiver.[[Receiver]].[[AssociatedRemoteMediaStreams]]로
설정한다.
transceiver.[[Receiver]].[[LastStableStateReceiveCodecs]]를
transceiver.[[Receiver]].[[ReceiveCodecs]]로
설정한다.
remote가 false이면 다음 단계 중
하나를 실행한다:
description이
"offer"
유형이면,
connection.[[PendingLocalDescription]]을
description으로 생성한 새
RTCSessionDescription
객체로 설정하고,
connection.[[SignalingState]]을
"have-local-offer"로
설정한 다음 초기
후보를 해제한다.
description이
"answer"
유형이면
제안-응답 협상이
완료된다.
connection.[[CurrentLocalDescription]]을
description으로 생성한 새
RTCSessionDescription
객체로 설정하고,
connection.[[CurrentRemoteDescription]]을
connection.[[PendingRemoteDescription]]으로
설정한다.
connection.[[PendingRemoteDescription]]과
connection.[[PendingLocalDescription]]을
모두 null로 설정한다.
connection.[[LastCreatedOffer]]와
connection.[[LastCreatedAnswer]]를
모두 ""로 설정하고,
connection.[[SignalingState]]을
"stable"로
설정한 다음 초기
후보를 해제한다. 마지막으로,
connection.[[LocalIceCredentialsToReplace]]의
ICE 자격 증명 중 어느 것도 description에 없으면,
connection.[[LocalIceCredentialsToReplace]]을
빈 집합으로 설정한다.
description이
"pranswer"
유형이면,
connection.[[PendingLocalDescription]]을
description으로 생성한 새
RTCSessionDescription
객체로 설정하고,
connection.[[SignalingState]]을
"have-local-pranswer"로
설정한 다음
초기
후보를 해제한다.
그렇지 않으면(remote가
true이면) 다음 단계 중 하나를 실행한다:
description이
"offer"
유형이면,
connection.[[PendingRemoteDescription]]
속성을 description으로 생성한 새
RTCSessionDescription
객체로 설정하고,
connection.[[SignalingState]]을
"have-remote-offer"로
설정한다.
description이
"answer"
유형이면
제안-응답 협상이
완료된다.
connection.[[CurrentRemoteDescription]]을
description으로 생성한 새
RTCSessionDescription
객체로 설정하고,
connection.[[CurrentLocalDescription]]을
connection.[[PendingLocalDescription]]으로
설정한다.
connection.[[PendingRemoteDescription]]과
connection.[[PendingLocalDescription]]을
모두 null로 설정한다.
connection.[[LastCreatedOffer]]와
connection.[[LastCreatedAnswer]]를
모두 ""로 설정하고,
connection.[[SignalingState]]을
"stable"로
설정한다.
마지막으로, 새로 설정된
connection.[[CurrentLocalDescription]]에
connection.[[LocalIceCredentialsToReplace]]의
ICE 자격 증명이 하나도 없으면,
connection.[[LocalIceCredentialsToReplace]]을
빈 집합으로 설정한다.
description이
"pranswer"
유형이면,
connection.[[PendingRemoteDescription]]을
description으로 생성한 새
RTCSessionDescription
객체로 설정하고
connection.[[SignalingState]]을
"have-remote-pranswer"로
설정한다.
description이
"answer" 유형이고
[RFC8841]의
10.3절 및 10.4절에 정의된 대로 기존 SCTP 연결의
종료를 시작하면,
connection.[[SctpTransport]]의
값을
null로
설정한다.
trackEventInits, muteTracks, addList, removeList 및 errorList를 빈 목록으로 둔다.
description이
"answer" 또는 "pranswer"
유형이면 다음 단계를 실행한다:
description이
[RFC8841]의
10.3절 및 10.4절에 정의된 대로
새 SCTP 연결 설정을 시작하면,
초기 상태가
"connecting"인
RTCSctpTransport를
생성하고, 그 결과를
[[SctpTransport]]
슬롯에 할당한다. 그렇지 않고
SCTP 연결이 설정되어 있지만
max-message-size SDP
속성이 업데이트되면,
connection.[[SctpTransport]]의
데이터
최대 메시지 크기를 업데이트한다.
description이 SCTP 전송의 DTLS
역할을 협상하면, null
id를 가진
각
RTCDataChannel
channel에 대해
다음 단계를 실행한다:
[[ReadyState]]를
"closed"로
설정하고
channnel을 errorList에 추가한다.
description이
"rollback"
유형이 아니면 다음
단계를 실행한다:
remote가 false이면
description의 각 미디어 설명에 대해
다음 단계를 실행한다:
미디어
설명이 아직
RTCRtpTransceiver
객체와 연결되지 않았으면 다음 단계를
실행한다:
transceiver를
미디어
설명을 생성하는 데 사용된
RTCRtpTransceiver로
둔다.
transceiver.[[Mid]]를
transceiver.[[JsepMid]]로
설정한다.
transceiver.[[Stopped]]가
true이면 이 하위
단계를 중단한다.
[RFC8843]에
따라
미디어
설명에서 기존 미디어
미디어
전송을 사용하는 것으로
표시하면, transport를 해당 전송의
RTP/RTCP 구성 요소를 나타내는
RTCDtlsTransport
객체로 둔다.
그렇지 않으면 transport를
새로운 기반
RTCIceTransport를
가진,
새로 생성된 RTCDtlsTransport
객체로
둔다.
transceiver.[[Sender]].[[SenderTransport]]를
transport로 설정한다.
transceiver.[[Receiver]].[[ReceiverTransport]]를
transport로 설정한다.
transceiver를
미디어
설명과 연결된
RTCRtpTransceiver로
둔다.
transceiver.[[Stopped]]가
true이면 이 하위 단계를 중단한다.
direction을 미디어
미디어
설명의 방향을 나타내는
RTCRtpTransceiverDirection
값으로
둔다.
direction이
"sendrecv"
또는
"recvonly"이면,
transceiver.[[Receptive]]를
true로 설정하고, 그렇지 않으면
false로 설정한다.
transceiver.[[Receiver]].[[ReceiveCodecs]]를
description에서 수신용으로 협상하고
사용자 에이전트가 현재 수신할 준비가
된 코덱으로 설정한다.
description이
"answer"
또는
"pranswer"
유형이면 다음
단계를 실행한다:
transceiver.
[[Sender]].[[SendEncodings]]
.length가 1보다 크면
다음 단계를 실행한다:
description에 이전에 협상한
모든 계층이
없으면,
transceiver.[[Sender]].[[SendEncodings]]에서
첫 번째 사전을 제외한 모든 사전을 제거하고
다음
단계를 건너뛴다.
description에
이전에 협상한 계층 중 하나라도
없으면,
누락된 계층에
대응하는 사전을
transceiver.[[Sender]].[[SendEncodings]]에서
제거한다.
transceiver.[[Sender]].[[SendCodecs]]를
description에서 송신용으로 협상하고
사용자 에이전트가 현재 송신할 수
있는 코덱으로 설정하고,
transceiver.[[Sender]].[[LastReturnedParameters]]를
null로 설정한다.
direction이
"sendonly"
또는
"inactive"이고,
transceiver.[[FiredDirection]]이
"sendrecv"
또는
"recvonly"
중 하나이면 다음 단계를 실행한다:
transceiver.[[Receiver]],
빈 목록, 또 다른 빈 목록 및
removeList가 주어졌을 때
연결된
원격 스트림을 설정한다.
transceiver와
muteTracks가 주어졌을 때
미디어
설명에 대해 원격
원격
트랙 제거를 처리한다.
transceiver.[[CurrentDirection]]과
transceiver.[[FiredDirection]]을
direction으로 설정한다.
그렇지 않으면(remote가
true이면)
description의 각 미디어 설명에 대해
다음 단계를 실행한다:
description이
"offer"
유형이고
미디어
설명에 동시 송출 수신 요청이
포함되어 있으면, simulcast 속성에
지정된 rid 값의 순서를 사용하여
각 동시 송출 계층에 대한
RTCRtpEncodingParameters
사전을 생성하고,
대응하는 rid 값값에
따라(쉼표로 구분된 대안이 있으면
첫 번째 값만 사용하여)
rid
멤버를 채운 다음,
sendEncodingsproposedSendEncodings를
생성된 사전을 포함하는 목록으로
목록으로 둔다.
그렇지 않으면 sendEncodings를
proposedSendEncodings를
빈
목록으로
목록으로 둔다.
proposedSendEncodings의 각 인코딩
encoding에 대해 역순으로,
encoding의
rid가
proposedSendEncodings에 있는
다른 인코딩의 값과 일치하면
encoding을
proposedSendEncodings에서 제거한다.
scaleResolutionDownBy를
2^(length of sendEncodingsproposedSendEncodings -
encoding index - 1)로 설정한다.
[RFC8829RFC9429]
(5.10절)에
설명된 대로,
미디어
설명을 나타낼 기존
RTCRtpTransceiver
객체
transceiver를 찾으려고 시도한다.
적합한 트랜시버를 찾았고
(transceiver가 설정됨),
sendEncodingsproposedSendEncodings가
비어 있지 않으면,
transceiver.[[Sender]].[[SendEncodings]]를
sendEncodings로 설정하고,
transceiver.[[Sender]].[[LastReturnedParameters]]를
다음
단계를 실행한다:
null로 설정한다.
transceiver.[[Sender]].[[SendEncodings]]의
길이가 1이고 유일한 인코딩에
rid
멤버가 포함되어 있지 않으면,
transceiver.[[Sender]].[[SendEncodings]]를
proposedSendEncodings로 설정하고,
transceiver.[[Sender]].[[LastReturnedParameters]]를
null로 설정한다.
적합한 트랜시버를 찾지 못한 경우 (transceiver가 설정되지 않은 경우), 다음 단계를 실행한다:
RTCRtpSender를
생성하여,
sender로 하고, 미디어
미디어
설명에서
sendEncodingsproposedSendEncodings을
사용한다.
RTCRtpReceiver를
생성하여,
receiver로 하고, 미디어
미디어
설명을 사용한다.
RTCRtpTransceiver
생성에
sender, receiver
및 RTCRtpTransceiverDirection
값
"recvonly"를
사용하고, 그 결과를 transceiver로
한다.
transceiver를
connection의 트랜시버 집합에
집합에
추가한다.
description의 유형이
"answer"
또는
"pranswer"이고,
또한
transceiver.
[[Sender]].[[SendEncodings]]
.length가 1보다 크면, 다음
단계를 실행한다:
description이 동시 송출을
지원하지 않거나 원하지 않음을 나타내거나, 또는
description에 이전에 협상된
모든 계층이 누락된 경우,
transceiver.[[Sender]].[[SendEncodings]]에서
첫 번째 사전을 제외한 모든 사전을 제거하고 이 하위
단계들을 중단한다.
description이 거부한
누락한
제안된
이전에
협상된 계층이 하나라도 있으면, 그런
다음
그런
다음
transceiver.[[Sender]].[[SendEncodings]]에서
거부된
누락된
계층에 대응하는 해당
해당
사전을 제거한다.
각 동시 송출 계층의 일시 중지 상태를
[RFC8853]에
명시된 대로 갱신한다. 이를 위해
transceiver.[[Sender]].[[SendEncodings]]의
대응하는 사전에 있는
멤버를 일시 중지되지 않은 경우
activetrue로, 일시 중지된 경우
false로 설정한다.
transceiver.[[Mid]]를
transceiver.[[JsepMid]]로
설정한다.
direction을 미디어
미디어
설명의 방향을 나타내되, 송신 및 수신
방향을 반대로 하여 이 피어의 관점에서 나타내는
RTCRtpTransceiverDirection
값으로
한다. 미디어
설명이
거부된 경우, direction을
"inactive"로
설정한다.
direction이
"sendrecv"
또는
"recvonly"인
경우, msids를 미디어 설명이
transceiver.[[Receiver]].[[ReceiverTrack]]과
연결되어야 한다고 나타내는 MSID의 목록으로 한다.
그렇지 않으면 msids를 빈 목록으로 한다.
원격 트랙 처리에 transceiver, direction, msids, addList, removeList 및 trackEventInits를 사용한다.
transceiver.[[Receiver]].[[ReceiveCodecs]]를
description이 수신용으로 협상하고 사용자
에이전트가 현재 수신할 준비가 된 코덱으로 설정한다.
description의 유형이
"answer"
또는
"pranswer"이면,
다음
단계를 실행한다:
transceiver.[[Sender]].[[SendCodecs]]를
description이 송신용으로 협상하고 사용자
에이전트가 현재 송신할 수 있는 코덱으로 설정한다.
transceiver.[[CurrentDirection]]
및
transceiver.[[Direction]]들
을 direction으로 설정한다.
transport를
transceiver에 연결된
미디어
설명이 사용하는 미디어
미디어
전송의 RTP/RTCP 구성요소를
나타내는
RTCDtlsTransport
객체로 하며, 이는
[RFC8843]을
따른다.
transceiver.[[Sender]].[[SenderTransport]]를
transport로 설정한다.
transceiver.[[Receiver]].[[ReceiverTransport]]를
transport로 설정한다.
transport의 [[IceRole]]을
[RFC8445]의
규칙에 따라 설정한다.
[[IceRole]]이
unknown이
아니면,
[[IceRole]]을
수정하지 않는다.
controlling으로
설정한다.
a=ice-lite를
포함하면,
[[IceRole]]을
controlling으로
설정한다.
a=ice-lite를
포함하지 않으면,
[[IceRole]]을
controlled로
설정한다.
[[IceRole]]이
항상 값을
갖게 된다.
미디어
설명이 거부되었고,
transceiver.[[Stopped]]이
false이면,
transceiver RTCRtpTransceiver를
중지
중지
한다.
그렇지 않으면(description의 유형이
"rollback"인
경우)
다음 단계를 실행한다:
pendingDescription을
connection.[[PendingLocalDescription]]
또는
connection.[[PendingRemoteDescription]]
중 null이 아닌 것으로 한다.
connection의 트랜시버 집합에 있는 각 transceiver에 대해 다음 단계를 실행한다:
pendingDescription이 설정되기
전에 transceiver가 미디어
설명과 연결되어 있지
않았다면 연결을 해제하고,
transceiver.[[JsepMid]]와
transceiver.[[Mid]]를 모두
null로 설정한다.
transceiver.[[Sender]].[[SenderTransport]]를
transceiver.[[Sender]].[[LastStableStateSenderTransport]]로
설정한다.
transceiver.[[Sender]].[[LastStableRidlessSendEncodings]]이
null이 아니고,
transceiver.[[Sender]].[[SendEncodings]]의
인코딩 중 하나라도
rid
멤버를 포함하면,
transceiver.[[Sender]].[[SendEncodings]]을
transceiver.[[Sender]].[[LastStableRidlessSendEncodings]]로
설정한다.
transceiver.[[Receiver]].[[ReceiverTransport]]를
transceiver.[[Receiver]].[[LastStableStateReceiverTransport]]로
설정한다.
transceiver.[[Receiver]].[[ReceiveCodecs]]를
transceiver.[[Receiver]].[[LastStableStateReceiveCodecs]]로
설정한다.
connection.[[SignalingState]]이
"have-remote-offer"이면,
다음 하위 단계를 실행한다:
msids를
transceiver.[[Receiver]].[[LastStableStateAssociatedRemoteMediaStreams]]에
있는 모든
MediaStream
객체의 id 목록으로
하며, 객체가 없으면 빈 목록으로 한다.
원격
트랙 처리에
transceiver,
transceiver.[[CurrentDirection]],
msids, addList,
removeList 및
trackEventInits를 사용한다.
pendingDescription이 설정될 때
transceiver가 생성되었고,
addTrack()을
통해 트랙이 연결된 적이 없다면,
transceiver RTCRtpTransceiver를
중지하고,
connection의 트랜시버
집합에서 제거한다.
connection.[[PendingLocalDescription]]과
connection.[[PendingRemoteDescription]]을
null로 설정하고,
connection.[[SignalingState]]을
"stable"로
설정한다.
description의 유형이
"answer"이면,
다음
단계를 실행한다:
connection의 트랜시버 집합에 있는 각 transceiver에 대해 다음 단계를 실행한다:
transceiver가
stopped이고,
m= 섹션과 연결되어 있으며,
연결된 m=
섹션이
connection.[[CurrentLocalDescription]]
또는
connection.[[CurrentRemoteDescription]]에서
거부되었다면, transceiver를
connection의 트랜시버
집합에서 제거한다.
이제 connection.[[SignalingState]]이
"stable"이면,
다음
단계를 실행한다:
앞 단계에서 트랜시버 집합에서
제거된 각 transceiver에 대해,
해당 전송 중 하나라도
(transceiver.[[Sender]].[[SenderTransport]]
또는
transceiver.[[Receiver]].[[ReceiverTransport]])이
아직 닫히지 않았고, 더 이상 중지되지 않은
트랜시버가 참조하지 않는다면, 해당
RTCDtlsTransport와
연결된
RTCIceTransport를
닫는다.
그 결과 대기열에 추가된 태스크에서
이 객체들에 이벤트가 발생한다.
connection의 트랜시버 집합에 있는 각 transceiver에 대해:
codecs를 transceiver.[[Sender]].[[SendCodecs]]로
한다.
codecs가 빈 목록이 아니면:
transceiver.[[Sender]].[[SendEncodings]]의
각 encoding에 대해,
encoding.codec이
ignoreLevels를
true로 설정한 코덱
사전 일치 알고리즘을 사용해
codecs의 어떤 항목과도 일치하지 않으면,
encoding.codec을
제거한다.
위에서 connection.[[SignalingState]]이
변경되었다면, connection에서
signalingstatechange라는
이름의 이벤트를 발생시킨다.
errorList의 각 channel에 대해,
RTCErrorEvent
인터페이스를 사용하고
errorDetail
속성을
"data-channel-failure"로
설정하여, channel에서
error라는
이름의 이벤트를 발생시킨다.
muteTracks의 각 track에 대해,
track의 음소거
상태를
true로 설정한다.
removeList의 각 stream 및 track 쌍에 대해, stream에서 track을 제거한다.
addList의 각 stream 및 track 쌍에 대해, stream에 track을 추가 한다.
trackEventInits의 각 항목 entry에 대해,
이벤트를 발생시킨다. 이벤트의 이름은
track이며, RTCTrackEvent
인터페이스를 사용하고,
그 receiver
속성은
entry.receiver로
초기화하고,
그 track
속성은
entry.track으로
초기화하고,
그
streams
속성은
entry.streams로
초기화하며,
또한
그 transceiver
속성은
entry.transceiver로
초기화하여
connection 객체에서 발생시킨다.
p를
undefined로 이행한다.
p를 반환한다.
구성을 설정하기 위해 configuration을 사용하여 다음 단계를 실행한다:
connection을 대상 RTCPeerConnection
객체로 한다.
oldConfig를
connection.[[Configuration]]으로 한다.
oldConfig가 null이 아니면 다음
단계를 실행하고, 그중 하나라도 실패하면 다음 예외를 던진다:
InvalidModificationError:
configuration.certificates의
길이가
oldConfig.certificates의
길이와 다르면 실패한다.
index를 0으로 한다.
index가
configuration.certificates의
길이보다 작은 동안 다음 단계를 실행한다:
configuration.certificates의
index 위치에 있는 값이 나타내는 ECMAScript 객체가
oldConfig.certificates의
index 위치에 있는 값이 나타내는 ECMAScript
객체와 같지 않으면 실패한다.
index를 1만큼 증가시킨다.
configuration.bundlePolicy의
값이
oldConfig.bundlePolicy와
다르면 실패한다.
configuration.rtcpMuxPolicy의
값이
oldConfig.rtcpMuxPolicy와
다르면 실패한다.
configuration.iceCandidatePoolSize의
값이
oldConfig.iceCandidatePoolSize와
다르고, setLocalDescription이
이미
호출되었다면 실패한다.
iceServers를
configuration.iceServers로 한다.
iceServers를 지원되는 최대 요소 수로 잘라낸다.
iceServers의 각 server에 대해 다음 단계를 실행한다:
urls를
server.urls로 한다.
urls가 문자열이면, urls를 해당 문자열 하나로만 구성된 목록으로 설정한다.
urls가 비어 있으면 다음 예외를 던진다:
"SyntaxError" DOMException.
urls의 각 url에 대해, url에 ICE 서버 URL 검증 알고리즘을 실행한다.
ICE 에이전트의 ICE 전송 설정을
configuration.iceTransportPolicy의
값으로 설정한다.
[RFC9429]
(4.1.18절
)에 정의된 대로, 새 ICE 전송 설정이 기존
설정을 변경하는 경우 다음 수집 단계까지
아무 작업도 수행되지 않는다. 스크립트가
이를 즉시 적용하려면 ICE
재시작을 수행해야 한다.
[RFC9429]
(3.5.4절
및 4.1.1절
)에 정의된 대로 ICE 에이전트의 미리 가져온 ICE 후보 풀
크기를
configuration.iceCandidatePoolSize의
값으로 설정한다.
새 ICE 후보 풀
크기가 기존
설정을 변경하면, [RFC9429]
(4.1.18절
)에 정의된 대로 새 풀 후보가 즉시
수집되거나 기존 풀 후보가 폐기될 수
있다.
ICE 에이전트의 ICE 서버 목록을 iceServers로 설정한다.
[RFC9429] (4.1.18절 )에 정의된 대로, 새 서버 목록이 ICE 에이전트의 기존 ICE 서버 목록을 교체하면 다음 수집 단계까지 아무 작업도 수행되지 않는다. 스크립트가 이를 즉시 적용하려면 ICE 재시작을 수행해야 한다. 그러나 ICE 후보 풀의 크기가 0이 아니면 기존 풀 후보는 모두 폐기되고 새 후보가 새 서버에서 수집된다.
configuration을
[[Configuration]] 내부 슬롯에 저장한다.
url에 대해 ICE 서버 URL을 검증하려면 다음 단계를 실행한다:
[RFC3986]에
정의된 일반 URI 구문을 사용하여 url을 구문 분석하고
scheme
name을 얻는다. [RFC3986]에
정의된 구문에 따른 구문 분석이 실패하면
다음 예외를 던진다:
SyntaxError.
scheme name이
브라우저에서 구현되지 않은 경우 다음 예외를 던진다:
NotSupportedError.
scheme name이
turn 또는 turns이고,
[RFC7065]에
정의된 구문으로 url을 구문 분석하는 데
실패하면 다음 예외를 던진다: SyntaxError.
scheme
name이 stun 또는
stuns이고,
[RFC7064]에
정의된 구문으로 url을 구문 분석하는 데
실패하면 다음 예외를 던진다:
SyntaxError.
parsedURL을 url을 구문 분석한 결과로 한다.
다음 조건 중 하나라도 적용되면 다음 예외를 던진다:
"SyntaxError" DOMException:
parsedURL의 스킴이 사용자 에이전트에서
구현되지 않았다면 다음 예외를 던진다: NotSupportedError.
hostAndPortURL을
"https://"와 parsedURL의 경로를 연결한 문자열을 구문 분석한
결과로 한다.
hostAndPortURL이 실패이면 다음 예외를 던진다:
"SyntaxError" DOMException.
hostAndPortURL의 경로,
사용자
이름 또는 비밀번호가 null이 아니면
다음 예외를 던진다: "SyntaxError" DOMException.
parsedURL의 쿼리가 null이 아니고 parsedURL의 쿼리가
"transport=udp" 또는 "transport=tcp" 중 어느 것과도 다르면
다음 예외를 던진다: "SyntaxError" DOMException.
scheme nameparsedURL's' 스킴이 turn"turn" 또는 또는
turns"turns"이고,
server.username 또는
server.credential 중 하나가 생략되어
있으면
존재하지 않으면, 다음 예외를 던진다:
InvalidAccessError.
scheme name이 turn 또는 turns이고,
server.credentialType이
""이고,
server.passwordcredential이
DOMString이 아니면
다음 예외를 던진다: InvalidAccessError.
이 절에서 제시하는 RTCPeerConnection 인터페이스는 이 명세 전반의 여러
부분 인터페이스에 의해 확장된다. 특히 RTP 미디어 API 절은
MediaStreamTrack 객체를 송수신하는 API를 추가한다.
WebIDL[Exposed=Window]
interface RTCPeerConnection : EventTarget {
constructor(optional RTCConfiguration configuration = {});
Promise<RTCSessionDescriptionInit> createOffer(optional RTCOfferOptions options = {});
Promise<RTCSessionDescriptionInit> createAnswer(optional RTCAnswerOptions options = {});
Promise<undefined> setLocalDescription(optional RTCLocalSessionDescriptionInit description = {});
readonly attribute RTCSessionDescription? localDescription;
readonly attribute RTCSessionDescription? currentLocalDescription;
readonly attribute RTCSessionDescription? pendingLocalDescription;
Promise<undefined> setRemoteDescription(RTCSessionDescriptionInit description);
readonly attribute RTCSessionDescription? remoteDescription;
readonly attribute RTCSessionDescription? currentRemoteDescription;
readonly attribute RTCSessionDescription? pendingRemoteDescription;
Promise<undefined> addIceCandidate(optional RTCIceCandidateInit candidate = {});
readonly attribute RTCSignalingState signalingState;
readonly attribute RTCIceGatheringState iceGatheringState;
readonly attribute RTCIceConnectionState iceConnectionState;
readonly attribute RTCPeerConnectionState connectionState;
readonly attribute boolean? canTrickleIceCandidates;
undefined restartIce();
RTCConfiguration getConfiguration();
undefined setConfiguration(optional RTCConfiguration configuration = {});
undefined close();
attribute EventHandler onnegotiationneeded;
attribute EventHandler onicecandidate;
attribute EventHandler onicecandidateerror;
attribute EventHandler onsignalingstatechange;
attribute EventHandler oniceconnectionstatechange;
attribute EventHandler onicegatheringstatechange;
attribute EventHandler onconnectionstatechange;
// 레거시 인터페이스 확장
// 이 절의 메서드 지원은 선택 사항이다.
// 이러한 메서드를 지원하는 경우
// "레거시 인터페이스 확장" 절에 정의된 대로
// 구현해야 한다.
Promise<undefined> createOffer(RTCSessionDescriptionCallback successCallback,
RTCPeerConnectionErrorCallback failureCallback,
optional RTCOfferOptions options = {});
Promise<undefined> setLocalDescription(RTCLocalSessionDescriptionInit description,
VoidFunction successCallback,
RTCPeerConnectionErrorCallback failureCallback);
Promise<undefined> createAnswer(RTCSessionDescriptionCallback successCallback,
RTCPeerConnectionErrorCallback failureCallback);
Promise<undefined> setRemoteDescription(RTCSessionDescriptionInit description,
VoidFunction successCallback,
RTCPeerConnectionErrorCallback failureCallback);
Promise<undefined> addIceCandidate(RTCIceCandidateInit candidate,
VoidFunction successCallback,
RTCPeerConnectionErrorCallback failureCallback);
};
localDescription
유형: RTCSessionDescription,
읽기 전용,
null 허용
localDescription
속성은
[[PendingLocalDescription]]이
null이 아니면 이를 반드시 반환하고, 그렇지 않으면
[[CurrentLocalDescription]]을
반드시 반환해야 한다.
[[CurrentLocalDescription]].sdp와
[[PendingLocalDescription]].sdp는
대응하는 setLocalDescription
호출에 전달된
sdp 값과
문자열 단위로 동일하지 않을 수 있음에 유의한다
(즉, SDP가 구문 분석되고 다시 형식화되며 ICE 후보가 추가될 수 있다).
currentLocalDescription
유형: RTCSessionDescription,
읽기 전용,
null 허용
currentLocalDescription
속성은
[[CurrentLocalDescription]]을
반드시 반환해야 한다.
이는 RTCPeerConnection이
마지막으로 stable 상태로 전환되었을 때 성공적으로
협상된 로컬 설명과, 제안 또는 응답이 생성된 이후
ICE
에이전트가 생성한 모든 로컬 후보를 나타낸다.
pendingLocalDescription
유형: RTCSessionDescription,
읽기 전용,
null 허용
pendingLocalDescription
속성은
[[PendingLocalDescription]]을
반드시 반환해야 한다.
이는 현재 협상 중인 로컬 설명과, 제안 또는 응답이
생성된 이후 ICE 에이전트가 생성한 모든
로컬 후보를 나타낸다. RTCPeerConnection이
stable
상태이면 값은 null이다.
remoteDescription
유형: RTCSessionDescription,
읽기 전용,
null 허용
remoteDescription
속성은
[[PendingRemoteDescription]]이
null이 아니면 이를 반드시 반환하고, 그렇지 않으면
[[CurrentRemoteDescription]]을
반드시 반환해야 한다.
[[CurrentRemoteDescription]].sdp와
[[PendingRemoteDescription]].sdp는
대응하는 setRemoteDescription
호출에 전달된
sdp 값과
문자열 단위로 동일하지 않을 수 있음에 유의한다
(즉, SDP가 구문 분석되고 다시 형식화되며 ICE 후보가 추가될 수 있다).
currentRemoteDescription
유형: RTCSessionDescription,
읽기 전용,
null 허용
currentRemoteDescription
속성은
[[CurrentRemoteDescription]]을
반드시 반환해야 한다.
이는 RTCPeerConnection이
마지막으로 stable 상태로 전환되었을 때 성공적으로 협상된
최종 원격 설명과, 제안 또는 응답이 생성된 이후
addIceCandidate()를
통해 제공된 모든 원격 후보를 나타낸다.
pendingRemoteDescription
유형: RTCSessionDescription,
읽기 전용,
null 허용
pendingRemoteDescription
속성은
[[PendingRemoteDescription]]을
반드시 반환해야 한다.
이는 현재 협상 중인 원격 설명과, 제안 또는 응답이
생성된 이후
addIceCandidate()를
통해 제공된 모든 원격 후보를 나타낸다.
RTCPeerConnection이
stable
상태이면 값은 null이다.
signalingState의
유형: RTCSignalingState,
읽기 전용
signalingState
속성은 RTCPeerConnection
객체의
[[SignalingState]]을
반드시 반환해야 한다.
iceGatheringState
유형: RTCIceGatheringState,
읽기 전용
iceGatheringState
속성은 RTCPeerConnection
객체의
[[IceGatheringState]]을
반드시 반환해야 한다.
iceConnectionState
유형: RTCIceConnectionState,
읽기 전용
iceConnectionState
속성은 RTCPeerConnection
객체의
[[IceConnectionState]]을
반드시 반환해야 한다.
connectionState
유형: RTCPeerConnectionState,
읽기 전용
connectionState
속성은 RTCPeerConnection
객체의
[[ConnectionState]]을
반드시 반환해야 한다.
canTrickleIceCandidates의 유형:
boolean, 읽기 전용, null 허용
canTrickleIceCandidates
속성은 원격 피어가 Trickle ICE 후보를 수락할 수 있는지를 나타낸다
[RFC8838].
이 값은 [RFC9429]
(4.1.17절
)에 정의된 대로
원격 설명이 Trickle ICE 지원을 나타내는지에 따라 결정된다.
setRemoteDescription이
완료되기 전에는 이 값이
null이다.
onnegotiationneeded의 유형:
EventHandler
negotiationneeded이다.
onicecandidate의 유형: EventHandler
icecandidate이다.
onicecandidateerror의 유형:
EventHandler
icecandidateerror이다.
onsignalingstatechange의 유형:
EventHandler
signalingstatechange이다.
oniceconnectionstatechange의 유형:
EventHandler
iceconnectionstatechange
onicegatheringstatechange의 유형:
EventHandler
icegatheringstatechange이다.
onconnectionstatechange의 유형:
EventHandler
connectionstatechange이다.
createOffer
createOffer
메서드는 이 RTCPeerConnection에
연결된 로컬 MediaStreamTrack의 설명,
이 구현이 지원하는 코덱/RTP/RTCP 기능, ICE 에이전트와 DTLS 연결의 매개변수를
포함하여
세션에 지원되는 구성이 담긴 RFC 3264 제안을 포함하는
SDP 블롭을 생성한다.
생성되는 제안을 추가로 제어하기 위해
options 매개변수를 제공할 수 있다.
시스템의 리소스가 제한된 경우(예: 디코더 수가 유한한 경우),
createOffer는
시스템의 현재 상태를 반영하는 제안을 반환해야 한다. 그래야
setLocalDescription이
해당 리소스를 확보하려고 할 때 성공한다.
세션 설명은 반환된 프로미스의 이행
콜백이 끝날 때까지 오류를 발생시키지 않고
setLocalDescription에서
사용할 수 있는 상태를 반드시 유지해야 한다.
SDP 생성은 [RFC9429]에 설명된
적절한 제안 생성 절차를 반드시 따라야 한다.
다만 이 경우 사용자 에이전트는 RFC9429의 목적상
stopping
트랜시버를 stopped로
반드시 취급해야 한다.
생성된 SDP는 제안이므로 세션에서 지원하거나 선호하는
코덱/RTP/RTCP 기능의 전체 집합을 포함한다
(사용할 특정 협상 하위 집합만 포함하는 응답과는 다르다).
세션이 설정된 후
createOffer가
호출되는 경우,
createOffer는
트랙 추가 또는 제거처럼 마지막으로 완료된 제안-응답 교환 이후
세션에 적용된 모든 변경 사항을 통합하여 현재 세션과 호환되는
제안을 생성한다. 변경 사항이 없으면 제안에는 현재 로컬 설명의
기능과 갱신된 제안에서 추가로 협상할 수 있는 기능이
포함된다.
생성된 SDP에는 ICE
에이전트의
usernameFragment,
password 및 ICE
옵션([RFC5245]
14절에 정의됨)이 포함되며, 에이전트가 수집한 모든 로컬
후보도 포함될 수 있다.
RTCPeerConnection의
configuration에 있는
certificates
값은 애플리케이션이
RTCPeerConnection에
구성한 인증서를 제공한다. 이러한 인증서는
모든 기본 인증서와 함께 인증서 지문 집합을 생성하는 데
사용된다. 이 인증서 지문은 SDP 구성에 사용된다.
SDP 생성 과정은 기반 시스템의 미디어 기능 중 일부를
노출하며, 이는 일반적으로 기기에 관한 지속적인 교차 출처
정보를 제공한다. 따라서 애플리케이션의 핑거프린팅 노출 면적이
증가한다. 개인정보 보호에 민감한 환경에서 브라우저는
공통 기능 하위 집합에만 일치하는 SDP를 생성하는 등의
완화책을 고려할 수 있다.
이 메서드가 호출되면 사용자 에이전트는 다음 단계를 반드시 실행해야 한다:
connection을 메서드가 호출된 RTCPeerConnection
객체로 한다.
connection.[[IsClosed]]가
true이면, 새로 생성된
InvalidStateError로
거부된 프로미스를 반환한다.
connection이 주어졌을 때 제안을 생성하려면 다음 단계를 실행한다:
connection.[[SignalingState]]이
"stable"도
아니고
"have-local-offer"도
아니면, 새로
생성된
InvalidStateError로
거부된
프로미스를 반환한다.
p를 새 프로미스로 한다.
병렬로, connection과 p가 주어졌을 때의 제안을 생성하는 병렬 단계를 시작한다.
p를 반환한다.
connection과 프로미스 p가 주어졌을 때의 제안을 생성하는 병렬 단계는 다음과 같다:
connection이 인증서 집합을 사용하여 생성되지 않았고 아직 인증서가 생성되지 않았다면, 인증서가 생성될 때까지 기다린다.
[RFC9429] (4.1.8절 )에 설명된 대로, 제안을 생성하는 데 필요한 현재 사용 가능한 리소스를 확인하기 위해 제안자의 시스템 상태를 검사한다.
이 검사가 어떤 이유로든 실패하면 새로 생성된
OperationError로
p를 거부하고 이 단계들을 중단한다.
connection과 p가 주어졌을 때의 제안 생성의 최종 단계를 실행하는 태스크를 대기열에 추가한다.
connection과 프로미스 p가 주어졌을 때의 제안 생성의 최종 단계는 다음과 같다:
connection.[[IsClosed]]가
true이면 이 단계들을 중단한다.
connection이 제안자의 시스템 상태를 추가로 검사해야 하는 방식으로 수정되었다면, 병렬로 connection과 p가 주어진 제안을 생성하는 병렬 단계를 다시 시작하고 이 단계들을 중단한다.
RTCRtpTransceiver만
connection에 추가된 상태에서
createOffer가
호출되었지만, 제안을
생성하는 병렬 단계를 수행하는 동안 비디오
RTCRtpTransceiver가
추가되어 비디오 시스템 리소스를 추가로
검사해야 하는 경우가 이에 해당할 수 있다.
이전 검사에서 얻은 정보와 connection 및 그
RTCRtpTransceiver들의
현재 상태를 바탕으로, [RFC9429]
(5.2절
)에 설명된 SDP 제안
sdpString을 생성한다.
[RFC8843]
7절에 설명된 대로 번들링을 사용하는 경우
(RTCBundlePolicy
참조),
BUNDLE 그룹을 협상하려면 제안자 태그가 지정된
m= 섹션을 선택해야 한다. 사용자 에이전트는
트랜시버
집합에서
중지되지 않은 첫 번째 트랜시버에 대응하는 m= 섹션을
제안자 태그가 지정된 m= 섹션으로
반드시 선택해야 한다.
이렇게 하면 원격 엔드포인트가 SDP를 구문 분석하지
않고도 어떤 트랜시버가 제안자 태그가 지정된 m= 섹션인지
예측할 수 있다.
filteredCodecs를
transceiver.[[PreferredCodecs]]에
다음 필터를 적용한 결과로 한다.
필터링은 코덱 선호도의 순서를
변경해서는 안 된다:
kind를 transceiver의
[[Receiver]]의
[[ReceiverTrack]]의
kind로
한다.
transceiver.direction이
"sendonly"
또는 "sendrecv"이면,
ignoreLevels를
true로 설정한 코덱
사전 일치
알고리즘을 사용하여 kind의
구현된
송신 코덱 목록에 포함되지 않은 코덱을 제외한다.
transceiver.direction이
"recvonly"
또는 "sendrecv"이면,
ignoreLevels를
true로 설정한 코덱
사전 일치
알고리즘을 사용하여 kind의
구현된
수신 코덱 목록에 포함되지 않은 코덱을 제외한다.
미디어 설명과 연결된 트랜시버 transceiver의 코덱 선호도는 filteredCodecs가 비어 있지 않으면 그 값으로 정의되고, 그렇지 않으면 설정되지 않은 것으로 정의된다.
RTCRtpSender의
[[SendEncodings]]
슬롯의 길이가 1보다 크면,
RTCRtpSender의
[[SendEncodings]]에
주어진 각 인코딩에 대해 대응하는 미디어 섹션에
a=rid send 줄을 추가하고,
encodings
필드에 지정된 것과 같은 순서로 RID를 나열하는
a=simulcast:send
줄을 추가한다. RID
제한은 설정하지 않는다.
[RFC8853] 5.2절은 a=simulcast 줄에 있는 RID의 순서가 제안된 선호 순서를 나타낸다고 규정한다. 브라우저가 모든 인코딩을 전송하지 않기로 결정하면 목록의 마지막 인코딩부터 전송을 중지할 것으로 예상해야 한다.
offer를 새로 생성된
RTCSessionDescriptionInit
사전으로 한다. 이 사전의
type
멤버는 문자열 "offer"로 초기화하고,
sdp
멤버는
sdpString으로 초기화한다.
[[LastCreatedOffer]]
내부 슬롯을
sdpString으로 설정한다.
p를 offer로 이행한다.
createAnswer
createAnswer
메서드는 원격 구성의 매개변수와 호환되는 세션 지원 구성을 포함한
[SDP]
응답을
생성한다.
createOffer와
마찬가지로 반환되는 SDP 블롭에는 이
RTCPeerConnection에
연결된 로컬 MediaStreamTrack의 설명,
이 세션에 대해 협상된 코덱/RTP/RTCP 옵션,
ICE 에이전트가 수집한 모든
후보가 포함된다. 생성되는 응답을 추가로 제어하기 위해
options 매개변수를 제공할 수 있다.
createOffer와
마찬가지로 반환되는 설명은 시스템의 현재 상태를
반영하는 것이 좋다. 세션
설명은 반환된 프로미스의 이행 콜백이 끝날 때까지 오류를 발생시키지 않고
setLocalDescription에서
사용할 수 있는 상태를 반드시 유지해야 한다.
생성된 SDP는 응답이므로, 대응하는 제안과 함께 미디어 평면을 설정하는 방법을 지정하는 특정 코덱/RTP/RTCP 구성을 포함한다. SDP 생성은 [RFC9429]에 설명된 적절한 응답 생성 절차를 반드시 따라야 한다.
생성된 SDP에는 ICE
에이전트의
usernameFragment,
password 및 ICE
옵션([RFC5245]
14절에 정의됨)이 포함되며, 에이전트가 수집한 모든 로컬
후보도 포함될 수 있다.
RTCPeerConnection의
configuration에 있는
certificates
값은 애플리케이션이
RTCPeerConnection에
구성한 인증서를 제공한다. 이러한 인증서는
모든 기본 인증서와 함께 인증서 지문 집합을 생성하는 데
사용된다. 이 인증서 지문은 SDP 구성에 사용된다.
응답은 [RFC9429]
(4.1.10.1절
)에 설명된 대로
type을
"pranswer"로 설정하여
임시 응답으로 표시할 수 있다.
이 메서드가 호출되면 사용자 에이전트는 다음 단계를 반드시 실행해야 한다:
connection을 메서드가 호출된 RTCPeerConnection
객체로 한다.
connection.[[IsClosed]]가
true이면, 새로 생성된
InvalidStateError로
거부된 프로미스를 반환한다.
connection이 주어졌을 때 응답을 생성하려면 다음 단계를 실행한다:
connection.[[SignalingState]]이
"have-remote-offer"도
아니고
"have-local-pranswer"도
아니면, 새로
생성된
InvalidStateError로
거부된
프로미스를 반환한다.
p를 새 프로미스로 한다.
병렬로, connection과 p가 주어졌을 때의 응답을 생성하는 병렬 단계를 시작한다.
p를 반환한다.
connection과 프로미스 p가 주어졌을 때의 응답을 생성하는 병렬 단계는 다음과 같다:
connection이 인증서 집합을 사용하여 생성되지 않았고 아직 인증서가 생성되지 않았다면, 인증서가 생성될 때까지 기다린다.
[RFC9429] (4.1.9절 )에 설명된 대로, 응답을 생성하는 데 필요한 현재 사용 가능한 리소스를 확인하기 위해 응답자의 시스템 상태를 검사한다.
이 검사가 어떤 이유로든 실패하면 새로 생성된
OperationError로
p를 거부하고 이
단계들을 중단한다.
p가 주어졌을 때의 응답 생성의 최종 단계를 실행하는 태스크를 대기열에 추가한다.
프로미스 p가 주어졌을 때의 응답 생성의 최종 단계는 다음과 같다:
connection.[[IsClosed]]가
true이면 이 단계들을 중단한다.
connection이 응답자의 시스템 상태를 추가로 검사해야 하는 방식으로 수정되었다면, 병렬로 connection과 p가 주어진 응답을 생성하는 병렬 단계를 다시 시작하고 이 단계들을 중단한다.
RTCRtpTransceiver의
방향이
"recvonly"일
때
createAnswer가
호출되었지만,
응답을
생성하는 병렬 단계를 수행하는 동안 방향이
"sendrecv"로
변경되어
비디오 인코딩 리소스를 추가로 검사해야 하는 경우가 이에 해당할 수 있다.
이전 검사에서 얻은 정보와
connection 및 그 RTCRtpTransceiver들의
현재 상태를 바탕으로, [RFC9429]
(5.3절
)에 설명된 SDP 응답
sdpString을 생성한다.
m= 섹션과 연결된 트랜시버의 코덱 선호도는
다음 필터링이 적용된
.[[PreferredCodecs]]의
값으로 정의된다([[PreferredCodecs]]가 비어 있으면 설정되지 않은 것으로
정의된다):
RTCRtpTransceiver
이
"directionsendrecv"이면,
.RTCRtpSender(kind).getCapabilities와
codecs.RTCRtpReceiver(kind).getCapabilities의
교집합에 포함되지 않은 코덱을 제외한다.
codecs
이
"direction"이면,
sendonly.RTCRtpSender(kind).getCapabilities에
포함되지 않은 코덱을 제외한다.
codecs
이
"direction"이면,
recvonly.RTCRtpReceiver(kind).getCapabilities에
포함되지 않은 코덱을 제외한다.
codecs
필터링은 코덱 선호도의 순서를 변경해서는 안 된다.
의
[[SendEncodings]]
슬롯의 길이가 1보다 크면,
RTCRtpSender의
[[SendEncodings]]에
지정된 각 인코딩에 대해 대응하는
미디어 섹션에 RTCRtpSendera=rid send 줄을 추가하고,
RID를
필드에 지정된 것과 같은 순서로 나열하는 encodingsa=simulcast:send
줄을 추가한다.
RID 제한은 설정하지 않는다.
filteredCodecs를
transceiver.[[PreferredCodecs]]에
다음 필터를 적용한 결과로 한다.
필터링은 코덱 선호도의 순서를
변경해서는 안 된다:
kind를 transceiver의
[[Receiver]]의
[[ReceiverTrack]]의
kind로
한다.
transceiver.direction이
"sendonly"
또는 "sendrecv"이면,
ignoreLevels를
true로 설정한 코덱
사전 일치
알고리즘을 사용하여 kind의
구현된
송신 코덱 목록에 포함되지 않은 코덱을 제외한다.
transceiver.direction이
"recvonly"
또는 "sendrecv"이면,
ignoreLevels를
true로 설정한 코덱
사전 일치
알고리즘을 사용하여 kind의
구현된
수신 코덱 목록에 포함되지 않은 코덱을 제외한다.
미디어 설명과 연결된 트랜시버 transceiver의 코덱 선호도는 filteredCodecs가 비어 있지 않으면 그 값으로 정의되고, 그렇지 않으면 설정되지 않은 것으로 정의된다.
이것이 동시 송출 수신 제안에 대한 응답이면, 동시 송출 수신을 요청하는 각 미디어 섹션에 대해 다음 단계를 실행한다:
a=simulcast
속성에 RID의 쉼표로 구분된 대안이 포함되어 있으면
첫 번째 항목을 제외한 나머지를 모두 제거한다.
a=simulcast 속성에
이름이 같은 RID가 있으면 첫 번째 항목을 제외한
나머지를 모두 제거한다. RID 제한은 설정하지 않는다.
대응하는 트랜시버의
[[Sender]].[[SendEncodings]]에서
찾을 수 없는 RID를 응답의 미디어 섹션에서 제외한다.
setRemoteDescription(offer)가
송신자의 제안된
엔벌로프를 설정하면,
송신자의 [[SendEncodings]]은
"have-remote-offer"에서
갱신되어 롤백에
노출된다. 그러나 송신자에 대해
동시 송출
엔벌로프가 설정된 후에는,
송신자의 [[SendEncodings]]에
대한 이후의 가지치기는 이 응답이
setLocalDescription으로
설정될 때 발생한다.
answer를 새로 생성된
RTCSessionDescriptionInit
사전으로 한다. 이 사전의
type
멤버는 문자열 "answer"로 초기화하고,
sdp
멤버는
sdpString으로 초기화한다.
[[LastCreatedAnswer]]
내부 슬롯을
sdpString으로 설정한다.
p를 answer로 이행한다.
setLocalDescription
setLocalDescription
메서드는 제공된
RTCLocalSessionDescriptionInit을
로컬 설명으로 적용하도록
RTCPeerConnection에
지시한다.
이 API는 로컬 미디어 상태를 변경한다. 애플리케이션이 한
미디어 형식에서 호환되지 않는 다른 형식으로 변경하도록
제안하려는 시나리오를 성공적으로 처리하기 위해,
RTCPeerConnection은
최종 응답을 받을 때까지 현재 로컬 설명과 보류 중인
로컬 설명을 모두 동시에 사용할 수 있도록
반드시 지원해야 한다
(예: 두 설명에 모두 존재하는 코덱을 지원해야 한다).
최종 응답을 받으면 RTCPeerConnection은
보류 중인 로컬 설명을 완전히 채택하거나, 원격 측이 변경을
거부했다면 현재 설명으로 롤백할 수 있다.
설명 전달은 선택 사항이다. 생략하면
setLocalDescription은
필요에 따라 암시적으로 제안을 생성하거나
응답을 생성한다.
[RFC9429]
(5.4절
)에 명시된 것처럼 SDP가 포함된
설명을 전달하는 경우, 해당 SDP는
createOffer 또는
createAnswer에서
반환된 이후 변경되어서는 안 된다.
이 메서드가 호출되면 사용자 에이전트는 다음 단계를 반드시 실행해야 한다:
description을 메서드의 첫 번째 인수로 한다.
connection을 메서드가 호출된 RTCPeerConnection
객체로 한다.
sdp를
description.sdp로
한다.
다음 단계들을 connection의 작업 체인에 연결한 결과를 반환한다:
type을
description.type이
있으면 그 값으로 한다. 없고
connection.[[SignalingState]]이
"stable",
"have-local-offer"
또는
"have-remote-pranswer"
중
하나이면 "offer"로
한다.
그렇지 않으면 "answer"로
한다.
type이 "offer"이고,
sdp가 빈 문자열이 아니며
connection.[[LastCreatedOffer]]와
같지 않으면, 새로
생성된
InvalidModificationError로
거부된 프로미스를
반환하고
이 단계들을 중단한다.
type이 "answer"
또는
"pranswer"이고,
sdp가
빈 문자열이 아니며
connection.[[LastCreatedAnswer]]와
같지 않으면, 새로
생성된
InvalidModificationError로
거부된 프로미스를
반환하고
이 단계들을 중단한다.
sdp가 빈 문자열이고
type이 "offer"이면
다음
하위 단계를 실행한다:
sdp를
connection.[[LastCreatedOffer]]의
값으로 설정한다.
sdp가 빈 문자열이거나 더 이상 connection의 제안자의 시스템 상태를 정확히 나타내지 않으면, p를 connection으로 제안을 생성한 결과로 하고, p에 첫 번째 인수가 나타내는 로컬 세션 설명을 설정하는 이행 단계로 반응한 결과를 반환한다.
sdp가 빈 문자열이고
type이 "answer"
또는
"pranswer"이면,
다음
하위 단계를 실행한다:
sdp를
connection.[[LastCreatedAnswer]]의
값으로 설정한다.
sdp가 빈 문자열이거나 더 이상 connection의 응답자의 시스템 상태를 정확히 나타내지 않으면, p를 connection으로 응답을 생성한 결과로 하고, 다음 이행 단계로 p에 반응한 결과를 반환한다:
answer를 이 이행 단계의 첫 번째 인수로 한다.
{type,
answer.가
나타내는
로컬 세션
설명을 설정한 결과를 반환한다.
sdp}
{type, sdp}가
나타내는 로컬 세션
설명을 설정한 결과를 반환한다.
setRemoteDescription
setRemoteDescription
메서드는 제공된
RTCSessionDescriptionInit을
원격 제안 또는
응답으로 적용하도록 RTCPeerConnection에
지시한다. 이 API는 로컬 미디어 상태를 변경한다.
이 메서드가 호출되면 사용자 에이전트는 다음 단계를 반드시 실행해야 한다:
description을 메서드의 첫 번째 인수로 한다.
connection을 메서드가 호출된 RTCPeerConnection
객체로 한다.
다음 단계들을 connection의 작업 체인에 연결한 결과를 반환한다:
description.type이
"offer"이고
[RFC9429]
(5.5절
및 5.6절
)에 설명된 현재
connection.[[SignalingState]]에
유효하지 않으면 다음 하위 단계를 실행한다:
p를
{type:
"이
나타내는 로컬 세션
설명을 설정한 결과로 한다.
rollback"}
p에 description을 원격 세션 설명으로 설정하는 이행 단계로 반응한 결과를 반환하고, 이 단계들을 중단한다.
description을 원격 세션 설명으로 설정한 결과를 반환한다.
addIceCandidate
addIceCandidate
메서드는 원격 후보를 ICE 에이전트에 제공한다.
이 메서드는 candidate 멤버가
빈 문자열인 상태로 호출하면 원격 후보의 끝을 나타내는 데도 사용할 수 있다.
이 메서드가 사용하는 인수의 멤버는
candidate, sdpMid,
sdpMLineIndex,
그리고
usernameFragment뿐이며,
나머지는 무시된다.
이 메서드가 호출되면 사용자 에이전트는 다음 단계를
반드시 실행해야 한다:
candidate를 메서드의 인수로 한다.
connection을 메서드가 호출된 RTCPeerConnection
객체로 한다.
candidate.candidate가
빈 문자열이 아니고,
candidate.sdpMid와
candidate.sdpMLineIndex가
모두 null이면, 새로
생성된
TypeError로
거부된 프로미스를 반환한다.
다음 단계들을 connection의 작업 체인에 연결한 결과를 반환한다:
remoteDescription이
null이면 새로 생성된
InvalidStateError로
거부된
프로미스를 반환한다.
candidate.sdpMid가
null이 아니면 다음 단계를 실행한다:
candidate.sdpMid가
remoteDescription에
있는 어떤 미디어 설명의 mid와도 같지 않으면,
새로 생성된
OperationError로
거부된
프로미스를 반환한다.
그렇지 않고
candidate.sdpMLineIndex가
null이 아니면 다음 단계를 실행한다:
candidate.sdpMLineIndex가
remoteDescription의
미디어 설명 수 이상이면,
새로 생성된
OperationError로
거부된
프로미스를 반환한다.
candidate.sdpMid
또는
candidate.sdpMLineIndex
중
하나가 remoteDescription에서
연결된 트랜시버가 stopped인
미디어 설명을 나타내면, undefined로
이행된
프로미스를 반환한다.
candidate.usernameFragment가
null이 아니고, 적용된 원격 설명의 대응하는 미디어
설명에 존재하는 어떤 사용자 이름 프래그먼트와도 같지 않으면,
새로 생성된
OperationError로
거부된 프로미스를
반환한다.
p를 새 프로미스로 한다.
병렬로, 후보가 관리상
금지되지 않았다면,
[RFC9429]
(4.1.19절
)에 설명된 대로 ICE 후보
candidate를 추가한다.
ICE 세대를 식별하려면
candidate.usernameFragment를
사용한다. usernameFragment가
null이면 가장 최근 ICE 세대에 대해
candidate를 처리한다.
candidate.candidate가
빈 문자열이면 candidate를 대응하는 미디어
설명과 ICE
후보 세대에 대한
후보 끝 표시로 처리한다.
candidate.sdpMid와
candidate.sdpMLineIndex가
모두 null이면 이 후보 끝 표시는 모든 미디어
설명에 적용된다.
candidate를 성공적으로 추가하지 못했다면 사용자 에이전트는 다음 단계를 실행하는 태스크를 반드시 대기열에 추가해야 한다:
connection.[[IsClosed]]가
true이면 이
단계들을 중단한다.
새로 생성된
OperationError로
p를 거부하고
이 단계들을 중단한다.
candidate가 성공적으로 적용되었거나 후보가 관리상 금지된 경우, 사용자 에이전트는 다음 단계를 실행하는 태스크를 반드시 대기열에 추가해야 한다:
connection.[[IsClosed]]가
true이면 이
단계들을 중단한다.
connection.[[PendingRemoteDescription]]이
null이 아니고
candidate가 처리된 ICE 세대를
나타내면, candidate를
connection.[[PendingRemoteDescription]].sdp에
추가한다.
connection.[[CurrentRemoteDescription]]이
null이 아니고
candidate가 처리된 ICE 세대를
나타내면, candidate를
connection.[[CurrentRemoteDescription]].sdp에
추가한다.
p를
undefined로
이행한다.
p를 반환한다.
UA가 이 주소에 대한 연결 시도를 허용하지 않기로 결정한 경우 후보는 관리상 금지된 것이다.
개인정보 보호를 위해 개발자에게 주소/포트의 차단 여부를 알리지 않는다. 해당 주소에서 응답이 전혀 없는 것과 정확히 같은 방식으로 동작한다.
UA는 [Fetch]의 잘못된 포트 차단 목록에 있는 주소로의 연결을 반드시 금지해야 하며, 다른 주소로의 연결도 금지하도록 선택할 수 있다.
RTCConfiguration의
iceTransportPolicy
멤버가 relay이면,
mDNS 후보나 DNS 후보처럼 외부 확인이 필요한 후보는
반드시 금지해야 한다.
WebIDL 처리로 인해
addIceCandidate(null)은
기본 사전이 존재하는 호출로 해석된다. 위 알고리즘에서 이는
모든 미디어 설명과 ICE 후보 세대에 대한 후보 끝을
나타낸다. 이는 레거시 사유로 의도된 동작이다.
restartIce
restartIce
메서드는 ICE를 다시 시작해야 한다고
RTCPeerConnection에
알린다. 이후
createOffer
호출은 [RFC5245]
9.1.1.1절에 설명된 대로 ICE를 다시 시작하는 설명을 생성한다.
이 메서드가 호출되면 사용자 에이전트는 다음 단계를 반드시 실행해야 한다:
connection을 메서드가 호출된 RTCPeerConnection으로
한다.
connection.[[LocalIceCredentialsToReplace]]를
비운 다음,
connection.[[CurrentLocalDescription]]에서
찾은 모든 ICE 자격 증명과
connection.[[PendingLocalDescription]]에서
찾은 모든 ICE 자격 증명([RFC5245]
15.4절에 정의된 ice-ufrag 및 ice-pwd)으로 채운다.
connection의 협상 필요 플래그를 갱신한다.
getConfiguration
이 RTCPeerConnection
객체의 현재 구성을 나타내는
RTCConfiguration 객체를
반환한다.
이 메서드가 호출되면 사용자 에이전트는
[[Configuration]] 내부
슬롯에 저장된
RTCConfiguration 객체를
반드시 반환해야 한다.
setConfiguration
setConfiguration
메서드는 이 RTCPeerConnection 객체의
구성을 갱신한다. 여기에는 ICE 에이전트의
구성 변경도 포함된다. [RFC9429]
(3.5.1절
)에 명시된 것처럼
ICE 구성이 새 수집 단계를 요구하는 방식으로 변경되면
ICE를 다시 시작해야 한다.
setConfiguration
메서드가 호출되면 사용자
에이전트는 다음 단계를 반드시 실행해야 한다:
connection을 메서드가 호출된 RTCPeerConnection으로
한다.
connection.[[IsClosed]]가
true이면 다음 예외를 던진다:
InvalidStateError.
configuration이 지정한 구성을 설정한다.
close
close 메서드가
호출되면 사용자 에이전트는
다음 단계를 반드시 실행해야 한다:
connection을 메서드가 호출된 RTCPeerConnection
객체로 한다.
false 값을 사용하여 연결을 닫는다.
connection과 불리언 disappear가 주어졌을 때 연결을 닫는 알고리즘은 다음과 같다:
connection.[[IsClosed]]가
true이면 이 단계들을 중단한다.
connection.[[IsClosed]]를
true로 설정한다.
connection.[[SignalingState]]을
"closed"로
설정한다. 이때는 어떤
이벤트도 발생하지 않는다.
transceivers를
CollectTransceivers
알고리즘을 실행한 결과로 한다.
transceivers의 모든
RTCRtpTransceiver
transceiver에 대해 다음 단계를 실행한다:
transceiver.[[Stopped]]가
true이면 이 하위 단계들을 중단한다.
transceiver와 disappear를 사용하여 RTCRtpTransceiver를 중지한다.
connection의 각 RTCDataChannel의
[[ReadyState]] 슬롯을
"closed"로
설정한다.
RTCDataChannel은
갑자기 닫히며 닫기
절차는 호출되지 않는다.
connection.[[SctpTransport]]가
null이 아니면 SCTP ABORT 청크를 전송하여 기반 SCTP
연결을 해제하고,
[[SctpTransportState]]을
"closed"로
설정한다.
connection의 각 RTCDtlsTransport의
[[DtlsTransportState]]
슬롯을
"closed"로
설정한다.
connection의 ICE 에이전트를 제거하여 활성 ICE 처리를 즉시 종료하고 관련 리소스 (예: TURN 권한)를 해제한다.
connection의 각 RTCIceTransport의
[[IceTransportState]]
슬롯을
"closed"로
설정한다.
connection.[[IceConnectionState]]을
"closed"로
설정한다. 이때는
어떤 이벤트도 발생하지 않는다.
connection.[[ConnectionState]]을
"closed"로
설정한다. 이때는
어떤 이벤트도 발생하지 않는다.
RTCPeerConnection.
오버로드된
함수는 부분 인터페이스에 정의할 수 없기 때문이다.
이 절의 메서드 지원 여부는 선택 사항이다. 그러나 이 메서드들을 지원하는 경우에는 여기에 명시된 내용에 따라 반드시 구현해야 한다.
addStream 메서드는
RTCPeerConnection에 존재했으며, 다음과 같이 쉽게
폴리필할 수
있다:
RTCPeerConnection.prototype.addStream = function(stream) {
stream.getTracks().forEach((track) => this.addTrack(track, stream));
};
createOffer
createOffer 메서드가
호출되면, 사용자 에이전트는 반드시 다음 단계를 실행해야 한다:
successCallback을 메서드의 첫 번째 인수로 한다.
failureCallback을 메서드의 두 번째 인수가 나타내는 콜백으로 한다.
options을 메서드의 세 번째 인수가 나타내는 콜백으로 한다.
RTCPeerConnection의
createOffer()
메서드에 지정된 단계를 실행한다. 인수는
options 하나뿐이며,
p를 그 결과로 생성된 프로미스로 한다.
이행되는 p의 값이 offer인 경우, successCallback을 offer를 인수로 하여 호출한다.
거부되는 p의 이유가 r인 경우, failureCallback을 r를 인수로 하여 호출한다.
프로미스를 반환한다. 이 프로미스는 해결되며 그 값은
undefined이다.
setLocalDescription
setLocalDescription 메서드가 호출되면,
사용자 에이전트는 반드시 다음 단계를 실행해야 한다:
description을 메서드의 첫 번째 인수로 한다.
successCallback을 메서드의 두 번째 인수가 나타내는 콜백으로 한다.
failureCallback을 메서드의 세 번째 인수가 나타내는 콜백으로 한다.
RTCPeerConnection의
setLocalDescription
메서드에 지정된 단계를 실행한다. 인수는
description 하나뿐이며,
p를 그 결과로 생성된 프로미스로 한다.
이행되는
p의 경우,
successCallback을
undefined를 인수로 하여 호출한다.
거부되는 p의 이유가 r인 경우, failureCallback을 r를 인수로 하여 호출한다.
프로미스를 반환한다. 이 프로미스는 해결되며 그 값은
undefined이다.
createAnswer
createAnswer
메서드가 호출되면, 사용자 에이전트는 반드시 다음 단계를 실행해야
한다:
successCallback을 메서드의 첫 번째 인수로 한다.
failureCallback을 메서드의 두 번째 인수가 나타내는 콜백으로 한다.
RTCPeerConnection의
createAnswer()
메서드에 지정된 단계를
실행한다. 인수는 없으며, p를 그 결과로 생성된
프로미스로 한다.
이행되는 p의 값이 answer인 경우, successCallback을 answer를 인수로 하여 호출한다.
거부되는 p의 이유가 r인 경우, failureCallback을 r를 인수로 하여 호출한다.
프로미스를 반환한다. 이 프로미스는 해결되며 그 값은
undefined이다.
setRemoteDescription
setRemoteDescription 메서드가 호출되면,
사용자 에이전트는 반드시 다음 단계를 실행해야 한다:
description을 메서드의 첫 번째 인수로 한다.
successCallback을 메서드의 두 번째 인수가 나타내는 콜백으로 한다.
failureCallback을 메서드의 세 번째 인수가 나타내는 콜백으로 한다.
RTCPeerConnection의
setRemoteDescription
메서드에 지정된 단계를
실행한다. 인수는 description 하나뿐이며,
p를 그 결과로 생성된 프로미스로 한다.
이행되는
p의 경우,
successCallback을
undefined를 인수로 하여 호출한다.
거부되는 p의 이유가 r인 경우, failureCallback을 r를 인수로 하여 호출한다.
프로미스를 반환한다. 이 프로미스는 해결되며 그 값은
undefined이다.
addIceCandidate
addIceCandidate
메서드가 호출되면, 사용자 에이전트는 반드시 다음 단계를 실행해야
한다:
candidate을 메서드의 첫 번째 인수로 한다.
successCallback을 메서드의 두 번째 인수가 나타내는 콜백으로 한다.
failureCallback을 메서드의 세 번째 인수가 나타내는 콜백으로 한다.
RTCPeerConnection의
addIceCandidate()
메서드에 지정된 단계를 실행한다. 인수는
candidate 하나뿐이며,
p를 그 결과로 생성된 프로미스로 한다.
이행되는
p의 경우,
successCallback을
undefined를 인수로 하여 호출한다.
거부되는 p의 이유가 r인 경우, failureCallback을 r를 인수로 하여 호출한다.
프로미스를 반환한다. 이 프로미스는 해결되며 그 값은
undefined이다.
이 콜백들은 레거시 API에서만 사용된다.
WebIDLcallback RTCPeerConnectionErrorCallback = undefined (DOMException error);
RTCPeerConnectionErrorCallback
매개변수
error의 형식은
DOMException
WebIDLcallback RTCSessionDescriptionCallback = undefined (RTCSessionDescriptionInit description);
RTCSessionDescriptionCallback
매개변수
RTCSessionDescriptionInit
이 절에서는 제안 생성 방식에 영향을 주는 데 사용할 수
있는 레거시 확장 집합을 설명한다. 이는 다음에 추가된
미디어와 함께 사용된다: RTCPeerConnection.
개발자는 RTCRtpTransceiver API를
대신 사용하는 것이 좋다.
createOffer가 이
절에
지정된 레거시 옵션 중 하나라도
포함하여 호출되면, 일반 createOffer
단계 대신 다음 단계를 실행한다:
options을 메서드의 첫 번째 인수로 한다.
connection을 현재
RTCPeerConnection 객체로 한다.
각 offerToReceive<Kind>
멤버에 대해, options에서 kind가 kind인
경우 다음 단계를 실행한다:
중지되지 않은 각
"sendrecv"
트랜시버
중 트랜시버
종류가 kind인 것에 대해,
transceiver.[[Direction]]을
"sendonly"로
설정한다.
중지되지 않은 각
"recvonly"
트랜시버
중 트랜시버
종류가 kind인 것에 대해,
transceiver.[[Direction]]을
"inactive"로
설정한다.
다음 옵션이 있는 경우 그 옵션으로 계속한다.
connection에 중지되지 않은
"sendrecv"
또는
"recvonly"
트랜시버가 있고, 그
트랜시버 종류가
kind이면, 다음 옵션이 있는
경우 그 옵션으로 계속한다.
transceiver를 다음 호출과 동등한 작업의
결과로 한다:
connection.addTransceiver(kind).
다만 이 작업에서는 다음을 해서는 안 된다: 협상
필요 플래그 갱신.
transceiver가 이전 작업에서 오류가 발생하여 설정되지 않았다면, 이 단계를 중단한다.
transceiver.[[Direction]]을
"recvonly"로
설정한다.
createOffer에 지정된
단계를 실행하여 제안을 생성한다.
WebIDLpartial dictionary RTCOfferOptions {
boolean offerToReceiveAudio;
boolean offerToReceiveVideo;
};
offerToReceiveAudio의 형식은 boolean
이 설정은 오디오 방향성을 추가로 제어한다. 예를 들어 오디오 전송 여부와 관계없이 오디오를 수신할 수 있도록 보장하는 데 사용할 수 있다.
offerToReceiveVideo의 형식은 boolean
이 설정은 비디오 방향성을 추가로 제어한다. 예를 들어 비디오 전송 여부와 관계없이 비디오를 수신할 수 있도록 보장하는 데 사용할 수 있다.
RTCPeerConnection 객체는 반드시 객체에서 이벤트 핸들러가
트리거되게 할 수 있는 이벤트가 하나라도 있는 동안 가비지
컬렉션되어서는 안 된다. 객체의 [[IsClosed]] 내부 슬롯이
true이면 이러한 이벤트 핸들러는 트리거될 수 없으므로
객체를 안전하게 가비지 컬렉션할 수 있다.
모든 RTCDataChannel 및 MediaStreamTrack 객체가 RTCPeerConnection에 연결되어 있으면,
해당
객체는 RTCPeerConnection 객체에 대한 강한 참조를 가진다.
프로미스를 반환하는 모든 메서드에는 프로미스의 표준 오류 처리 규칙이 적용된다. 프로미스를 반환하지 않는 메서드는 오류를 나타내기 위해 예외를 던질 수 있다.
RTCSdpType 열거형은
RTCSessionDescriptionInit, RTCLocalSessionDescriptionInit
또는 RTCSessionDescription 인스턴스의 유형을 설명한다.
WebIDLenum RTCSdpType {
"offer",
"pranswer",
"answer",
"rollback"
};
| 열거형 값 | 설명 |
|---|---|
offer
|
|
pranswer
|
|
answer
|
|
rollback
|
|
RTCSessionDescription 클래스는
RTCPeerConnection에서 로컬 및 원격
세션 기술을
노출하는 데 사용된다.
WebIDL[Exposed=Window]
interface RTCSessionDescription {
constructor(RTCSessionDescriptionInit descriptionInitDict);
readonly attribute RTCSdpType type;
readonly attribute DOMString sdp;
[Default] RTCSessionDescriptionInit toJSON();
};
constructor()
RTCSessionDescription()
생성자는 사전 인수
description을 받으며, 그 내용은
새로운 RTCSessionDescription
객체를 초기화하는 데
사용된다. 이 생성자는 더 이상 사용되지 않으며 레거시 호환성을
위해서만 존재한다.
type의 형식은 RTCSdpType이며 읽기 전용
sdp의 형식은 DOMString이며 읽기 전용이고 기본값은
""
toJSON()
WebIDLdictionary RTCSessionDescriptionInit {
required RTCSdpType type;
DOMString sdp = "";
};
type의 형식은 RTCSdpType이며 필수이다
sdp의 형식은 DOMString
type이 "rollback"이면
이 멤버는 사용되지 않는다.
WebIDLdictionary RTCLocalSessionDescriptionInit {
RTCSdpType type;
DOMString sdp = "";
};
type의 형식은 RTCSdpType
setLocalDescription은
다음을 기반으로
유형을 추론한다: RTCPeerConnection의
[[SignalingState]].
sdp의 형식은 DOMString
type이
"rollback"이면 이 멤버는
사용되지 않는다.
다음 객체의 상태에 대한 많은 변경은 RTCPeerConnection에서
원하는 효과를 내기 위해
신호 채널을 통해 원격 측과
통신해야 한다. 앱은
negotiationneeded 이벤트를 수신하여 신호 처리가
필요한
시점을 알 수 있다. 이 이벤트는 연결의 협상 필요 플래그의
상태에 따라 발생하며, 이 플래그는 [[NegotiationNeeded]] 내부 슬롯으로 표현된다.
이 절은 비규범적이다.
다음 객체인 RTCPeerConnection에서
신호 처리가 필요한 작업을 수행하면 연결에
협상이 필요하다고 표시된다. 이러한 작업의
예로는 RTCRtpTransceiver의 추가 또는 중지와 첫 번째 RTCDataChannel의 추가가 있다.
구현 내부의 변경으로 인해 연결에 협상이 필요하다고 표시될 수도 있다.
정확한 협상 필요 플래그 갱신 절차는 아래에 명시되어 있다.
이 절은 비규범적이다.
협상 필요 플래그는
유형이
"answer"인 세션 기술을 설정하는 데 성공하고 제공된 기술이 RTCRtpTransceiver들과
RTCDataChannel들의 상태와
일치하면 지워진다. 이 객체들은 현재
RTCPeerConnection에 존재한다.
구체적으로 이는
모든 비-stopped 트랜시버가 연결된 섹션을 로컬 기술에 가지고 있고 그 속성이
일치해야 하며, 데이터 채널을 하나라도 생성했다면 로컬
기술에 데이터 섹션이 있어야 한다는 뜻이다.
정확한 협상 필요 플래그 갱신 절차는 아래에 명시되어 있다.
아래 절차는 이 문서의 다른 곳에서 참조된 위치에서 수행된다. 협상에 영향을 주는 구현 내부 변경의 결과로 수행될 수도 있다. 이러한 변경이 발생하면 사용자 에이전트는 반드시 협상 필요 플래그를 갱신해야 한다.
협상 필요 플래그를 갱신하려면 connection에 대해 다음 단계를 실행한다:
만약 connection.[[Operations]]의 길이가 0이 아니면
connection.[[UpdateNegotiationNeededFlagOnEmptyChain]]을
true로 설정하고 이 단계를 중단한다.
다음 단계를 실행하는 태스크를 큐에 넣는다:
만약 connection.[[IsClosed]]이
true이면 이 단계를 중단한다.
만약
connection.[[Operations]]의 길이가
0이 아니면
connection.[[UpdateNegotiationNeededFlagOnEmptyChain]]을
true로 설정하고 이 단계를 중단한다.
만약 connection.[[SignalingState]]이
"stable"이 아니면
이 단계를 중단한다.
협상 필요
플래그는
상태가
"stable"로 전환되면
세션 기술을 설정하는
단계에서 갱신된다.
만약 협상이 필요한지 확인한
결과가 false이면,
협상 필요 플래그를 지운다:
connection.[[NegotiationNeeded]]을
false로 설정하고 이 단계를 중단한다.
만약 connection.[[NegotiationNeeded]]이
이미 true이면 이 단계를 중단한다.
connection.[[NegotiationNeeded]]을
true로 설정한다.
다음 이벤트를 발생시킨다: 이름은 negotiationneeded이고 대상은
connection.
태스크 큐잉은 negotiationneeded 이벤트가
너무 일찍 발생하는 것을 방지한다.
이는 흔히 connection을 여러 번 동시에 수정하는 상황에서
필요하다.
또한 협상 메서드와의 경쟁을
피하기 위해 negotiationneeded 이벤트는 작업 체인이 비어
있을 때만 발생시킨다.
협상이 필요한지 확인하려면 connection에 대해 다음 사항을 확인한다:
이 절의 시작 부분에서 설명한 구현별
협상이 필요하면 다음을 반환한다:
true.
만약
connection.[[LocalIceCredentialsToReplace]]이
비어 있지 않으면 다음을 반환한다: true.
description을 다음 값으로 한다:
connection.[[CurrentLocalDescription]].
만약 connection에서 하나 이상의 RTCDataChannel을
생성했고, description에서 데이터용 m= 섹션이 아직
협상되지 않았다면 다음을 반환한다: true.
각 transceiver에 대해, connection의 트랜시버 집합에서 다음 사항을 확인한다:
만약 transceiver.[[Stopping]]이
true이고
transceiver.[[Stopped]]이
false이면 다음을 반환한다: true.
만약 transceiver가 stopped 상태가 아니고 아직 연결된 m=
섹션이 description에 없으면 다음을 반환한다: true.
만약 transceiver가 stopped 상태가 아니고 연결된 m= 섹션이
description에 있으면 다음 사항을 확인한다:
만약 transceiver.[[Direction]]이
"sendrecv"
또는
"sendonly"이고
연결된 m=
섹션이 description에서 a=msid 줄을
하나도 포함하지
않거나, a=msid 줄에서 가져온 MSID 수 또는 이
m= 섹션의
MSID 값 자체가
transceiver.sender.[[AssociatedMediaStreamIds]]의
값과 다르면 다음을 반환한다: true.
만약 description의 유형이
"offer"이고 연결된 m=
섹션의 방향이
connection.[[CurrentLocalDescription]]와
connection.[[CurrentRemoteDescription]]
어느 쪽에서도 transceiver.[[Direction]]과
일치하지 않으면 다음을 반환한다: true. 이 단계에서
방향을 다음에 있는 방향과 비교할 때:
[[CurrentRemoteDescription]]에
있는 기술의
방향은 피어의 관점을 나타내도록 반대로
바꿔야 한다.
만약 description의 유형이
"answer"이고 연결된 m=
섹션이 description에 있으며 그 방향이
transceiver.[[Direction]]과 제안된 방향의
교집합과 일치하지 않으면(다음에 설명됨:
[RFC9429]
(5.3.1절)),
다음을 반환한다: true.
만약 transceiver가 stopped
상태이고 연결된 m=
섹션이
있지만, 해당 m= 섹션이 아직
connection.[[CurrentLocalDescription]]
또는
connection.[[CurrentRemoteDescription]]에서
거부되지 않았다면 다음을 반환한다: true.
앞선 모든 확인을 수행했는데
true가 반환되지 않았다면 협상할 항목이 남아 있지
않으므로 다음을 반환한다: false.
이 인터페이스는 [RFC5245]
2절에서 설명하는 ICE 후보를 나타낸다.
candidate,
sdpMid,
sdpMLineIndex 및
usernameFragment를 제외한
나머지 속성은 candidateInitDict의
candidate
멤버의 형식이 올바른 경우 이를 파싱하여 파생된다.
[Exposed=Window]
interface RTCIceCandidate {
constructor(optional RTCIceCandidateInit candidateInitDict = {});
readonly attribute DOMString candidate;
readonly attribute DOMString? sdpMid;
readonly attribute unsigned short? sdpMLineIndex;
readonly attribute DOMString? foundation;
readonly attribute RTCIceComponent? component;
readonly attribute unsigned long? priority;
readonly attribute DOMString? address;
readonly attribute RTCIceProtocol? protocol;
readonly attribute unsigned short? port;
readonly attribute RTCIceCandidateType? type;
readonly attribute RTCIceTcpCandidateType? tcpType;
readonly attribute DOMString? relatedAddress;
readonly attribute unsigned short? relatedPort;
readonly attribute DOMString? usernameFragment;
readonly attribute RTCIceServerTransportProtocol? relayProtocol;
readonly attribute DOMString? url;
RTCIceCandidateInit toJSON();
};
constructor()
RTCIceCandidate()
생성자는 사전 인수 candidateInitDict를 받으며,
그 내용은 새
RTCIceCandidate 객체를
초기화하는 데 사용된다.
호출되면 다음 단계를 실행한다.
sdpMid 및
sdpMLineIndex
멤버가 모두 null이면
다음 예외를 던진다:
TypeError.
candidateInitDict로 RTCIceCandidate를 생성한 결과를 반환한다.
candidateInitDict 사전으로 RTCIceCandidate를 생성하려면 다음 단계를 실행한다.
RTCIceCandidate 객체로 한다.
null로 초기화된 내부 슬롯을 생성한다.
foundation,
component,
priority,
address,
protocol,
port,
type,
tcpType,
relatedAddress
및 relatedPort.
candidate,
sdpMid,
sdpMLineIndex,
usernameFragment.
candidate
사전 멤버로 한다. candidate가 빈 문자열이 아니면 다음 단계를 실행한다.
candidate-attribute
문법을 사용하여 파싱한다.
candidate-attribute
파싱에 실패하면 이 단계들을 중단한다.
RTCIceCandidate
생성자는 candidateInitDict의 사전 멤버에 대해
기본적인 파싱과 형식 검사만 수행한다.
candidate,
sdpMid,
sdpMLineIndex,
usernameFragment의
형식 적합성 및 대응하는 세션 기술과의 일치 여부에 대한 상세 검증은
RTCIceCandidate
객체를
addIceCandidate()에
전달할 때 수행된다.
하위 호환성을 유지하기 위해 candidate 속성을 파싱할 때
발생하는 모든 오류는 무시된다. 이 경우
candidate
속성은 candidateInitDict에 제공된 원시
candidate
문자열을 보유하지만,
foundation,
priority
등의 파생 속성은 null로 설정된다.
아래 속성 대부분은 [RFC5245] 15.1절에 정의되어 있다.
candidate의 형식은 DOMString이며 읽기 전용이다.
candidate-attribute를
담는다. 이
RTCIceCandidate가
후보 종료 표시 또는 피어 반사형 원격 후보를 나타내면
candidate는
빈 문자열이다.
sdpMid의 형식은 DOMString이며 읽기 전용이고 null을 허용한다.
null이 아니면 이 후보가 연결된 미디어 구성요소에 대해
[RFC5888]에
정의된 미디어 스트림
“식별 태그”를 포함한다.
sdpMLineIndex의 형식은
unsigned short이며 읽기 전용이고 null을 허용한다.
null이 아니면 SDP에서 이 후보가 연결된
미디어 설명의
인덱스(0부터 시작)를 나타낸다.
foundation의 형식은 DOMString이며 읽기 전용이고 null을 허용한다.
RTCIceTransport에 나타나는
후보를 ICE가 서로 연관 지을 수 있게 하는 고유 식별자이다.
component의 형식은 RTCIceComponent이며
읽기 전용이고 null을 허용한다.
rtp” 또는 “rtcp”)이다.
이는 candidate-attribute의
component-id 필드에 대응하며,
RTCIceComponent에
정의된 문자열 표현으로 디코딩된다.
priority의 형식은 unsigned long이며 읽기 전용이고 null을 허용한다.
address의 형식은 DOMString이며 읽기 전용이고 null을 허용한다.
IPv4 주소, IPv6 주소 및 정규화된 도메인 이름(FQDN)을 허용하는 후보의 주소이다.
이는 candidate-attribute의
connection-address 필드에 대응한다.
예를 들어
[[SelectedCandidatePair]].remote를 통해
원격 후보가 노출될 수 있다. 기본적으로 사용자 에이전트는 노출되는 모든 원격 후보의
address
속성을 null로 반드시 유지해야 한다.
웹 애플리케이션이
addIceCandidate를
사용하여
RTCPeerConnection
인스턴스에 주소를 알려 주면 사용자 에이전트는 새로 알게 된 해당 주소를 가진
원격 후보를 나타내는 그
RTCPeerConnection
인스턴스의 모든
RTCIceCandidate에서
address
속성 값을 노출할 수 있다.
ICE를 통해 수집되어
RTCIceCandidate
인스턴스에서 애플리케이션에 표시되는 후보의 주소는 WebRTC를 지원하지 않는
브라우저에서 사용자가 예상했을 수 있는 것보다 기기와 사용자에 관한 더 많은
정보(예: 위치, 로컬 네트워크 토폴로지)를 드러낼 수 있다.
이 주소는 항상 애플리케이션에 노출되고 잠재적으로 통신 상대방에게도 노출되며, 특정한 사용자 동의 없이도 노출될 수 있다 (예: 데이터 채널과 함께 사용하는 피어 연결 또는 미디어 수신 전용 연결).
또한 이 주소는 일시적 또는 영구적인 교차 출처 상태로 사용될 수 있으므로
기기의 지문 식별 표면을 넓힌다.
애플리케이션은
RTCConfiguration의
iceTransportPolicy
멤버를 통해
ICE 에이전트가
릴레이 후보만 보고하도록 강제함으로써 일시적 또는 영구적으로 통신 상대방에게
주소가 노출되지 않게 할 수 있다.
애플리케이션 자체에 노출되는 주소를 제한하기 위해 브라우저는 [RFC8828]에 정의된 대로 로컬 주소 공유에 관한 다양한 정책을 사용자에게 제공할 수 있다.
protocol의 형식은 RTCIceProtocol이며
읽기 전용이고 null을 허용한다.
udp”/“tcp”)이다.
이는 candidate-attribute의
transport 필드에 대응한다.
port의 형식은 unsigned short이며 읽기 전용이고 null을 허용한다.
type의 형식은 RTCIceCandidateType이며
읽기 전용이고 null을 허용한다.
candidate-attribute의
candidate-types 필드에 대응한다.
tcpType의 형식은 RTCIceTcpCandidateType이며
읽기 전용이고 null을 허용한다.
protocol이
“tcp”이면
tcpType은
TCP 후보의 유형을 나타낸다. 그렇지 않으면
tcpType은
null이다. 이는
candidate-attribute의
tcp-type 필드에 대응한다.
relatedAddress의 형식은
DOMString이며 읽기 전용이고 null을 허용한다.
relatedAddress는
그 후보가 파생된 원본 후보의 IP 주소이다. 호스트 후보의 경우
relatedAddress는
null이다. 이는
candidate-attribute의
rel-address 필드에 대응한다.
relatedPort의 형식은 unsigned short이며 읽기 전용이고 null을 허용한다.
relatedPort는
그 후보가 파생된 원본 후보의 포트이다. 호스트 후보의 경우
relatedPort는
null이다. 이는
candidate-attribute의
rel-port 필드에 대응한다.
usernameFragment의 형식은 DOMString이며 읽기 전용이고 null을 허용한다.
ufrag를 담는다.
relayProtocol의 형식은 RTCIceServerTransportProtocol이며 읽기 전용이고
null을 허용한다.
relay”인
로컬 후보의 경우, 이는 엔드포인트가 TURN 서버와 통신하는 데 사용하는
프로토콜이다. 그 밖의 모든 후보에서는 null이다.
toJSON()
RTCIceCandidate 인터페이스의
toJSON()
연산을 호출하려면 다음 단계를 실행한다.
RTCIceCandidateInit
사전으로 한다.
candidate,
sdpMid,
sdpMLineIndex,
usernameFragment»의
각 속성 식별자 attr에 대해 다음 단계를 실행한다.
RTCIceCandidate
객체가 주어졌을 때 attr로 식별되는 속성의 기저 값을
가져온 결과를 value로 한다.
json[attr]을
value로 설정한다.
WebIDLdictionary RTCIceCandidateInit {
DOMString candidate = "";
DOMString? sdpMid = null;
unsigned short? sdpMLineIndex = null;
DOMString? usernameFragment = null;
};
candidate의 형식은 DOMString이며 기본값은 ""이다.
candidate-attribute를
담는다. 이것이 후보 종료 표시를 나타내면
candidate는
빈 문자열이다.
sdpMid의 형식은 DOMString이며 null을 허용하고 기본값은
null이다.
null이 아니면 이 후보가 연결된 미디어 구성요소에 대해
[RFC5888]에
정의된
미디어 스트림
“식별 태그”를 포함한다.
sdpMLineIndex의 형식은 unsigned short이며 null을 허용하고 기본값은
null이다.
null이 아니면 SDP에서 이 후보가 연결된
미디어 설명의
인덱스(0부터 시작)를 나타낸다.
usernameFragment의 형식은 DOMString이며 null을 허용하고 기본값은
null이다.
null이 아니면
[RFC5245]
15.4절에 정의된 ufrag를 담는다.
candidate-attribute 문법은
RTCIceCandidate()
생성자에서 candidateInitDict의
candidate 멤버를
파싱하는 데 사용된다.
candidate-attribute의
기본 문법은 [RFC5245]
15.1절에 정의되어 있다. 또한 브라우저는
[RFC6544]
4.5절에 정의된 ICE TCP 문법 확장을 반드시 지원해야 한다.
브라우저는 다른 RFC에 정의된
candidate-attribute의
기타 문법 확장을 지원할 수 있다.
RTCIceProtocol은
ICE 후보의 프로토콜을 나타낸다.
WebIDLenum RTCIceProtocol {
"udp",
"tcp"
};
| 열거형 값 | 설명 |
|---|---|
udp
|
[RFC5245]에 설명된 UDP 후보이다. |
tcp
|
[RFC6544]에 설명된 TCP 후보이다. |
RTCIceTcpCandidateType은
[RFC6544]에 정의된
ICE TCP 후보의 유형을 나타낸다.
WebIDLenum RTCIceTcpCandidateType {
"active",
"passive",
"so"
};
| 열거형 값 | 설명 |
|---|---|
active
|
“active”
TCP 후보는 전송 계층이 발신 연결을 열려고 시도하지만 들어오는 연결 요청은
받지 않는 후보이다.
|
passive
|
“passive”
TCP 후보는 전송 계층이 들어오는 연결 시도는 받지만 연결을 시도하지 않는
후보이다.
|
so
|
“so” 후보는
전송 계층이 피어와 동시에 연결을 열려고 시도하는 후보이다.
|
사용자 에이전트는 일반적으로
active
ICE TCP 후보만 수집한다.
RTCIceCandidateType은
[RFC5245]
15.1절에 정의된 ICE 후보의 유형을 나타낸다.
RTCIceServerTransportProtocol은
[RFC8656]
3.1절에 정의된 클라이언트와 서버 사이에서 사용되는 전송 프로토콜의 유형을 나타낸다.
WebIDLenum RTCIceServerTransportProtocol {
"udp",
"tcp",
"tls",
};
| 열거형 값 | 설명 |
|---|---|
udp
|
TURN 클라이언트가 서버로의 전송에 UDP를 사용한다. |
tcp
|
TURN 클라이언트가 서버로의 전송에 TCP를 사용한다. |
tls
|
TURN 클라이언트가 서버로의 전송에 TLS를 사용한다. |
icecandidate 이벤트는
RTCPeerConnection에서 발생하며
RTCPeerConnectionIceEvent
인터페이스를 사용한다.
RTCPeerConnectionIceEvent 이벤트가
RTCIceCandidate 객체를
포함하는 상태로 발생할 때는 반드시
sdpMid 및
sdpMLineIndex 값을 모두 포함해야 한다.
RTCIceCandidate의 유형이
“srflx” 또는
“relay”이면 이벤트의
url 속성은
반드시 후보를 얻은 ICE 서버의 URL로 설정되어야 한다.
icecandidate 이벤트는
서로 다른 세 가지 유형의 표시를 위해 사용된다.
후보가 수집되었다. 이벤트의
candidate
멤버는 정상적으로 채워진다. 이 후보는 원격 피어에 시그널링하고
addIceCandidate에
전달해야 한다.
RTCIceTransport가 후보의 한
세대에 대한 수집을 마쳤으며,
[RFC8838]
8.2절에 정의된 후보 종료 표시를 제공한다. 이는
candidate.candidate를
빈 문자열로 설정하여 나타낸다.
candidate
객체는 원격 피어에 후보 종료 표시를 제공하기 위해 일반적인 ICE 후보와 마찬가지로
원격 피어에 시그널링하고
addIceCandidate에
전달해야 한다.
모든 RTCIceTransport가
후보 수집을 마쳤으며
RTCPeerConnection의
RTCIceGatheringState가
“complete”로
전환되었다. 이는 이벤트의
candidate
멤버를 null로 설정하여 나타낸다. 이는 하위 호환성만을 위해
존재하며 이 이벤트를 원격 피어에 시그널링할 필요는 없다. 이는
icegatheringstatechange
이벤트의 상태가
“complete”인 것과
동일하다.
WebIDL[Exposed=Window]
interface RTCPeerConnectionIceEvent : Event {
constructor(DOMString type, optional RTCPeerConnectionIceEventInit eventInitDict = {});
readonly attribute RTCIceCandidate? candidate;
readonly attribute DOMString? url;
};
RTCPeerConnectionIceEvent.constructor()
candidate의 형식은 RTCIceCandidate이며
읽기 전용이고 null을 허용한다.
candidate
속성은 이벤트를 발생시킨 새 ICE 후보를 담은
RTCIceCandidate
객체이다.
후보 수집 종료를 나타내기 위해 이벤트가 생성되면 이 속성은
null로 설정된다.
미디어 구성요소가 여러 개여도 null 후보를 포함하는
이벤트는 하나만 발생한다.
url의 형식은 DOMString이며 읽기 전용이고 null을 허용한다.
url 속성은
이 후보를 수집하는 데 사용된 STUN 또는 TURN 서버를 식별하는
STUN 또는 TURN URL이다. 후보가 STUN 또는 TURN 서버에서 수집되지 않았으면
이 매개변수는 null로 설정된다.
이 속성은 사용이 중단되었으며, 이전 버전과의 호환성을 위해서만 존재한다.
후보의 url을 사용하는 것이 좋다.
WebIDLdictionary RTCPeerConnectionIceEventInit : EventInit {
RTCIceCandidate? candidate;
DOMString? url;
};
candidate의 형식은 RTCIceCandidate이며
null을 허용한다.
candidate
속성에 대해서는
RTCPeerConnectionIceEvent
인터페이스의 해당 설명을 참조한다.
url의 형식은 DOMString이며 null을 허용한다.
url 속성은
이 후보를 수집하는 데 사용된 STUN 또는 TURN 서버를 식별하는
STUN 또는 TURN URL이다.
icecandidateerror 이벤트는
RTCPeerConnection에서 발생하며
RTCPeerConnectionIceErrorEvent
인터페이스를 사용한다.
WebIDL[Exposed=Window]
interface RTCPeerConnectionIceErrorEvent : Event {
constructor(DOMString type, RTCPeerConnectionIceErrorEventInit eventInitDict);
readonly attribute DOMString? address;
readonly attribute unsigned short? port;
readonly attribute DOMString url;
readonly attribute unsigned short errorCode;
readonly attribute USVString errorText;
};
RTCPeerConnectionIceErrorEvent.constructor()
address의 형식은 DOMString이며 읽기 전용이고 null을 허용한다.
address
속성은 STUN 또는 TURN 서버와 통신하는 데 사용된 로컬 IP 주소이다.
다중 홈 시스템에서는 서버에 연결하기 위해 여러 인터페이스가 사용될 수 있으며, 이 속성을 통해 애플리케이션은 어느 인터페이스에서 실패가 발생했는지 알아낼 수 있다.
로컬 IP 주소 값이 로컬 후보의 일부로 이미 노출되어 있지 않으면
address
속성은 null로 설정된다.
port의 형식은 unsigned short이며 읽기 전용이고 null을 허용한다.
port
속성은 STUN 또는 TURN 서버와 통신하는 데 사용된 포트이다.
url의 형식은 DOMString이며 읽기 전용이다.
url
속성은 실패가 발생한 STUN 또는 TURN 서버를 식별하는 STUN 또는 TURN URL이다.
errorCode의 형식은 unsigned short이며 읽기 전용이다.
errorCode
속성은 STUN 또는 TURN 서버가 반환한 숫자형 STUN 오류 코드이다
[STUN-PARAMETERS].
서버에 도달할 수 있는 호스트 후보가 없으면
errorCode는
STUN 오류 코드 범위를 벗어난 값 701로 설정된다. 이 오류는
RTCIceGatheringState가
“gathering”인
동안 각 서버 URL에 대해 한 번만 발생한다.
errorText의 형식은 USVString이며 읽기 전용이다.
errorText
속성은 STUN 또는 TURN 서버가 반환한 STUN 사유 텍스트이다
[STUN-PARAMETERS].
서버에 도달할 수 없으면
errorText는
오류의 상세 정보를 제공하는 구현별 값으로 설정된다.
WebIDLdictionary RTCPeerConnectionIceErrorEventInit : EventInit {
DOMString? address;
unsigned short? port;
DOMString url;
required unsigned short errorCode;
USVString errorText;
};
address의 형식은 DOMString이며 null을 허용한다.
STUN 또는 TURN 서버와 통신하는 데 사용된 로컬 주소이거나
null이다.
port의 형식은 unsigned short이며 null을 허용한다.
STUN 또는 TURN 서버와 통신하는 데 사용된 로컬 포트이거나
null이다.
url의 형식은 DOMString이다.
실패가 발생한 STUN 또는 TURN 서버를 식별하는 STUN 또는 TURN URL이다.
errorCode의 형식은 unsigned short이며 필수이다.
STUN 또는 TURN 서버가 반환한 숫자형 STUN 오류 코드이다.
errorText의 형식은 USVString이다.
STUN 또는 TURN 서버가 반환한 STUN 사유 텍스트이다.
RTCPeerConnection 인스턴스가
피어와 인증하는 데 사용하는 인증서는
RTCCertificate 인터페이스를 사용한다.
애플리케이션은
generateCertificate
메서드를 사용하여 이 객체를 명시적으로 생성할 수 있으며,
RTCConfiguration에 제공하여 새
RTCPeerConnection
인스턴스를 생성할 수 있다.
여기에 제공된 명시적 인증서 관리 기능은 선택 사항이다. 애플리케이션이
certificates 구성 옵션을
제공하지 않고
RTCPeerConnection을 생성하면,
새 인증서 세트는 반드시
사용자
에이전트가 생성해야 한다.
이 세트에는 P-256 곡선의 개인 키와 SHA-256 해시를 사용하는 서명이 포함된
ECDSA 인증서가 반드시 포함되어야 한다.
WebIDLpartial interface RTCPeerConnection {
static Promise<RTCCertificate>
generateCertificate(AlgorithmIdentifier keygenAlgorithm);
};
generateCertificate, 정적
generateCertificate
함수는
사용자 에이전트가
X.509 인증서 [X509V3]와
이에 대응하는 개인 키를 생성하게 한다. 이 정보에 대한 핸들은
RTCCertificate 인터페이스의
형태로 제공된다. 반환된
RTCCertificate를 사용하면
RTCPeerConnection이
설정한 DTLS 세션에서 제시할 인증서를 제어할 수 있다.
keygenAlgorithm 인수는 인증서와 연결된 개인 키가 생성되는 방식을 제어하는 데 사용된다. keygenAlgorithm 인수는 WebCrypto [WebCryptoAPI]의 AlgorithmIdentifier 형식을 사용한다.
다음 값은 반드시
사용자 에이전트에서 지원되어야 한다:
{ name: "RSASSA-PKCS1-v1_5",
modulusLength: 2048, publicExponent: new Uint8Array([1, 0,
1]), hash: "SHA-256" } 및 { name:
"ECDSA", namedCurve:
"P-256"
}.
사용자 에이전트가 허용하는 값의 집합은 작거나 고정되어 있을 것으로 예상된다.
이 과정에서 생성되는 인증서에는 서명도 포함된다. 이 서명의 유효성은
호환성을 위해서만 중요하다. 공개 키와 그 결과로 생성된 인증서 지문만
RTCPeerConnection에서
사용되지만, 인증서의 형식이 올바르면 그 인증서가 허용될 가능성이 더 높다.
브라우저는 인증서 서명에 사용할 알고리즘을 선택한다. 해시 알고리즘이 필요한 경우
브라우저는 다음 알고리즘을 선택하는 것이 좋다:
SHA-256 [FIPS-180-4].
결과 인증서에는 다음과 연계할 수 있는 정보를 포함해서는 안 된다: 사용자 또는 사용자 에이전트. 식별 이름과 일련번호에는 무작위 값을 사용하는 것이 좋다.
메서드가 호출되면 사용자 에이전트는 반드시 다음 단계를 실행해야 한다.
keygenAlgorithm을
generateCertificate의
첫 번째 인수로 한다.
expires를 2592000000(30*24*60*60*1000)으로 한다.
이는 기본적으로
generateCertificate
호출 시점부터 30일 후에 인증서가 만료됨을 의미한다.
keygenAlgorithm이 객체이면 다음 단계를 실행한다.
certificateExpiration을
keygenAlgorithm이 나타내는 ECMAScript 객체를
변환하여
RTCCertificateExpiration
사전으로 만든 결과로 한다.
변환이 error와 함께 실패하면 error로 거부된 프로미스를 반환한다.
certificateExpiration.expires가
undefined가 아니면 expires를
certificateExpiration.expires로
설정한다.
expires가 31536000000보다 크면 expires를 31536000000으로 설정한다.
이는 인증서의 유효 기간이
generateCertificate
호출 시점부터 365일을 초과할 수 없음을 의미한다.
사용자 에이전트는 expires 값의 상한을 더 낮게 설정할 수 있다.
normalizedKeygenAlgorithm을 연산 이름
generateKey와
supportedAlgorithms
값 중
RTCPeerConnection용
인증서 생성에 특정된 값을 사용하여
알고리즘을
정규화한 결과로 한다.
위의 정규화 단계가 error와 함께 실패하면 error로 거부된 프로미스를 반환한다.
normalizedKeygenAlgorithm 매개변수가
사용자 에이전트가
RTCPeerConnection용
인증서를 생성하는 데 사용할 수 없거나 사용하지 않을 알고리즘을 식별하면,
거부된 프로미스를 반환한다.
거부 사유는
DOMException이며 그 유형은
NotSupportedError이다.
특히 normalizedKeygenAlgorithm은 DTLS 연결 인증에 사용되는
서명을 생성할 수 있는 비대칭 알고리즘이어야
한다.
p를 새 프로미스로 한다.
다음 단계를 병렬로 실행한다.
keygenAlgorithm을 사용하여 normalizedKeygenAlgorithm이 지정한 키 생성 연산을 수행한다.
generatedKeyingMaterial 및 generatedKeyCertificate를 위 단계에서 생성한 개인 키 자료와 인증서로 한다.
certificate를 새
RTCCertificate
객체로 한다.
certificate.[[Expires]]를 현재 시각에 expires 값을 더한 값으로 설정한다.
certificate.[[Origin]]을
관련 설정 객체의
출처로 설정한다.
generatedKeyingMaterial을 보안 모듈에 저장하고, handle을 이를 참조하는 식별자로 한다.
certificate.[[KeyingMaterialHandle]]을
handle로 설정한다.
certificate.[[Certificate]]을
generatedCertificate로 설정한다.
현재 영역의 전역 객체가 global로 주어졌을 때, p를 certificate로 이행하기 위해 네트워킹 작업 소스에 전역 작업을 대기열에 추가한다.
p를 반환한다.
RTCCertificateExpiration은
generateCertificate로
생성한 인증서의 만료일을 설정하는 데 사용된다.
WebIDLdictionary RTCCertificateExpiration {
[EnforceRange] unsigned long long expires;
};
expires, 형식은 unsigned long long이다.
선택적인
expires 속성을
추가할 수 있다. 추가 대상은
generateCertificate에
전달되는 알고리즘의 정의이다. 이 매개변수가 있으면 인증서가 생성된 시점부터 측정하여
RTCCertificate이 유효한
최대 시간을 밀리초 단위로 나타낸다.
RTCCertificate 인터페이스는
WebRTC 통신을 인증하는 데 사용되는 인증서를 나타낸다. 표시되는 속성 외에도 내부 슬롯에는
생성된 개인 키 자료에 대한 핸들
([[KeyingMaterialHandle]]), 인증서
([[Certificate]])가 포함된다. 이 인증서는
RTCPeerConnection이
피어와 인증할 때 사용한다. 또한 내부 슬롯에는 이 객체를 생성한 출처
([[Origin]])도 포함된다.
WebIDL[Exposed=Window, Serializable]
interface RTCCertificate {
readonly attribute EpochTimeStamp expires;
sequence<RTCDtlsFingerprint> getFingerprints();
};
expires의 형식은
EpochTimeStamp이며 읽기 전용이다.
expires 속성은 1970-01-01T00:00:00Z를 기준으로 한
밀리초 단위의 날짜와 시간을 나타내며, 이 시간이 지나면 브라우저는 인증서를
유효하지 않은 것으로 간주한다. 이 시간이 지난 후 해당 인증서를 사용하여
RTCPeerConnection을
생성하려는 시도는 실패한다.
이 값은 인증서 자체의 notAfter 매개변수에
반영되지 않을 수도 있다.
getFingerprints
인증서 지문 목록을 반환한다. 이 가운데 하나는 인증서 서명에 사용된 다이제스트 알고리즘으로 계산된다.
이 API에서는
[[Certificate]] 슬롯이
비구조화 이진 데이터를 포함한다. 애플리케이션이
[[KeyingMaterialHandle]]
내부 슬롯이나 이 슬롯이 참조하는 키 자료에 접근할 수 있는 방법은 제공되지 않는다.
구현은 RTCCertificate 객체를
영구 저장소에 저장하고 다시 가져오는 기능을 애플리케이션에
반드시 지원해야 한다. 이 과정에서는
[[KeyingMaterialHandle]]이
참조하는 키 자료도 보존되어야 한다. 구현은 민감한 키 자료를 동일 프로세스 메모리 공격으로부터
안전한 보안 모듈에 저장하는 것이 좋다. 그러면 개인 키를 저장하고
사용할 수 있으면서도 메모리 공격으로 쉽게 읽을 수 없게 된다.
RTCCertificate 객체는
직렬화
가능한 객체이다
[HTML].
value와
serialized가 주어졌을 때 이 객체의
직렬화 단계는 다음과 같다.
expires 속성의 값으로 설정한다.
[[Certificate]]에 있는
비구조화 이진 데이터의 복사본으로 설정한다.
[[Origin]]에 있는
비구조화 이진 데이터의 복사본으로 설정한다.
[[KeyingMaterialHandle]]에 있는
핸들을 직렬화한 값으로 설정한다. 개인 키 자료 자체를 직렬화하는 것은 아니다.
serialized와 value가 주어졌을 때 이 객체의 역직렬화 단계는 다음과 같다.
expires
속성이 serialized.[[Expires]]를 포함하도록 초기화한다.
[[Certificate]]을
serialized.[[Certificate]]의 복사본으로 설정한다.
[[Origin]]을
serialized.[[Origin]]의 복사본으로 설정한다.
[[KeyingMaterialHandle]]을
serialized.[[KeyingMaterialHandle]]을 역직렬화하여 얻은
개인 키 자료 핸들로 설정한다.
이 방식으로 구조화된 복제를 지원하면
RTCCertificate 인스턴스를
저장소에 영구 저장할 수 있다. 또한
postMessage(message, options)
[html] 같은 API를 사용하여 인스턴스를 다른 출처로
전달할 수도 있다. 그러나 이 객체는 원래 객체를 생성한 출처 이외의 다른 출처에서는
사용할 수 없다.
RTP 미디어 API를
사용하면 웹 애플리케이션이 피어 간 연결을 통해
MediaStreamTrack을
송수신할 수 있다. 트랙을
RTCPeerConnection에 추가하면 시그널링이
발생하며, 이
시그널링이 원격 피어로 전달되면 원격 측에 대응하는 트랙이
생성된다.
한
RTCPeerConnection에서 전송되고
다른 쪽에서 수신되는 트랙 사이에는 정확한 1:1 대응 관계가 없다. 우선 전송된 트랙의 ID는
수신된 트랙의 ID와 매핑되지 않는다. 또한
replaceTrack은
RTCRtpSender가 전송하는 트랙을
수신 측에 새 트랙을 생성하지 않고 변경한다. 이에 대응하는
RTCRtpReceiver에는 하나의 트랙만 있으며,
이 트랙은 서로 이어 붙인 여러 미디어 소스를 나타낼 수도 있다.
addTransceiver와
replaceTrack을 사용하면 동일한 트랙을
여러 번 전송할 수 있으며, 수신 측에서는 이를 각각 별도의 트랙을 보유한
여러 수신기로 관찰하게 된다. 따라서 한쪽의 RTCRtpSender와
다른 쪽의 RTCRtpReceiver 트랙 사이에 1:1 관계가
있다고 보는 것이
더 정확하다. 필요한 경우 송신기와 수신기는 RTCRtpTransceiver의
mid를 사용하여 대응시킬 수 있다.
미디어를 전송할 때 송신기는 SDP로 협상된 범위, 인코더의 정렬 제한, CPU 과부하 감지 또는 대역폭 추정 등의 여러 요구 사항을 충족하기 위해 미디어의 크기나 샘플링을 조정해야 할 수 있다.
[RFC9429]의 규칙(3.6절)에 따라 비디오는 축소할 수 있다. 입력 소스에 존재하지 않았던 가짜 데이터를 만들기 위해 미디어를 확대해서는 안 되며, 픽셀 수 제한을 충족하는 데 필요한 경우를 제외하고 미디어를 잘라내서는 안 되고, 종횡비를 변경해서는 안 된다.
WebRTC 워킹 그룹은 이 상황을 더 복잡하게 처리할 필요성과 그 일정에 관한 구현 피드백을 구하고 있다. 가능한 몇 가지 설계는 GitHub 이슈 1283에서 논의되었다.
scaleResolutionDownBy의
결과로
비디오 크기가 조정될 때 결과 너비 또는 높이가 정수가 아닌 상황이
발생할 수 있다. 사용자 에이전트는 전송해서는 안 된다. 단,
정수 부분을 기준으로
scaleResolutionDownBy로
조정된
너비와 높이보다 큰 비디오는 인코더의 최소 해상도를 준수하기 위한 경우를 제외하고 전송해서는 안 된다.
조정된 너비 또는 높이의 정수 부분이 0일 때 무엇을 전송할지는
구현에서 정의된다.
MediaStreamTrack의
실제 인코딩 및 전송은
RTCRtpSender라는 객체를 통해
관리된다. 마찬가지로
MediaStreamTrack의
수신 및 디코딩은
RTCRtpReceiver라는 객체를 통해
관리된다. 각 RTCRtpSender에는
최대 하나의 트랙이 연결되며, 수신할 각 트랙에는 정확히 하나의
RTCRtpReceiver가 연결된다.
각 MediaStreamTrack의 인코딩 및 전송은
해당 특성(비디오 트랙의 width,
height 및 frameRate,
오디오 트랙의 sampleSize, sampleRate 및
channelCount)이 원격 측에서 생성되는 트랙에도
합리적인 수준으로 유지되도록 구성하는 것이 좋다.
이 원칙이 적용되지 않는 상황도 있다. 예를 들어 어느 한 엔드포인트나 네트워크에
리소스 제약이 있거나
RTCRtpSender에
구현이 다르게 동작하도록 지시하는 설정이 적용될 수 있다.
RTCPeerConnection 객체에는
일부 상태를 공유하는 쌍으로 구성된 송신기와 수신기를 나타내는 다음 객체의 집합이 있다:
RTCRtpTransceiver.
이 집합은
RTCPeerConnection 객체가
생성될 때 빈 집합으로 초기화된다. RTCRtpSender와 RTCRtpReceiver는 항상
RTCRtpTransceiver와 동시에 생성되며,
수명 내내
해당 객체에 연결된 상태로 유지된다. RTCRtpTransceiver는
애플리케이션이 MediaStreamTrack을
RTCPeerConnection에 addTrack()
메서드로 연결할 때 암시적으로 생성되거나, 애플리케이션이
addTransceiver 메서드를 사용할 때
명시적으로 생성된다. 새로운 미디어 기술을 포함하는 원격 기술이 적용될 때도
생성된다. 또한 원격 엔드포인트에 전송할 미디어가 있음을 나타내는 원격 기술이 적용되면 관련
MediaStreamTrack과
RTCRtpReceiver가 애플리케이션에
track 이벤트를 통해 제공된다.
RTCRtpTransceiver가 다른 엔드포인트와
미디어를
송신하거나 수신하려면 양쪽 엔드포인트에
RTCRtpTransceiver 객체가 있고, 이
객체가 동일한
대상과 연결되도록
SDP로 협상해야 한다. 그 대상은 동일한 미디어 설명이다.
제안을 생성할 때 해당 측의 모든 트랜시버를 포함하기에 충분한 수의 미디어 기술이 생성된다. 이 제안을 로컬 기술로 설정하면 연결되지 않았던 모든 트랜시버가 제안의 미디어 기술과 연결된다.
제안이 원격 기술로 설정되면 제안 안에서 아직 트랜시버와 연결되지 않은 모든 미디어 기술이
새 트랜시버 또는 기존 트랜시버와 연결된다. 이 경우
addTrack() 메서드로 생성된
연결되지 않은 트랜시버만 연결될 수 있다.
addTransceiver()
메서드로 생성된 연결되지 않은 트랜시버는 원격 제안에 사용 가능한 미디어 기술이 있더라도
연결되지 않는다. 대신
addTrack()으로 생성된
트랜시버가 충분하지 않으면 새 트랜시버가 생성되어 연결된다. 이로 인해
addTrack()으로 생성된 트랜시버와
addTransceiver()로 생성된
트랜시버 사이에는 속성을 검사해서는 관찰할 수 없는 중요한 차이가 생긴다.
응답을 생성할 때는 제안에 존재했던 미디어 기술만 응답에 나열할 수 있다. 따라서
원격 제안을 설정할 때 연결되지 않았던 트랜시버는 로컬 응답을 설정한 뒤에도
연결되지 않은 상태로 남는다. 응답자가 후속 제안을 생성하여 또 다른
제안/응답 교환을 시작하면 이를 해결할 수 있다. 또는
addTrack()으로 생성된
트랜시버를 사용하는 경우에는 최초 교환에서 충분한 수의 미디어 기술을 제안하도록 보장할 수 있다.
RTP 미디어 API는 아래 설명과 같이 RTCPeerConnection 인터페이스를
확장한다.
WebIDL partial interface RTCPeerConnection {
sequence<RTCRtpSender> getSenders();
sequence<RTCRtpReceiver> getReceivers();
sequence<RTCRtpTransceiver> getTransceivers();
RTCRtpSender addTrack(MediaStreamTrack track, MediaStream... streams);
undefined removeTrack(RTCRtpSender sender);
RTCRtpTransceiver addTransceiver((MediaStreamTrack or DOMString) trackOrKind,
optional RTCRtpTransceiverInit init = {});
attribute EventHandler ontrack;
};
ontrack의 타입은 EventHandler
이 이벤트 처리기의 이벤트 타입은 track이다.
getSenders
RTCRtpSender 객체의 시퀀스를 반환한다.
이 객체들은 중지되지 않은
RTCRtpTransceiver 객체에 속하며
현재 이
RTCPeerConnection 객체에 연결된
RTP 송신기를 나타낸다.
getSenders 메서드가
호출되면 사용자 에이전트는
반드시 CollectSenders
알고리즘을 실행한 결과를 반환해야 한다.
CollectSenders 알고리즘을 다음과 같이 정의한다.
CollectTransceivers
알고리즘을 실행한 결과로 둔다.
[[Stopped]]가
false이면
transceiver.[[Sender]]를
senders에 추가한다.
getReceivers
RTCRtpReceiver 객체의 시퀀스를
반환한다. 이 객체들은 중지되지 않은
RTCRtpTransceiver 객체에 속하며
현재 이
RTCPeerConnection 객체에 연결된
RTP 수신기를 나타낸다.
getReceivers 메서드가
호출되면 사용자 에이전트는
반드시 다음 단계를 실행해야 한다.
CollectTransceivers
알고리즘을 실행한 결과로 둔다.
[[Stopped]]가
false이면
transceiver.[[Receiver]]를
receivers에 추가한다.
getTransceivers
현재 연결된 RTP 트랜시버를 나타내는
RTCRtpTransceiver 객체의
시퀀스를 반환한다. 이 트랜시버들은 이
RTCPeerConnection 객체에
연결되어 있다.
getTransceivers
메서드는 반드시
CollectTransceivers
알고리즘을 실행한 결과를 반환해야 한다.
CollectTransceivers 알고리즘을 다음과 같이 정의한다.
RTCRtpTransceiver 객체로
구성된 새 시퀀스로 둔다. 이 객체들은 이
RTCPeerConnection
객체의 트랜시버 집합에 있으며
삽입 순서에 따라 배치된다.
addTrack
새 트랙을 RTCPeerConnection에 추가하고,
해당 트랙이 지정된 MediaStream에 포함됨을 나타낸다.
addTrack 메서드가
호출되면 사용자 에이전트는 반드시
다음 단계를 실행해야 한다.
connection을 이 메서드가 호출된
RTCPeerConnection
객체로 둔다.
track을 메서드의 첫 번째 인수가 나타내는
MediaStreamTrack 객체로
둔다.
kind를 track.kind로 둔다.
streams를 MediaStream
객체의 목록으로 둔다. 이 목록은 메서드의 나머지 인수로 구성하며,
메서드가 하나의 인수로 호출되었다면 빈 목록으로 둔다.
connection.[[IsClosed]]가
true이면 다음 예외를 발생시킨다:
InvalidStateError.
senders를
CollectSenders 알고리즘을
실행한 결과로 둔다.
RTCRtpSender 중
track에 대한 객체가 이미 senders에 있으면 다음 예외를
발생시킨다:
InvalidAccessError.
아래 단계에서는 기존 송신기를 재사용할 수 있는지 판단하는 방법을 설명한다.
기존 송신기를 재사용하면 이후
createOffer와
createAnswer를
호출할 때 대응하는 미디어
설명을 sendrecv 또는 sendonly로 표시하고 송신기 스트림의 MSID를 추가한다.
이는 [RFC9429]의
(
5.2.2절 및
5.3.2절)에 정의되어 있다.
senders에 있는 RTCRtpSender 객체 중
다음 기준을 모두 충족하는 객체가 있으면 sender를
그 객체로 두고, 그렇지 않으면 null로 둔다.
송신기의 트랙이 null이다.
트랜시버 종류는
송신기와 연결된
RTCRtpTransceiver의
종류이며 kind와 일치한다.
[[Stopping]] 슬롯은
송신기와 연결된
RTCRtpTransceiver에
속하며 그 값은 false이다.
송신기가 전송에 사용된 적이 없다. 더 정확하게 말하면
[[CurrentDirection]]
슬롯은 송신기와 연결된
RTCRtpTransceiver에
속하며 그 값이
"sendrecv"
또는
"sendonly"였던
적이 없다.
sender가 null이 아니면 해당 송신기를 사용하기 위해
다음 단계를 실행한다.
sender.[[SenderTrack]]을
track으로 설정한다.
sender.[[AssociatedMediaStreamIds]]를
빈 집합으로 설정한다.
각 stream에 대해(streams 안에서)
stream.id를
[[AssociatedMediaStreamIds]]에
추가한다. 단, 아직 그곳에 없는 경우에만 추가한다.
transceiver를
RTCRtpTransceiver로
둔다. 이 객체는 sender와 연결되어 있다.
transceiver.[[Direction]]이
"recvonly"이면
transceiver.[[Direction]]을
"sendrecv"로
설정한다.
transceiver.[[Direction]]이
"inactive"이면
transceiver.[[Direction]]을
"sendonly"로
설정한다.
sender가 null이면 다음 단계를 실행한다.
RTCRtpSender를 생성한다. 이때 track, kind 및 streams를 사용하고 그 결과를 sender로 둔다.
RTCRtpReceiver를 생성한다. 이때 kind를 사용하고 그 결과를 receiver로 둔다.
RTCRtpTransceiver를 생성한다. 이때
sender, receiver 및 값이
"sendrecv"인
RTCRtpTransceiverDirection을
사용하고 그 결과를
transceiver로 둔다.
transceiver를 connection의 트랜시버 집합에 추가한다.
트랙의 콘텐츠에 애플리케이션이 접근할 수 없는 경우가 있다.
트랙을 CORS
교차 출처가 되게 하는 모든 원인으로 인해 이런 상황이 발생할 수 있다.
이러한 트랙도
addTrack()
메서드에 제공할 수 있으며 해당 트랙의
RTCRtpSender를 생성할 수 있지만,
콘텐츠는 전송해서는 안 된다.
트랙 콘텐츠 대신 무음(오디오), 검은 프레임(비디오) 또는 이와 동등하게
콘텐츠가 없는 상태를 전송한다.
이 속성은 시간에 따라 변경될 수 있다는 점에 유의한다.
협상 필요 플래그를 갱신한다. 대상은 connection이다.
sender를 반환한다.
removeTrack
sender의 미디어 전송을 중지한다.
RTCRtpSender는 계속
getSenders에 나타난다.
이렇게 하면 이후 createOffer를
호출할 때 대응하는 트랜시버의 미디어 설명을
"recvonly"
또는
"inactive"로
표시한다. 이는
[RFC9429]의
(
5.2.2절)에 정의되어 있다.
다른 피어가 이러한 방식으로 트랙 전송을 중지하면 해당 트랙은 원격
MediaStream에서 제거된다. 이 스트림은 최초
track
이벤트에서 공개된 스트림이다. 또한
MediaStreamTrack이 아직 음소거되지 않았다면
트랙에서 mute 이벤트가 발생한다.
removeTrack()과
같은 효과는 대응하는 트랜시버의
RTCRtpTransceiver.direction
속성을 설정하고 송신기에서
RTCRtpSender.replaceTrack(null)을
호출하여 얻을 수 있다. 한 가지 사소한 차이는
replaceTrack()은
비동기식이고
removeTrack()은
동기식이라는 점이다.
removeTrack 메서드가
호출되면 사용자 에이전트는
반드시 다음 단계를 실행해야 한다.
sender를 removeTrack에
전달된 인수로 둔다.
connection을 이 메서드가 호출된
RTCPeerConnection
객체로 둔다.
connection.[[IsClosed]]가
true이면 다음 예외를 발생시킨다:
InvalidStateError.
sender가
connection에 의해 생성된 것이 아니면 다음 예외를
발생시킨다:
InvalidAccessError.
transceiver를
RTCRtpTransceiver
객체로 둔다. 이 객체는 sender에 대응한다.
transceiver.[[Stopping]]이
true이면 이 단계를 중단한다.
senders를
CollectSenders 알고리즘을
실행한 결과로 둔다.
sender가 senders에 없으면 이 단계를 중단한다.
이는 해당 트랜시버가 중지되었거나
세션 기술을 설정하여 제거되었음을 나타낸다.
해당 세션 기술의 type은
"rollback"이다.
sender.[[SenderTrack]]이 null이면
이 단계를 중단한다.
sender.[[SenderTrack]]을 null로 설정한다.
transceiver.[[Direction]]이
"sendrecv"이면
transceiver.[[Direction]]을
"recvonly"로 설정한다.
transceiver.[[Direction]]이
"sendonly"이면
transceiver.[[Direction]]을
"inactive"로 설정한다.
협상 필요 플래그를 갱신한다. 대상은 connection이다.
addTransceiver
새 RTCRtpTransceiver를 생성하여
트랜시버 집합에 추가한다.
트랜시버를 추가하면 이후
createOffer를
호출할 때 대응하는 트랜시버의 미디어 설명이
추가된다. 이는 [RFC9429]의
(
5.2.2절)에 정의되어 있다.
mid의 초기값은 null이다.
세션 기술을 설정하면 나중에 이 값이
null이 아닌 값으로 변경될 수 있다.
sendEncodings
인수를 사용하여 제안할 동시 전송 인코딩의 수와 선택적으로 해당 RID 및
인코딩 매개변수를 지정할 수 있다.
이 메서드가 호출되면 사용자 에이전트는 반드시 다음 단계를 실행해야 한다.
init을 두 번째 인수로 둔다.
streams를
init.streams로 둔다.
sendEncodings를
init.sendEncodings로 둔다.
direction을
init.direction으로 둔다.
첫 번째 인수가 문자열이면 kind를 첫 번째 인수로 두고 다음 단계를 실행한다.
첫 번째 인수가 MediaStreamTrack이면
track을 첫 번째 인수로 두고 kind를
track.kind로 둔다.
connection.[[IsClosed]]가
true이면 다음 예외를 발생시킨다:
InvalidStateError.
다음
sendEncodings에 대해
addTransceiver sendEncodings 검증 단계를 실행한다.
그 안의 각 RTCRtpEncodingParameters
딕셔너리를 “인코딩”이라고 하며, 이를 통해 검증한다.
각
값이
sendEncodings에서 [RFC8851] 10절에
명시된 문법을 준수하는지 확인한다.
RID 중 하나라도 이 요구 사항을 충족하지 않으면 다음 예외를
발생시킨다:
ridTypeError.
TypeError.
어떤 인코딩이 포함하는 읽기 전용
매개변수가
rid가
아니면 다음 예외를 발생시킨다:
InvalidAccessError.
어떤 인코딩이 포함하는
codec
멤버의 값이 어떤 코덱과도
일치하지 않으면
다음에서 지원하는 코덱이 아니다:
RTCRtpSender.getCapabilities(kind).codecs.
이 경우 다음 예외를 발생시킨다:
OperationError.
사용자 에이전트가 협상 없이 코덱을 변경하는 기능을 지원하지 않거나
개별 인코딩에 코덱을 설정하는 기능을 지원하지 않으면 프로미스를
거부된 상태로
반환한다. 이때 새로 생성한
OperationError를 사용한다.
kind가 "audio"이면
scaleResolutionDownBy
및
maxFramerate
멤버 중 하나라도 포함하는 모든 인코딩에서
해당 멤버를 제거한다.
어떤 인코딩이 포함하는
scaleResolutionDownBy
멤버의 값이 1.0보다 작으면 다음 예외를 발생시킨다:
RangeError.
정의된 각
maxFramerate
멤버가 sendEncodings에서 0.0보다 큰 값을 갖는지 확인한다.
maxFramerate
값 중 하나라도 이 요구 사항을 충족하지 않으면 다음 예외를
발생시킨다:
RangeError.
maxN을 사용자 에이전트가 지원할 수 있는 동시 인코딩 총수의
최댓값으로 둔다. 이는 해당 kind에 적용되며 최소값은
1이다. 아직 사용할 코덱을 알 수 없으므로 이 값은
낙관적으로 정하는 것이 좋다.
어떤 인코딩이 포함하는
scaleResolutionDownBy
멤버가 있으면 해당 멤버가 없는 각 인코딩에
scaleResolutionDownBy
멤버를 값 1.0과 함께 추가한다.
저장된 인코딩 수가 sendEncodings에서 maxN을 초과하면 sendEncodings의 길이가 maxN이 될 때까지 끝에서부터 잘라낸다.
kind가 "video"이고 어느 인코딩에도
포함되어 있지 않은
scaleResolutionDownBy
멤버라면 각 인코딩에
scaleResolutionDownBy
멤버를 다음 값과 함께 추가한다:
2^(length of sendEncodings - encoding
index - 1). 그 결과 해상도가 작은 것부터 큰 것 순으로 배치되며
마지막 인코딩에는 크기 조정이 적용되지 않는다. 예를 들어 길이가 3이면
4:2:1이 된다.
현재 저장된 인코딩 수가
sendEncodings에서 1이면 유일한 항목에서
모든 rid
멤버를 제거한다.
RTCRtpEncodingParameters를
sendEncodings에 제공하면 애플리케이션이 나중에
setParameters를
사용하여 인코딩 매개변수를 설정할 수 있다. 동시 전송을 사용하지
않는 경우에도 가능하다.
RTCRtpSender를 생성한다. 이때 track, kind, streams 및 sendEncodings를 사용하고 그 결과를 sender로 둔다.
sendEncodings가 설정되어 있으면 이후
createOffer
호출은 여러 RTP 인코딩을 전송하도록 구성된다. 이는
[RFC9429]의
(
5.2.2절 및
5.2.1절)에 정의되어 있다.
setRemoteDescription이
여러 RTP 인코딩을 수신할 수 있는 대응 원격 기술로 호출되었다고 하자.
이 기능은
[RFC9429]의
(
3.7절)에 정의되어 있다. 이 경우
RTCRtpSender가
여러 RTP 인코딩을 전송할 수 있으며, 트랜시버의
sender.getParameters()를
통해 가져온 매개변수에는 협상된 인코딩이 반영된다.
RTCRtpReceiver를 생성한다. 이때 kind를 사용하고 그 결과를 receiver로 둔다.
RTCRtpTransceiver를 생성한다. 이때 sender, receiver 및 direction을 사용하고 그 결과를 transceiver로 둔다.
transceiver를 connection의 트랜시버 집합에 추가한다.
협상 필요 플래그를 갱신한다. 대상은 connection이다.
transceiver를 반환한다.
WebIDLdictionary RTCRtpTransceiverInit {
RTCRtpTransceiverDirection direction = "sendrecv";
sequence<MediaStream> streams = [];
sequence<RTCRtpEncodingParameters> sendEncodings = [];
};
direction의 타입은 RTCRtpTransceiverDirection이며,
기본값은 "sendrecv"이다.
RTCRtpTransceiver의 방향이다.
streams의 타입은 sequence<MediaStream>이다.
원격 RTCPeerConnection의 트랙
이벤트가 발생할 때, 추가되는 RTCRtpReceiver에 대응하여
이벤트에 포함될 스트림이다.
sendEncodings의 타입은 sequence<RTCRtpEncodingParameters>이다.
미디어의 RTP 인코딩을 전송하기 위한 매개변수를 포함하는 시퀀스이다.
WebIDLenum RTCRtpTransceiverDirection {
"sendrecv",
"sendonly",
"recvonly",
"inactive",
"stopped"
};
| 열거형 값 | 설명 |
|---|---|
sendrecv
|
RTCRtpTransceiver의
RTCRtpSender
sender는 RTP 전송을 제안하며, 원격 피어가 이를 수락하고
sender.getParameters().encodings[i].active가
어떤 i 값에 대해서든 true이면 RTP를 전송한다.
RTCRtpTransceiver의
RTCRtpReceiver는 RTP 수신을
제안하며, 원격 피어가 수락하면 RTP를 수신한다.
|
sendonly
|
RTCRtpTransceiver의
RTCRtpSender
sender는 RTP 전송을 제안하며, 원격 피어가 이를 수락하고
sender.getParameters().encodings[i].active가
어떤 i 값에 대해서든 true이면 RTP를 전송한다.
RTCRtpTransceiver의
RTCRtpReceiver는 RTP 수신을
제안하지 않으며 RTP를 수신하지 않는다.
|
recvonly
|
RTCRtpTransceiver의
RTCRtpSender는 RTP 전송을
제안하지 않으며 RTP를 전송하지 않는다.
RTCRtpTransceiver의
RTCRtpReceiver는 RTP 수신을
제안하며, 원격 피어가 수락하면 RTP를 수신한다.
|
inactive
|
RTCRtpTransceiver의
RTCRtpSender는 RTP 전송을
제안하지 않으며 RTP를 전송하지 않는다.
RTCRtpTransceiver의
RTCRtpReceiver는 RTP 수신을
제안하지 않으며 RTP를 수신하지 않는다.
|
stopped
|
RTCRtpTransceiver는
RTP를 송신하지도 수신하지도 않는다.
제안에서는 포트 0을 생성한다. 응답에서는
RTCRtpSender가 RTP 전송을
제안하지 않고,
RTCRtpReceiver도 RTP 수신을
제안하지 않는다. 이는 종단 상태이다.
|
애플리케이션은 트랜시버의 방향을 양방향 모두 일시적으로 끄는
"inactive"로 설정하거나
수신 방향만 거부하는
"sendonly"로 설정하여
수신 미디어 기술을 거부할 수 있다. m-line을 재사용할 수 있게 하면서 영구적으로 거부하려면
애플리케이션이
RTCRtpTransceiver.stop()을 호출한 후
해당 측에서 협상을 시작해야 한다.
원격 트랙을 처리하려면
RTCRtpTransceiver transceiver,
direction, msids, addList,
removeList 및 trackEventInits가 주어졌을 때
다음 단계를 실행한다.
연결된 원격 스트림을 설정한다. 이때
transceiver.[[Receiver]], msids,
addList 및 removeList를 사용한다.
direction이
"sendrecv" 또는
"recvonly"이고
transceiver.[[FiredDirection]]이
"sendrecv"도 아니고
"recvonly"도 아니거나,
이전 단계에서 addList의 길이가 증가했다면
원격 트랙의
추가를 처리한다. 이때 transceiver와
trackEventInits를 사용한다.
direction이
"sendonly" 또는
"inactive"이면
transceiver.[[Receptive]]를
false로 설정한다.
direction이
"sendonly" 또는
"inactive"이고
transceiver.[[FiredDirection]]이
"sendrecv" 또는
"recvonly"이면
원격 트랙의
제거를 처리한다. 대상은 미디어
설명이며,
transceiver와 muteTracks를 사용한다.
transceiver.[[FiredDirection]]을
direction으로 설정한다.
원격 트랙의 추가를
처리하려면 다음 값이 주어진다: RTCRtpTransceiver
transceiver 및 trackEventInits. 그런 다음
다음 단계를 실행한다.
receiver를
transceiver.[[Receiver]]로 둔다.
track을
receiver.[[ReceiverTrack]]으로 둔다.
streams를
receiver.[[AssociatedRemoteMediaStreams]]로 둔다.
새 RTCTrackEventInit 딕셔너리를 생성한다.
그 멤버는 receiver, track, streams 및
transceiver이며, 이 딕셔너리를
trackEventInits에 추가한다.
원격 트랙의 제거를
처리하려면 RTCRtpTransceiver
transceiver와 muteTracks를 사용하여 다음
단계를 실행한다.
receiver를
transceiver.[[Receiver]]로 둔다.
track을
receiver.[[ReceiverTrack]]으로 둔다.
track.muted가 false이면
track을 muteTracks에 추가한다.
연결된
원격 스트림을 설정하려면 다음 값이 주어진다:
RTCRtpReceiver receiver,
msids, addList 및 removeList.
그런 다음 다음 단계를 실행한다.
connection을
RTCPeerConnection 객체로 둔다.
이 객체는 receiver와 연결되어 있다.
msids의 각 MSID에 대해
MediaStream
객체가 해당 id를 사용하여 이
connection에 대해 이전에 생성되지 않았다면
그 id를 가진
MediaStream 객체를 생성한다.
streams를
MediaStream 객체의 목록으로 둔다.
이 객체들은 이 connection에 대해
id로 생성되었으며, 해당 ID는
msids에 대응한다.
track을
receiver.[[ReceiverTrack]]으로 둔다.
각 stream에 대해, 해당 항목이
receiver.[[AssociatedRemoteMediaStreams]]에
있지만 streams에는 없다면
stream과 track을 한 쌍으로
removeList에 추가한다.
streams에 있는 각 stream이
receiver.[[AssociatedRemoteMediaStreams]]에
없다면 stream과 track을 한 쌍으로
addList에 추가한다.
receiver.[[AssociatedRemoteMediaStreams]]를
streams로 설정한다.
RTCRtpSender 인터페이스는
애플리케이션이 주어진
MediaStreamTrack을 인코딩하여 원격 피어로 전송하는 방식을 제어할 수
있도록 한다. setParameters
가
RTCRtpSender 객체에서
호출되면 인코딩이 그에 맞게 변경된다.
RTCRtpSender를 생성하는 절차를 MediaStreamTrack인
track, 문자열 kind,
MediaStream
객체 목록 streams 및 선택적인
RTCRtpEncodingParameters 객체 목록
sendEncodings으로
실행하려면 다음 단계를 실행한다:
sender를 새 RTCRtpSender 객체로 둔다.
sender에 [[SenderTrack]] 내부 슬롯을 두고 track로 초기화한다.
sender에 [[SenderTransport]]
내부 슬롯을 두고 null로 초기화한다.
sender에
[[LastStableStateSenderTransport]] 내부
슬롯을 두고 null로 초기화한다.
sender에 [[Dtmf]]
내부
슬롯을 두고 null로 초기화한다.
kind가 "audio"이면 RTCDTMFSender를
생성하는 절차로 dtmf를 생성하고 [[Dtmf]]
내부 슬롯을 dtmf로 설정한다.
sender에
[[AssociatedMediaStreamIds]] 내부 슬롯을 두고,
이 슬롯은 해당 sender와 연결할 MediaStream 객체의
ID 목록을 나타낸다.
[[AssociatedMediaStreamIds]]
슬롯은
sender가
[RFC9429] (section 5.2.1.)에 설명된 대로 SDP로 표현될 때 사용한다.
sender.[[AssociatedMediaStreamIds]]를
빈
집합으로 설정한다.
각
stream에 대해, streams에 속하는 항목이라면
stream.id를 [[AssociatedMediaStreamIds]]
에 아직 없을 때 추가한다.
sender에 [[SendEncodings]]
내부 슬롯을 두며, 이는
RTCRtpEncodingParameters
사전의 목록을 나타낸다.
sendEncodings가 이 알고리즘의 입력으로 주어지고
비어 있지 않으면, [[SendEncodings]] 슬롯을
sendEncodings로 설정한다. 그렇지 않으면
새 RTCRtpEncodingParameters
사전 하나를 포함하는 목록으로 설정하고,
kind가 "video"이면 해당 사전에
scaleResolutionDownBy
멤버를 추가하여
값을 1.0으로 설정한다.
RTCRtpEncodingParameters
사전에는
active 멤버가 포함되며
그 기본값은
true이다.
sender에
[[LastStableRidlessSendEncodings]] 내부
슬롯을 두고 null로 초기화한다.
sender에 [[SendCodecs]] 내부
슬롯을 둔다. 이 슬롯은 RTCRtpCodecParameters
사전의 목록을 나타내며 빈 목록으로 초기화한다.
sender에
[[LastReturnedParameters]] 내부 슬롯을
두며, 이는 getParameters와
setParameters 트랜잭션을 대응시키는 데 사용한다.
sender를 반환한다.
WebIDL[Exposed=Window]
interface RTCRtpSender {
readonly attribute MediaStreamTrack? track;
readonly attribute RTCDtlsTransport? transport;
static RTCRtpCapabilities? getCapabilities(DOMString kind);
Promise<undefined> setParameters(RTCRtpSendParameters parameters,
optional RTCSetParameterOptions setParameterOptions = {});
RTCRtpSendParameters getParameters();
Promise<undefined> replaceTrack(MediaStreamTrack? withTrack);
undefined setStreams(MediaStream... streams);
Promise<RTCStatsReport> getStats();
};
track of type MediaStreamTrack, readonly,
nullable
track 속성은
이
RTCRtpSender 객체와 연결된 트랙이다. track이 종료되었거나
트랙의 출력이 비활성화되었으면, 즉 트랙이 비활성화되거나
음소거되었으면, RTCRtpSender는 반드시 검은 프레임을
보내야 하고(비디오) 절대로 전송해서는 안 된다(오디오). 비디오의 경우
RTCRtpSender는 가급적 초당 하나의 검은 프레임을 보내야 한다.
track이 null이면
RTCRtpSender는
전송하지 않는다. 값을 가져올 때 이 속성은 반드시
[[SenderTrack]] 슬롯의 값을 반환해야 한다.
transport of type RTCDtlsTransport,
readonly, nullable
transport
속성은
track의 미디어를
RTP 패킷
형태로 보내는 전송이다. RTCDtlsTransport 객체가 생성되기 전에는
transport 속성이
null이다. 번들링을 사용하면
여러 RTCRtpSender 객체가 하나의
transport를 공유하며
모두 같은 전송으로 RTP와 RTCP를
보낸다.
값을
가져올 때 이 속성은 반드시
[[SenderTransport]] 슬롯의 값을 반환해야 한다.
getCapabilities, static
정적
RTCRtpSender.getCapabilities()
메서드는 리소스, 포트
또는 다른 상태를 예약하지 않고도 사용자 에이전트가 주어진 종류의
미디어를 보내기 위해 지원하는 기능의 종류를 알아내는 방법을 제공한다.
getCapabilities
메서드가 호출되면 사용자 에이전트는 반드시 다음
단계를 실행해야 한다:
kind를 메서드의 첫 번째 인수로 둔다.
kind가 "video"도 "audio"도
아니면 null을 반환한다.
새 RTCRtpCapabilities
사전을 반환한다. 이때
codecs
멤버는
구현된
송신 코덱 목록 중 kind에 해당하는 목록으로 초기화하고,
headerExtensions
멤버는
구현된
송신용 헤더 확장 목록 중
kind에 해당하는 목록으로 초기화한다.
구현된 송신 코덱 목록은 주어진 kind에
대해 구현 정의 방식으로 정해지는 RTCRtpCodec
사전의 목록이며,
주어진 kind(비디오 또는 오디오)의 미디어를 보내기 위해 사용자 에이전트가 지원하는 코덱을 가장 낙관적으로 나타낸다.
구현된 송신용 헤더 확장
목록은 주어진
kind에 대해 구현 정의
방식으로 정해지는
RTCRtpHeaderExtensionCapability
사전의
목록이며, 주어진
kind(비디오 또는 오디오)의 미디어를 보내기 위해 사용자 에이전트가 지원하는 헤더 확장을 가장 낙관적으로 나타낸다.
이러한
기능은 일반적으로 오래 유지되며 출처를 넘어 이용할
수 있는 장치 정보를 제공하므로 애플리케이션의
핑거프린팅 가능 범위를 늘린다. 개인정보 보호에
민감한 상황에서 사용자 에이전트는 경우에 따라 기능의
공통
부분집합만 보고하는 등의 완화 조치를 고려할 수 있다.
반환된
코덱 기능은
setCodecPreferences()
알고리즘과 이
알고리즘이 어떤 입력에 대해 InvalidModificationError를
던지는지에
영향을 준다. 개인정보 보호 완화 조치의 효과를 보장하려면, 이 정보는
createOffer()와
createAnswer()가
송신용으로
협상된 코덱에 관해 드러내는
정보와도 일관되어야 한다.
setParameters
setParameters
메서드는 track을 인코딩하여
원격 피어로 전송하는 방식을 갱신한다.
setParameters 메서드가
호출되면 사용자 에이전트는
반드시 다음 단계를 실행해야 한다:
RTCRtpSender 객체로 두며, 이 객체에서
setParameters
가 호출된다.
RTCRtpTransceiver 객체로
두며, 이는
sender와 연결되어 있다(즉, sender는
transceiver.[[Sender]]이다).
[[Stopping]]가
true이면 거부된
상태인 프로미스를 반환한다. 이때
거부 사유는 새로 생성한 InvalidStateError이다.
[[LastReturnedParameters]]가
null이면 거부된
상태인 프로미스를 반환한다. 이때
거부 사유는 새로 생성한 InvalidStateError이다.
encodings로 둔다.
codecs로 둔다.
choosableCodecs를 codecs로 둔다.
choosableCodecs가 빈 목록이면
choosableCodecs를
transceiver.[[PreferredCodecs]]로
설정하고
구현된
송신 코덱 목록에 포함되지 않는 코덱은 모두 제외한다.
choosableCodecs가 여전히 빈 목록이면 choosableCodecs를 구현된 송신 코덱 목록 중 transceiver의 종류에 해당하는 목록으로 설정한다.
RTCRtpEncodingParameters의
개수로 두며, 이는
sender.[[SendEncodings]]에 저장되어 있는 사전의 개수이다.
InvalidModificationError이다:
encodings.length
가 N과 다르다.
[[LastReturnedParameters]]
의 대응하는 매개변수 값과 다르다. 이는
transactionId에도 적용된다.
true로 설정한다.
트랜시버
종류가 "audio"이면
scaleResolutionDownBy와
maxFramerate
멤버를 모든 encodings에서 제거하되, 이들 중 하나라도
포함하는 항목에 대해 수행한다.
트랜시버
종류가 "video"
이면 encodings의 각 인코딩 중 멤버를
포함하지 않는 항목에 대해, 그 멤버는
scaleResolutionDownBy이다.
여기에
scaleResolutionDownBy
멤버를 추가하고 값을 1.0으로 설정한다.
트랜시버
종류가 "video"
이고 encodings의 어떤 인코딩이
포함하는
scaleResolutionDownBy
멤버의 값이 1.0보다
작으면, 거부된 상태인 프로미스를 반환한다.
거부 사유는 새로 생성한 RangeError이다.
encodings의 각 인코딩에 값이
0.0 이상인 maxFramerate
멤버가 있는지 확인한다.
maxFramerate
값 중 하나라도 이 요건을 충족하지
않으면, 거부된 상태인 프로미스를 반환한다. 이때
거부 사유는 새로 생성한 RangeError이다.
사용자 에이전트가 어느 인코딩의 코덱 설정이나 서로 다른
인코딩에
서로 다른 코덱 값을 혼합하는 것을 지원하지 않으면,
거부된
상태인 프로미스를 반환한다. 이때 거부 사유는 새로 생성한
OperationError이다.
[[SenderTrack]]이다.
[[LastReturnedParameters]]를
null로 설정한다.
[[SendEncodings]]를
parameters.encodings로 설정한다.
undefined로 결정한다.
RTCError이며, 그
errorDetail은
"
hardware-encoder-not-available
"로 설정한다. 그리고 이 단계들을 중단한다.
RTCError이며 그
errorDetail은
"
hardware-encoder-error
"로
설정한다. 그리고 이 단계들을 중단한다.
OperationError이다.
setParameters
는 SDP 재협상을 유발하지
않으며, 제안/응답으로 협상된 엔벌로프 안에서 미디어
스택이 보내거나 받는 것을 변경하는 데만 사용할
수 있다. RTCRtpSendParameters
사전의 속성은
이 범위를 벗어나는 변경을 허용하지 않도록 설계되어 있으므로,
cname처럼 변경할
수
없는 속성은 읽기 전용이다. 비트레이트 같은 다른
항목은 maxBitrate
등의 한도로 제어한다. 사용자
에이전트는 maxBitrate
가 지정하는 최대 비트레이트를 초과하지 않는 동시에 SDP 등
다른 곳에서 지정한 비트레이트 제약도 충족하도록 보장해야 한다.
getParameters
getParameters()
메서드는 RTCRtpSender
객체의 현재 매개변수를 반환한다. 이는 track을
인코딩하여 원격 RTCRtpReceiver로 전송하는 방식에 관한 매개변수이다.
getParameters
가 호출되면 사용자 에이전트는 반드시 다음
단계를 실행해야 한다:
sender를 getter가 호출된 RTCRtpSender
객체로 둔다.
sender.[[LastReturnedParameters]]가
null이 아니면
sender.[[LastReturnedParameters]]
를
반환하고 이 단계들을 중단한다.
result를 다음과 같이 구성한 새 RTCRtpSendParameters
사전으로 둔다:
transactionId는
새 고유
식별자로 설정한다.
encodings는
[[SendEncodings]]
내부 슬롯의 값으로 설정한다.
headerExtensions
시퀀스는
송신용으로 협상된 헤더 확장을
바탕으로 채운다.
codecs
는
[[SendCodecs]] 내부 슬롯의
값으로 설정한다.
rtcp.cname
는 연결된 RTCPeerConnection의 CNAME으로 설정한다.
rtcp.reducedSize는
축소 크기 RTCP가 송신용으로 협상되었으면 true로, 그렇지
않으면 false로 설정한다.
sender.[[LastReturnedParameters]]를
result로 설정한다.
sender.[[LastReturnedParameters]]를
null로 설정하는 태스크를 큐에 넣는다.
result를 반환한다.
getParameters
는 setParameters
와 함께 다음 방식으로 매개변수를 변경하는 데 사용할 수 있다:
async function updateParameters() {
try {
const params = sender.getParameters();
// ... make changes to parameters
params.encodings[0].active = false;
await sender.setParameters(params);
} catch (err) {
console.error(err);
}
}
setParameters
호출이 완료되면 이후의
getParameters
호출은 수정된 매개변수
집합을 반환한다.
replaceTrack
재협상
없이 RTCRtpSender의 현재 track을
제공된 다른 트랙(또는 null
트랙)으로 대체하려고 시도한다.
replaceTrack 메서드가
호출되면 사용자 에이전트는
반드시 다음 단계를 실행해야 한다:
sender를 RTCRtpSender 객체로 두며, 이
객체에서 replaceTrack가
호출된다.
transceiver를 RTCRtpTransceiver
객체로 두며, 이 객체는 sender와 연결되어 있다.
connection를 RTCPeerConnection
객체로 두며, 이 객체는 sender와 연결되어 있다.
withTrack를 이 메서드의 인수로 둔다.
withTrack가 null이 아니고
withTrack.kind가
트랜시버 종류,
즉 transceiver의
종류와 다르면, 거부된 상태인 프로미스를 반환한다. 거부 사유는 새로 생성한 TypeError이다.
작업을 연결하는 절차로 다음 단계를 connection의 작업 체인에 연결한 결과를 반환한다:
transceiver.[[Stopping]]가
true이면 거부된
상태인 프로미스를 반환한다. 이때 거부 사유는 새로 생성한
InvalidStateError이다.
p를 새 프로미스로 둔다.
sending를 true로 두되, 이는
transceiver.[[CurrentDirection]]가
"sendrecv"
또는 "
sendonly"인 경우이다.
그렇지 않으면
false로 둔다.
다음 단계를 병렬로 실행한다:
sending가 true이고
withTrack이 null이면
송신자의 전송을 중단시킨다.
sending가 true이고
withTrack이 null
이 아니면, withTrack을
송신자가 이미 협상한 엔벌로프를 위반하지
않고 즉시 보낼 수 있는지
판단한다. 불가능하면:
InvalidModificationError이다.
sending가 true이고
withTrack이 null
이 아니면, 송신자가 기존 트랙 대신
withTrack을 끊김 없이
전송하도록 전환시킨다.
다음 단계를 실행하는 태스크를 큐에 넣는다:
connection.[[IsClosed]]가
true이면 이 단계들을 중단한다.
sender.[[SenderTrack]]를
withTrack로 설정한다.
전역 태스크를 큐에
넣는다. 소스는 네트워킹 태스크
소스이고
현재 렐름의 전역 객체를
global로 사용한다. 태스크는 결정 절차로
p를 undefined로 결정한다.
p를 반환한다.
크기나 프레임 속도를 변경하는 데 협상이 필요하지 않을 수도 있다. 협상이 필요할 수 있는 경우는 다음과 같다:
setStreams
이
송신자의 트랙과 연결할 MediaStream 객체들을
설정한다.
setStreams 메서드가
호출되면 사용자 에이전트는
반드시 다음 단계를 실행해야 한다:
sender를 이 메서드가 호출된 RTCRtpSender
객체로 둔다.
connection를 이 메서드가 호출된 RTCPeerConnection
객체로 둔다.
connection.[[IsClosed]]가
true이면 예외를 던지는 절차로
InvalidStateError를 던진다.
streams을 메서드의 인수에서 구성한 MediaStream
객체 목록으로 두며, 인수
없이 호출되었으면 빈 목록으로 둔다.
sender.[[AssociatedMediaStreamIds]]를
빈 집합으로 설정한다.
각
stream에 대해, streams에 속하는 항목이라면
stream.id를
[[AssociatedMediaStreamIds]]에
아직 없을 때 추가한다.
협상 필요 플래그를 갱신하는 절차를 connection에 대해 실행한다.
getStats
이 송신자에 대해서만 통계를 수집하고 결과를 비동기적으로 보고한다.
getStats()
메서드가 호출되면 사용자 에이전트는
반드시 다음 단계를 실행해야 한다:
selector를 메서드가 호출된 RTCRtpSender
객체로 둔다.
p를 새 프로미스로 두고 다음 단계를 병렬로 실행한다:
selector가 나타내는 통계를 통계 선택 알고리즘에 따라 수집한다.
전역 태스크를 큐에 넣는다. 이 태스크의 소스는 네트워킹 태스크 소스이고,
현재 렐름의 전역 객체를
global로 사용한다. 태스크는 결정 절차로
p를 결정하며, 그 값은 수집한 통계를 포함하는 결과 RTCStatsReport
객체이다.
p를 반환한다.
WebIDLdictionary RTCRtpParameters {
required sequence<RTCRtpHeaderExtensionParameters> headerExtensions;
required RTCRtcpParameters rtcp;
required sequence<RTCRtpCodecParameters> codecs;
};
RTCRtpParameters Members
headerExtensions of type sequence<RTCRtpHeaderExtensionParameters>,
required
RTP 헤더 확장의 매개변수를 포함하는 시퀀스이다. 읽기 전용 매개변수이다.
rtcp of type RTCRtcpParameters,
required
RTCP에 사용하는 매개변수이다. 읽기 전용 매개변수이다.
codecs
of type sequence<RTCRtpCodecParameters>,
required
RTCRtpSender가 선택할
미디어 코덱과 RTX,
RED 및 FEC 메커니즘의 항목을 포함하는
시퀀스이다. RTX를 통한 재전송이 활성화된 각 미디어
코덱에는 codecs의 대응 항목이 있으며, 이 항목의
mimeType
속성은 audio/rtx 또는
video/rtx를 통한 재전송을 나타내고,
sdpFmtpLine
속성은 "apt"와
"rtx-time" 매개변수를 제공한다. 읽기 전용
매개변수이다.
WebIDLdictionary RTCRtpSendParameters : RTCRtpParameters {
required DOMString transactionId;
required sequence<RTCRtpEncodingParameters> encodings;
};
RTCRtpSendParameters
Members
transactionId of type DOMString, required
마지막으로
적용된 매개변수 집합의 고유 식별자이다.
setParameters가
이전의
getParameters
를 바탕으로만 호출되고 그 사이에 변경이 없도록 보장한다. 읽기 전용 매개변수이다.
encodings of type sequence<RTCRtpEncodingParameters>,
required
미디어의 RTP 인코딩 매개변수를 포함하는 시퀀스이다.
WebIDLdictionary RTCRtpReceiveParameters : RTCRtpParameters {
};
WebIDLdictionary RTCRtpCodingParameters {
DOMString rid;
};
RTCRtpCodingParameters
Members
rid of type DOMString
설정되어
있으면 이 RTP 인코딩은
[RFC9429]
(section
5.2.1.)에 정의된 RID 헤더
확장과 함께 전송된다. RID는 setParameters
로 변경할
수 없다. 송신 측의 addTransceiver에서만
설정하거나 변경할 수 있다. 읽기 전용
매개변수이다.
WebIDLdictionary RTCRtpEncodingParameters : RTCRtpCodingParameters {
boolean active = true;
RTCRtpCodec codec;
unsigned long maxBitrate;
double maxFramerate;
double scaleResolutionDownBy;
};
RTCRtpEncodingParameters
Members
active of type boolean, defaulting to
true
이
인코딩을 실제로 보내고 있음을 나타낸다.
false로 설정하면 이 인코딩을
더 이상 보내지 않는다. true로
설정하면 이 인코딩을 보낸다. 값을
false로 설정해도 SSRC가 제거되지는 않으므로 RTCP
BYE를 보내지 않는다.
codec of type RTCRtpCodec
이 인코딩의 RTP 스트림에 사용할 코덱을 선택하는 선택적 값이다. 없으면 사용자 에이전트는 송신용으로 협상된 코덱 중 어느 것이든 선택하여 사용할 수 있다.
codec이
설정되어 있고 [[SendCodecs]]가
협상되어 있으면,
사용자 에이전트는 가급적 [[SendCodecs]] 중
codec과
일치하는 첫 번째 항목을 송신에 사용해야 한다. 일치 여부는 코덱 사전 일치
알고리즘으로
판정하며, ignoreLevels는 true로 설정한다.
maxBitrate of type unsigned long
존재하면
이 인코딩을 보내는 데
사용할 수 있는 최대
비트레이트를 나타낸다. 사용자 에이전트는
maxBitrate
값을 초과하지 않는 한 인코딩 간에 대역폭을
자유롭게 할당할 수 있다. 인코딩은 전송별 또는 세션별
대역폭 한도 같은 다른 한도에 따라 여기서 지정한 최대값보다
낮게 제한될 수도 있다. maxBitrate는
[
RFC3890
]
6.2.2절에 정의된 전송 독립적 애플리케이션별 최대(TIAS) 대역폭과 같은 방식으로 계산한다. 이는
IP 또는 TCP나 UDP 같은 다른 전송 계층을 계산에 넣지 않은, 필요한
최대 대역폭이다. maxBitrate의
단위는 초당 비트이다.
비트레이트를 달성하는 방식은 미디어와 인코딩에 따라 다르다. 비디오에서는 항상 가능한 한 빨리 프레임을 보내지만, 비트레이트가 충분히 낮아질 때까지 프레임을 버릴 수 있다. 따라서 비트레이트가 0이어도 프레임 하나는 보낼 수 있다. 오디오에서는 비트레이트가 선택한 인코딩을 전송할 만큼 충분한 대역폭을 허용하지 않으면 재생을 중단해야 할 수도 있다.
maxFramerate of type double
이
멤버는 송신자의 kind가
"video"
일 때만 존재할 수 있다. 존재하면 이 인코딩을 보내는 데 사용할 수
있는 최대 프레임 속도를 초당 프레임 수로 나타낸다. 사용자
에이전트
는
maxFramerate
값을 초과하지 않는 한 인코딩 간에 대역폭을 자유롭게 할당할 수 있다.
setParameters()
로 변경하면 새
프레임 속도는 현재 그림이 완성된 뒤에 적용된다. 따라서 최대
프레임 속도를 0으로 설정하면 다음 프레임에서 비디오가 정지하는 효과가
있다.
scaleResolutionDownBy of type
double
이
멤버는 송신자의 kind가
"video"일
때만 존재한다. 전송하기 전에 비디오 해상도의
각 차원을 주어진 값으로 나누어 축소한다.
예를 들어 값이 2.0이면 각 차원을
2배 축소하므로 크기가 4분의 1인 비디오를
보내게 된다. 값이 1.0이면 비디오에 영향을
주지 않는다. 값은 1.0 이상이어야 한다.
기본적으로 2배씩 축소하는 방식을 역순으로 적용하여
4:2:1처럼 낮은 해상도부터 높은 해상도까지의
순서를 만든다. 계층이 하나뿐이면 송신자는 기본적으로
축소하지 않는다(즉,
scaleResolutionDownBy는
1.0이다).
WebIDLdictionary RTCRtcpParameters {
DOMString cname;
boolean reducedSize;
};
RTCRtcpParameters Members
cname
of type DOMString
RTCP가 사용하는 정규 이름(CNAME)이다(예: SDES 메시지에서 사용). 읽기 전용 매개변수이다.
reducedSize of type boolean
축소 크기 RTCP[ RFC5506 ]를 구성했는지(true일 때), 또는 [ RFC3550 ]에 지정된 복합 RTCP를 구성했는지(false일 때)를 나타낸다. 읽기 전용 매개변수이다.
WebIDLdictionary RTCRtpHeaderExtensionParameters {
required DOMString uri;
required unsigned short id;
boolean encrypted = false;
};
RTCRtpHeaderExtensionParameters
Members
uri of type DOMString, required
[ RFC5285 ]에 정의된 RTP 헤더 확장의 URI이다. 읽기 전용 매개변수이다.
id of type unsigned short, required
헤더 확장을 식별하도록 RTP 패킷에 넣는 값이다. 읽기 전용 매개변수이다.
encrypted of type boolean
헤더 확장이 암호화되는지를 나타낸다. 읽기 전용 매개변수이다.
RTCRtpHeaderExtensionParameters
사전을
사용하면 애플리케이션은
RTCRtpSender 또는 RTCRtpReceiver에서 헤더 확장을 사용하도록 구성되어 있는지 판단할 수 있다.
RTCRtpTransceiver
transceiver에 대해서는
SDP를 파싱하지 않고도 헤더 확장의 "direction" 매개변수([
RFC5285]
5절에 정의됨)를 다음과 같이 판단할 수
있다:
sender.getParameters().headerExtensions에만 포함된다.
receiver.getParameters().headerExtensions에만 포함된다.
sender.getParameters().headerExtensions와
transceiver.receiver.getParameters().headerExtensions에 모두 포함된다.
sender.getParameters().headerExtensions와
transceiver.receiver.getParameters().headerExtensions 어느 쪽에도 포함되지 않는다.
WebIDLdictionary RTCRtpCodec {
required DOMString mimeType;
required unsigned long clockRate;
unsigned short channels;
DOMString sdpFmtpLine;
};
RTCRtpCodec Members
RTCRtpCodec 사전은 코덱
객체에
관한 정보를 제공한다.
mimeType of type DOMString, required
코덱의 MIME 미디어 유형/하위 유형이다. 유효한 미디어 유형과 하위 유형은 [ IANA-RTP-2 ]에 나열되어 있다.
clockRate of type unsigned long, required
헤르츠 단위로 표현한 코덱 클록 속도이다.
channels of type unsigned short
존재하면 최대 채널 수를 나타낸다(mono=1, stereo=2).
sdpFmtpLine of type DOMString
코덱에
대응하는 SDP의
a=fmtp 행이
존재하면 그 행의 "형식별 매개변수" 필드이며,
[RFC9429]
(section
5.8.)에 정의되어 있다.
WebIDLdictionary RTCRtpCodecParameters : RTCRtpCodec {
required octet payloadType;
};
RTCRtpCodecParameters
Members
RTCRtpCodecParameters
사전은 협상된
코덱에 관한 정보를 제공한다.
RTCRtpCodec에서 상속한 필드는 반드시 모두 읽기 전용 매개변수여야 한다.
RTCRtpSender의 sdpFmtpLine 매개변수는
[[CurrentRemoteDescription]]
에서 가져오며,
RTCRtpReceiver의 경우 로컬
설명에서 가져온다. 로컬 설명은
[[PendingLocalDescription]]이
null이 아니면 그 값이고, 그렇지 않으면
[[CurrentLocalDescription]]이다.
payloadType of type octet, required
이 코덱을 식별하는 RTP 페이로드 유형이다. 읽기 전용 매개변수이다.
WebIDLdictionary RTCRtpCapabilities {
required sequence<RTCRtpCodec> codecs;
required sequence<RTCRtpHeaderExtensionCapability> headerExtensions;
};
RTCRtpCapabilities Members
codecs of type sequence<RTCRtpCodec>,
required
지원되는 미디어 코덱과 RTX, RED 및 FEC 메커니즘의 항목이다. 생성된 SDP 제안에서 서로 다른 페이로드 유형을 사용하는 조합만 제공해야 한다. 예를 들어:
반드시 codecs에는
RTX를 통한 재전송 항목이 하나만
있어야 하며, 그 항목에는 sdpFmtpLine이
없어야 한다.
headerExtensions of type sequence<RTCRtpHeaderExtensionCapability>,
required
지원되는 RTP 헤더 확장이다.
WebIDLdictionary RTCRtpHeaderExtensionCapability {
required DOMString uri;
};
RTCRtpHeaderExtensionCapability
Members
uri of type DOMString, required
[ RFC5285 ]에 정의된 RTP 헤더 확장의 URI이다.
WebIDLdictionary RTCSetParameterOptions {
};
RTCSetParameterOptions
MembersRTCSetParameterOptions는 확장 가능성을 허용하도록 빈 사전으로 정의된다.
RTCRtpReceiver
인터페이스는
애플리케이션이 MediaStreamTrack의 수신을 검사할 수 있도록 한다.
RTCRtpReceiver를 생성하는 절차를 문자열 kind으로 실행하려면 다음 단계를 실행한다:
receiver를 새 RTCRtpReceiver 객체로 둔다.
track을 새 MediaStreamTrack 객체로 둔다[
GETUSERMEDIA].
track의 소스는
원격
소스이며 receiver가
제공한다. track.id
는 사용자 에이전트가 생성하며 원격 측의
트랙 ID와는 대응하지 않는다.
track.kind를 kind로 초기화한다.
track.label을 문자열
"remote "와 kind을 이어 붙인 결과로 초기화한다.
track.readyState를 live로 초기화한다.
track.muted를 true로 초기화한다.
MediaStreamTrack
절에서 muted
속성이 MediaStreamTrack의 미디어 데이터 수신 여부를 어떻게 반영하는지
참조한다.
receiver에 [[ReceiverTrack]] 내부 슬롯을 두고 track로 초기화한다.
receiver에 [[ReceiverTransport]]
내부 슬롯을 두고 null로 초기화한다.
receiver에
[[LastStableStateReceiverTransport]] 내부
슬롯을 두고 null로 초기화한다.
receiver에
[[AssociatedRemoteMediaStreams]] 내부 슬롯을
둔다. 이는 MediaStream 객체의 목록을 나타내며, 이 수신자의
MediaStreamTrack 객체와 연결된 스트림들이다.
이 슬롯은
빈 목록으로 초기화한다.
receiver에 [[LastStableStateAssociatedRemoteMediaStreams]] 내부 슬롯을 두고 빈 목록으로 초기화한다.
receiver에 [[ReceiveCodecs]]
내부 슬롯을 둔다. 이 슬롯은 RTCRtpCodecParameters
사전의 목록을 나타내며 빈 목록으로 초기화한다.
receiver에 [[LastStableStateReceiveCodecs]] 내부 슬롯을 두고 빈 목록으로 초기화한다.
receiver에 [[JitterBufferTarget]]
내부 슬롯을 두고 null로 초기화한다.
receiver를 반환한다.
WebIDL[Exposed=Window]
interface RTCRtpReceiver {
readonly attribute MediaStreamTrack track;
readonly attribute RTCDtlsTransport? transport;
static RTCRtpCapabilities? getCapabilities(DOMString kind);
RTCRtpReceiveParameters getParameters();
sequence<RTCRtpContributingSource> getContributingSources();
sequence<RTCRtpSynchronizationSource> getSynchronizationSources();
Promise<RTCStatsReport> getStats();
attribute DOMHighResTimeStamp? jitterBufferTarget;
};
track of type
MediaStreamTrack, readonly
track 속성은
이
RTCRtpReceiver 객체
receiver와 연결된 트랙이다.
track.stop()은 되돌릴
수 없지만 복제본에는 영향을 주지 않는다.
receiver.track.stop()은
receiver를 암묵적으로
중지하지 않으므로 수신자 보고서를 계속 보낸다. 값을 가져올 때 이 속성은 반드시
[[ReceiverTrack]] 슬롯의 값을 반환해야 한다.
transport of type RTCDtlsTransport,
readonly, nullable
transport
속성은
수신자의 track에 대한
미디어를 RTP 패킷 형태로 받는 전송이다.
RTCDtlsTransport 객체가 생성되기
전에는 transport 속성이
null이다. 번들링을 사용하면 여러
RTCRtpReceiver 객체가
하나의 transport
를 공유하며 모두 같은 전송으로 RTP와 RTCP를 받는다.
값을
가져올 때 이 속성은 반드시
[[ReceiverTransport]]
슬롯의 값을 반환해야 한다.
jitterBufferTarget of type DOMHighResTimeStamp, nullable
이 속성을
사용하면 애플리케이션은 RTCRtpReceiver의 지터
버퍼에 보관할 미디어의 목표 지속 시간을 밀리초 단위로 지정할 수 있다. 이는
사용자 에이전트가 수행하는 버퍼링의
양에 영향을 주며, 다시
재전송과 패킷 손실 복구에 영향을 준다. 애플리케이션은 목표값을 변경하여 재생
지연과 네트워크 지터로 인해 오디오 또는 비디오 프레임이 부족해질 위험
사이의 균형을 제어할 수 있다.
사용자 에이전트는 반드시 허용되는 최소 목표와 허용되는 최대 목표를 가져야 한다. 이 값들은 사용자 에이전트 가 네트워크 상태와 메모리 제약에 따라 제공할 수 있거나 제공하려는 범위를 반영하며, 언제든지 변경될 수 있다.
이는 목표값이다. 그에 따른 지연 변화는 시간에
걸쳐 점진적으로 관찰할 수 있다. 수신자의 평균
지터 버퍼 지연은
jitterBufferDelay의
변화량을
jitterBufferEmittedCount의 변화량으로 나누어 측정할 수 있다.
DTX를 사용하더라도 평균 지연이 생길 것으로 예상된다. 예를 들어 DTX를 사용하며 무음 후에 패킷이 흐르기 시작하면, 목표값이 클수록 사용자 에이전트 가 이 패킷을 재생하는 대신 버퍼링하도록 영향을 줄 수 있다.
값을 가져올 때 이 속성은 반드시
[[JitterBufferTarget]]
내부 슬롯의 값을 반환해야 한다.
값을 설정할 때 사용자 에이전트는 반드시 다음 단계를 실행해야 한다:
receiver를 설정자가 호출된
RTCRtpReceiver
객체로 둔다.
target를 설정자의 인수로 둔다.
target이 음수이거나 4000밀리초보다 크면
예외를 던지는 절차로 RangeError를 던진다.
receiver의 [[JitterBufferTarget]]를
target으로 설정한다.
track을 receiver의
[[ReceiverTrack]]으로 둔다.
병렬로 다음 단계를 실행하기 시작한다:
기반 시스템에 새 target
을 알리거나, target이
null이면 애플리케이션의 선호가 없음을 알린다.
track이 다른
RTCRtpReceiver
의 트랙과
오디오/비디오
동기화
를 위해 동기화되어 있으면, 사용자
에이전트는 가급적 두
수신자의
[[JitterBufferTarget]]
중 더 큰 값을 두 수신자 모두에 사용해야 한다.
기반 시스템은 지터 버퍼 목표를 적용할 때 실제 지터 버퍼 목표가 허용되는 최소 목표와 허용되는 최대 목표 사이로 제한되도록 계속 보장한다.
사용자
에이전트가 결과적으로 요청된 값과
다른 목표를 사용하더라도(예: 네트워크 상태나 물리적
메모리 제약 때문에), 이는
[[JitterBufferTarget]]
내부 슬롯에 반영되지 않는다.
기반 시스템의 지터 버퍼 목표를 변경하면 가급적 사용자 경험을 해치지 않도록 내부 오디오 또는 비디오 버퍼링에 점진적으로 영향을 주어야 한다. 오디오 샘플이나 비디오 프레임은 가급적 재생 전에 가속하거나 감속해야 하며, 이는 오디오/비디오 동기화 또는 혼잡 제어에 대응할 때와 비슷한 방식으로 수행한다.
가속 또는 감속 속도는 네트워크 상태나 수신한 오디오의 종류(예: 음성 또는 배경 소음)에 따라 달라질 수 있다. 경우에 따라 1초 분량의 버퍼링을 달성하는 데 몇 초가 걸릴 수 있으나, 가급적 패킷을 수신하고 있다는 가정하에 30초를 넘기지 않아야 한다. 속도는 경우에 따라 오디오와 비디오에서 다를 수 있다.
오디오의
가속과 감속은
insertedSamplesForDeceleration와
removedSamplesForAcceleration
으로 측정할 수 있다. 비디오에서는 같은 프레임을 여러 번
렌더링하거나 프레임을 버리는 결과가 생길 수 있다.
getCapabilities, static
정적
RTCRtpReceiver.getCapabilities()
메서드는 리소스, 포트
또는 다른 상태를 예약하지 않고도 사용자 에이전트가 주어진 종류의
미디어를 받기 위해 지원하는 기능의 종류를 알아내는 방법을 제공한다.
getCapabilities
메서드가 호출되면 사용자 에이전트는 반드시 다음
단계를 실행해야 한다:
kind를 메서드의 첫 번째 인수로 둔다.
kind가 "video"도 "audio"도
아니면 null을 반환한다.
새 RTCRtpCapabilities
사전을 반환한다. 이때
codecs
멤버는
구현된 수신
코덱 목록 중 kind에 해당하는 목록으로 초기화하고,
headerExtensions
멤버는
구현된 수신용 헤더 확장 목록 중
kind에 해당하는 목록으로 초기화한다.
구현된 수신 코덱
목록은 주어진 kind에 대해
구현 정의 방식으로 정해지는
RTCRtpCodec
사전의
목록이며, 주어진
kind(비디오 또는 오디오)의 미디어를 받기 위해 사용자 에이전트가 지원하는 코덱을 가장 낙관적으로 나타낸다.
구현된 수신용 헤더 확장
목록은 주어진
kind에 대해 구현 정의
방식으로 정해지는
RTCRtpHeaderExtensionCapability
사전의
목록이며, 주어진
kind(비디오 또는 오디오)의 미디어를 받기 위해 사용자 에이전트가 지원하는 헤더 확장을 낙관적으로 나타낸다.
이러한
기능은 일반적으로 오래 유지되며 출처를 넘어 이용할
수 있는 장치 정보를 제공하므로 애플리케이션의
핑거프린팅 가능 범위를 늘린다. 개인정보 보호에
민감한 상황에서 사용자 에이전트는 경우에 따라 기능의
공통
부분집합만 보고하는 등의 완화 조치를 고려할 수 있다.
반환된
코덱 기능은
setCodecPreferences()
알고리즘과 이
알고리즘이 어떤 입력에 대해 InvalidModificationError를
던지는지에
영향을 준다. 개인정보 보호 완화 조치의 효과를 보장하려면, 이 정보는
createOffer()와
createAnswer()가
수신용으로
협상된 코덱에 관해 드러내는
정보와도 일관되어야 한다.
getParameters
getParameters()
메서드는 RTCRtpReceiver
객체의 현재 매개변수를 반환한다. 이는 track을 디코딩하는 방식에 관한 매개변수이다.
getParameters
가 호출되면
RTCRtpReceiveParameters
사전은 다음과 같이
구성된다:
headerExtensions
시퀀스는 수신자가
현재 수신할 준비가 된 헤더 확장을
바탕으로 채운다.
codecs
는
[[ReceiveCodecs]] 내부 슬롯의
값으로 설정한다.
getParameters입니다.
그러나
원격 엔드포인트가 둘만 포함해 응답하면, 빠진 코덱을 더
이상 반환하지 않는 메서드는 getParameters
입니다.
수신자가 그 코덱을 받을 준비를 할 필요가 없어졌기 때문입니다.
rtcp.reducedSize는
수신자가 현재 축소 크기 RTCP 패킷을 수신할 준비가 되어 있으면 true로,
그렇지 않으면
false로 설정한다.
rtcp.cname는
생략한다.
getContributingSources
RTCRtpContributingSource를
각 고유 CSRC 식별자에
대해 반환한다. 이는 이 RTCRtpReceiver가 직전
10초 동안 수신한 식별자이며, timestamp의
내림차순으로 반환한다.
getSynchronizationSources
RTCRtpSynchronizationSource를
각 고유 SSRC
식별자에 대해 반환한다. 이는 이 RTCRtpReceiver가
직전 10초 동안 수신한 식별자이며,
timestamp의
내림차순으로 반환한다.
getStats
이 수신자에 대해서만 통계를 수집하고 결과를 비동기적으로 보고한다.
getStats()
메서드가 호출되면 사용자 에이전트는
반드시 다음 단계를 실행해야 한다:
selector를 메서드가 호출된 RTCRtpReceiver
객체로 둔다.
p를 새 프로미스로 두고 다음 단계를 병렬로 실행한다:
selector가 나타내는 통계를 통계 선택 알고리즘에 따라 수집한다.
전역 태스크를 큐에 넣는다. 이 태스크의 소스는 네트워킹 태스크 소스이고,
현재 렐름의 전역 객체를
global로 사용한다. 태스크는 결정 절차로
p를 결정하며, 그 값은 수집한 통계를 포함하는 결과 RTCStatsReport
객체이다.
p를 반환한다.
RTCRtpContributingSource와
RTCRtpSynchronizationSource 사전은 각각
주어진 기여 소스(CSRC) 또는 동기화
소스(SSRC)의 정보를 포함한다. 하나 이상의 RTP
패킷에서 나온 오디오 또는 비디오 프레임이
RTCRtpReceiver의 MediaStreamTrack에 전달되면, 사용자 에이전트는 반드시
태스크를 큐에 넣어
RTCRtpContributingSource와 RTCRtpSynchronizationSource
사전의 관련 정보를 해당 패킷 내용에 따라
갱신해야 한다. RTCRtpSynchronizationSource
사전
중 SSRC 식별자에 대응하는 관련 정보는 매번
갱신되며, RTP 패킷에 CSRC 식별자가 포함되어 있으면
RTCRtpContributingSource 사전 중
해당 CSRC
식별자들에 대응하는 관련 정보도 갱신한다. 사용자 에이전트는 반드시 RTP
타임스탬프의 오름차순으로 RTP 패킷을 처리해야 한다. 사용자 에이전트는 반드시
직전 10초 동안
RTCRtpReceiver의 MediaStreamTrack에 전달된 RTP 패킷의 정보를 보관해야 한다.
MediaStreamTrack 이 재생을 위한 어떤 싱크에도 연결되지 않은
경우에도, getSynchronizationSources
및
getContributingSources
는 트랙이
아직 종료되지 않은 상태인 동안 최신 정보를 반환한다. 싱크는 RTP 패킷을 디코딩하기 위해서
반드시 있어야 하는 전제조건이 아니다.
RTCRtpSynchronizationSource 및
RTCRtpContributingSource
딕셔너리는 특정한 수신기 객체인
RTCRtpReceiver 에
대해서 RTP 스트림의 단일 시점에서 가져온 정보를 담아야
한다.
WebIDLdictionary RTCRtpContributingSource {
required DOMHighResTimeStamp timestamp;
required unsigned long source;
double audioLevel;
required unsigned long rtpTimestamp;
};
timestamp of type
DOMHighResTimeStamp, required
timestamp는
이 소스에서 발생한
RTP 패킷의 프레임이 가장
최근에 RTCRtpReceiver의 MediaStreamTrack에
전달된 시각을 나타낸다. timestamp
는 그 시점의 Performance.timeOrigin +
Performance.now()로 정의한다.
source of type unsigned long, required
기여 소스 또는 동기화 소스의 CSRC 또는 SSRC 식별자이다.
audioLevel of type double
오디오 수신자에만 존재한다. 이는 0..1 사이의 선형 값이며, 1.0은 0 dBov를, 0은 무음을, 0.5는 0 dBov에서 음압 수준이 약 6 dBSPL만큼 변한 것을 나타낸다.
CSRC의 경우 이 값은 반드시 RFC 6465 헤더 확장이 존재하면 [ RFC6465 ]에 정의된 레벨 값에서 변환해야 하고, 그렇지 않으면 이 멤버는 반드시 없어야 한다.
SSRC의 경우 이 값은 반드시 [ RFC6464 ]에 정의된 레벨 값에서 변환해야 한다. 수신한 패킷에 RFC 6464 헤더 확장이 없으면(예: 다른 끝점이 사용자 에이전트가 아니거나 레거시 끝점인 경우), 이 값은 가급적 없어야 한다.
두 RFC 모두 시스템이 인코딩할 수 있는 가장 큰 신호를 기준으로 음수 데시벨로 표현한 오디오 레벨을 0부터 127까지의 정수 값으로 정의한다. 따라서 0은 시스템이 인코딩할 수 있는 가장 큰 신호를 나타내고, 127은 무음을 나타낸다.
이
값들을 선형 0..1 범위로 변환하려면
127은 0으로 변환하고 다른 모든
값은 10^(-rfc_level/20) 식으로 변환한다.
rtpTimestamp of type unsigned long, required
[ RFC3550 ] 5.1절에 정의된 RTP 타임스탬프로서, timestamp 시점에 재생된 미디어에 해당한다.
WebIDLdictionary RTCRtpSynchronizationSource : RTCRtpContributingSource {};
RTCRtpSynchronizationSource
사전은 SSRC에서만 사용할 수 있는 데이터를 명세가 노출하기 위한 확장 지점으로 사용될
것으로 예상된다.
RTCRtpTransceiver 인터페이스는
RTCRtpSender와 RTCRtpReceiver가
공통의 미디어
스트림 "identification-tag"를 공유하는 조합을 나타낸다. [RFC9429] (section 3.4.1.)에 정의된 대로, RTCRtpTransceiver는 다음 조건을
만족할 때 연결된
상태로 간주된다. 그 대상은 미디어 설명이며,
조건은 "mid" 속성이 null이 아니고 미디어 스트림 "identification-tag"와 일치하는 것이다. 이 태그는 해당 미디어 설명에 있어야
한다. 그렇지 않으면 해당 미디어 설명과 연결 해제된 것으로 간주한다.
RTCRtpTransceiver는
현재 설명과는 계속
연결 해제된 상태인 채 RFC9429의 새 보류 중인
설명과 연결될 수 있다. 이는 협상이 필요한지 확인하는 절차에서 발생할 수 있다.
트랜시버 종류은 RTCRtpTransceiver
에 대해 연결된 RTCRtpReceiver의
MediaStreamTrack 객체의 종류로 정의된다.
RTCRtpTransceiver를 생성하는 절차를 RTCRtpReceiver
객체 receiver, RTCRtpSender 객체
sender 및 RTCRtpTransceiverDirection 값
direction으로 실행하려면 다음 단계를 실행한다:
transceiver를 새 RTCRtpTransceiver 객체로 둔다.
transceiver에 [[Sender]] 내부 슬롯을 두고 sender로 초기화한다.
transceiver에 [[Receiver]] 내부 슬롯을 두고 receiver로 초기화한다.
transceiver에 [[Stopping]]
내부 슬롯을 두고 false로 초기화한다.
transceiver에 [[Stopped]]
내부 슬롯을 두고 false로 초기화한다.
transceiver에 [[Direction]] 내부 슬롯을 두고 direction로 초기화한다.
transceiver에 [[Receptive]]
내부 슬롯을 두고 false로 초기화한다.
transceiver에
[[CurrentDirection]]
내부 슬롯을 두고
null로 초기화한다.
transceiver에 [[FiredDirection]]
내부 슬롯을 두고 null로 초기화한다.
transceiver에 [[PreferredCodecs]] 내부 슬롯을 두고 빈 목록으로 초기화한다.
transceiver에 [[JsepMid]]
내부 슬롯을 두고 null로
초기화한다. 이는 [RFC9429] (section 5.2.1. and section 5.3.1.)
에 정의된 "RtpTransceiver
mid property"이며 거기에서만 수정된다.
transceiver에 [[Mid]] 내부
슬롯을 두고 null로 초기화한다.
transceiver를 반환한다.
RTCDtlsTransport 및 RTCIceTransport 객체. 이러한 객체들은 세션
설명을 설정하는 과정의 일부로만 생성된다. 해당 과정은 세션 설명 설정 처리.
WebIDL[Exposed=Window]
interface RTCRtpTransceiver {
readonly attribute DOMString? mid;
[SameObject] readonly attribute RTCRtpSender sender;
[SameObject] readonly attribute RTCRtpReceiver receiver;
attribute RTCRtpTransceiverDirection direction;
readonly attribute RTCRtpTransceiverDirection? currentDirection;
undefined stop();
undefined setCodecPreferences(sequence<RTCRtpCodec> codecs);
};
mid of type DOMString, readonly, nullable
mid 속성은 협상되어 로컬 및 원격 설명에 존재하는 미디어
스트림 "identification-tag"이다. 값을
가져올 때 이 속성은 반드시
[[Mid]] 슬롯의 값을 반환해야 한다.
sender of type RTCRtpSender, readonly
sender
속성은 RTCRtpSender를
노출하며, 이는 mid =
[[Mid]]로 보낼 수 있는 RTP 미디어에 대응한다. 값을 가져올 때 이 속성은 반드시
[[Sender]] 슬롯의 값을 반환해야 한다.
receiver of type RTCRtpReceiver, readonly
receiver 속성은
RTCRtpReceiver이며,
이는 mid =
[[Mid]]로 받을 수 있는 RTP 미디어에 대응한다. 값을 가져올 때 이 속성은 반드시
[[Receiver]] 슬롯의 값을 반환해야 한다.
direction of type RTCRtpTransceiverDirection
[RFC9429]
(section
4.2.4.)에 정의된 대로,
direction 속성은 이
트랜시버의 선호 방향을 나타내며,
createOffer와
createAnswer
호출에
사용된다. 방향을 갱신해도 즉시 적용되지는 않는다.
대신 이후의 createOffer와
createAnswer
호출은 대응하는 미디어 설명을
sendrecv,
sendonly, recvonly 또는 inactive
로 표시한다. 이는 [RFC9429]
(section 5.2.2.
and section
5.3.2.)에 정의되어 있다.
값을 가져올 때 사용자 에이전트는 반드시 다음 단계를 실행해야 한다:
transceiver를 getter가 호출된 RTCRtpTransceiver
객체로 둔다.
transceiver.[[Stopping]]가
true이면 "
stopped"을 반환한다.
그렇지
않으면 [[Direction]]
슬롯의 값을 반환한다.
값을 설정할 때 사용자 에이전트는 반드시 다음 단계를 실행해야 한다:
transceiver를 설정자가 호출된 RTCRtpTransceiver
객체로 둔다.
connection를 RTCPeerConnection
객체로 두며, 이 객체는 transceiver와 연결되어 있다.
transceiver.[[Stopping]]가
true이면 예외를 던지는 절차로
InvalidStateError를 던진다.
newDirection를 설정자의 인수로 둔다.
newDirection이
transceiver.[[Direction]]와 같으면 이
단계들을 중단한다.
transceiver.[[Direction]]를
newDirection로 설정한다.
협상 필요 플래그를 갱신하는 절차를 connection에 대해 실행한다.
currentDirection of type RTCRtpTransceiverDirection,
readonly,
nullable
[RFC9429]
(section
4.2.5.)에 정의된 대로,
currentDirection 속성은 이 트랜시버에
대해 현재 협상된 방향을 나타낸다.
currentDirection의 값은
RTCRtpEncodingParameters.active의
값과 독립적이며, 한쪽에서 다른 쪽을 추론할 수
없다. 이 트랜시버가 제안/응답 교환에 한 번도 나타나지
않았으면 값은 null이다. 트랜시버가
stopped 상태이면 값은
"stopped"이다.
값을 가져올 때 사용자 에이전트는 반드시 다음 단계를 실행해야 한다:
transceiver를 getter가 호출된 RTCRtpTransceiver
객체로 둔다.
transceiver.[[Stopped]]가
true이면 "
stopped"을 반환한다.
그렇지
않으면
[[CurrentDirection]]
슬롯의 값을 반환한다.
stop
트랜시버를
stopping 상태로 되돌릴 수 없게
표시한다. 단, 이미 stopped 상태이면 수행하지 않는다. 이로
인해 트랜시버의 송신자는 즉시 전송을 중단하고 수신자는
즉시 수신을 중단한다. stop() 호출은
협상
필요 플래그를 갱신하는 절차도 수행하며, 그 대상은 RTCRtpTransceiver
와 연결된
RTCPeerConnection이다.
중지 중 상태인 트랜시버가 있으면 이후의
createOffer
호출은 대응하는
트랜시버의 미디어 설명
에서 포트를
0으로 생성한다. 이는 [RFC9429]
(section
4.2.1.)에 정의되어 있다(사용자 에이전트는 반드시 이 경우에만 RFC9429의 목적상
stopping
상태인 트랜시버를 stopped 상태로
취급해야 한다). 그러나 [
RFC8843
]와 관련된 문제를 피하기 위해, stopping 상태이지만
stopped 상태가 아닌
트랜시버는
createAnswer에 영향을 주지 않는다.
중지됨 상태인 트랜시버가 있으면 이후
createOffer 또는
createAnswer
호출은 대응하는
트랜시버의 미디어 설명
에서 포트를
0으로 생성한다. 이는 [RFC9429]
(section
4.2.1.)에 정의되어 있다.
트랜시버는
stopping 상태를 유지한다.
단, stopped 상태가 되면 그렇지 않으며, 이는
setRemoteDescription가
원격 제안
또는 응답에서 거부된 m행을 처리한 결과이다.
stopping 상태이지만 stopped 상태가
아닌 트랜시버에는 항상 협상이 필요하다. 실제로 이는 트랜시버에서
stop()을
호출하면, 양쪽 끝에서 협상이 완료되도록 허용되는 한 해당 트랜시버가 결국
stopped 상태가
된다는
뜻이다.
stop 메서드가 호출되면
사용자 에이전트는 반드시 다음
단계를 실행해야 한다:
transceiver를 메서드가 호출된 RTCRtpTransceiver
객체로 둔다.
connection를 RTCPeerConnection
객체로 두며, 이 객체는 transceiver와 연결되어 있다.
connection.[[IsClosed]]가
true이면 예외를 던지는 절차로
InvalidStateError를 던진다.
transceiver.[[Stopping]]가
true이면 이 단계들을 중단한다.
송수신을 중단하는 절차를 transceiver로 실행한다.
협상 필요 플래그를 갱신하는 절차를 connection에 대해 실행한다.
송수신을 중단하는 알고리즘은
transceiver 및 선택적인 불리언
disappear를 입력으로 받으며 기본값은
false이다. 알고리즘은 다음과 같다:
sender를
transceiver.[[Sender]]로 둔다.
receiver를
transceiver.[[Receiver]]로 둔다.
병렬로 sender 의 미디어 전송을 중단하고 sender가 보내던 각 RTP 스트림에 대해 [ RFC3550 ]에 지정된 대로 RTCP BYE를 보낸다.
병렬로 receiver의 미디어 수신을 중단한다.
disappear가 false
이면
receiver.[[ReceiverTrack]]을
종료된
상태로 만드는
단계를 실행한다. 이로 인해 이벤트가 발생한다.
transceiver.[[Direction]]를
"inactive"로 설정한다.
transceiver.[[Stopping]]를
true로 설정한다.
RTCRtpTransceiver를 중지하는 알고리즘은
transceiver 및 선택적인 불리언
disappear를 입력으로 받으며 기본값은
false이다. 알고리즘은 다음과 같다:
transceiver.[[Stopping]]이
false이면 송수신을 중단하는
절차를
transceiver와 disappear로 실행한다.
transceiver.[[Stopped]]를
true로 설정한다.
transceiver.[[Receptive]]를
false로 설정한다.
transceiver.[[CurrentDirection]]를
null로 설정한다.
setCodecPreferences
setCodecPreferences
메서드는 사용자 에이전트가 사용하는 협상
입력용 기본 코덱 선호를 재정의한다.
세션 설명을 생성할 때
사용하는 메서드가
createOffer
또는
createAnswer
이면, 사용자 에이전트는
반드시
반드시
지정된
코덱을 선호 코덱을 direction에
따라 필터링해야 하며 그 결과가 비어 있지 않은 목록이면 반드시
지정된 코덱을
codecs
인수의 순서대로, 미디어 섹션
섹션 중 이 이
RTCRtpTransceiver에 대응하는 섹션에서 사용해야 한다.
이
메서드는 특정 코덱(RTX/RED/FEC 포함)의 협상을 비활성화할
수 있게 한다.
또한 원격 피어가
목록의 첫 번째 코덱을 선호하도록 할 수 있으며, 그
용도는 다음과 같다. 이를 위해
모든 코덱을 나열하되
다음은 제외한다: 송신비활성화할 코덱.
m= 섹션을 수신에 사용하면 SDP(제안과 응답 모두)에 나열된 코덱의 순서는 로컬 끝점이 어떤 코덱으로 수신하기를 선호하는지 원격 끝점에 알려 준다. m= 섹션을 수신에 사용하지 않더라도, 자체적인 코덱 선호가 없는 응답자는 기본적으로 SDP 응답에 같은 순서를 사용한다.
RTCRtpSender는
기본적으로 원격
끝점이 수신하기를 선호한다고 나타낸
코덱으로 보내지만, 애플리케이션은 협상된
codecs 중에서 송신할
코덱을 변경할 수 있다. 이를 위해
setParameters를
호출하여 송신할
codec을
지정한다.
RTCRtpReceiver
는 협상된 모든 코덱을 수신할 준비가
되어 있다.
코덱
선호는
createOffer와
createAnswer
중 이
RTCRtpTransceiver를
포함하는 모든 호출에 대해 이 메서드를 다시 호출할
때까지 유지된다. codecs를 빈 시퀀스로
설정하면
코덱 선호가 시퀀스
또는 direction에
따라 필터링한 뒤 비게
되는 시퀀스로 설정하면 기본 값으로 재설정된다코덱 선호가 적용된다.
코덱의
페이로드 유형은 SDP의 각 m= 섹션
아래에 나열되어 페이로드 유형과 코덱
사이의 매핑을 정의한다. 이 페이로드 유형은
m=video 또는 m=audio 행에서 선호 순서대로
참조되며, 협상되지 않은 코덱은 [
RFC8829RFC9429
] 5.2.1절에 정의된 대로
이 목록에 나타나지 않는다. 이전에 협상되었다가 제거된 코덱은
m=video 또는 m=audio 행에서 사라진다. 해당 코덱 페이로드
유형은 이후 제안이나 응답에서 재사용해서는 안 되며, 그
페이로드 유형을 SDP의 페이로드 유형 매핑에서도 제거할 수 있다.
codecs 시퀀스를 입력으로 받는
setCodecPreferences
는 이 시퀀스에 다음 코덱만 허용한다. 는
codecs를 설정할 때 다음 코덱과 일치하지
않는 입력을 거부한다.
해당 코덱을 반환하는
API는 다음과 같다:
비교할 코덱은 다음 API 중 하나에 있는 항목이다:
RTCRtpSender.getCapabilities(kind)
또는
RTCRtpReceiver.getCapabilities(kind).
여기서 kind는
RTCRtpTransceiver
의 종류이며, 이 객체에서 메서드가 호출된다. 또한
사전
멤버는 수정할 수 없다. codecs가
이 요건을 충족하지 않으면 사용자 에이전트는 반드시 예외를 던지는 절차로 RTCRtpCodecCapabilityInvalidModificationError를 던져야 한다.
[
SDP]의
권고에 따라
호출은
가급적 코덱 선호
목록과 제안에 나타난 코덱의 공통 부분집합만 사용해야 한다.
예를 들어 코덱 선호가 "C, B, A"이지만
"A, B" 코덱만 제안되었다면 응답에는 "B, A"
코덱만 포함하는 것이 좋다. 그러나 [RFC8829]
(section
5.3.1.)은 제안에 없던 코덱을
추가하는 것을 허용하므로 구현에 따라 다르게 동작할 수
있다.
createAnswer
setCodecPreferences()
가 호출되면 사용자
에이전트는 반드시 다음 단계를 실행해야 한다:
transceiver를 이 메서드가 호출된 RTCRtpTransceiver
객체로 둔다.
codecs를 첫 번째 인수로 둔다.
codecs가 빈 목록이면
transceiver.[[PreferredCodecs]]를
codecs로 설정하고 이 단계들을 중단한다.
codecs에서 중복 값을 모두 제거한다. 코덱의 우선순위를 유지하도록 목록의 뒤에서부터 시작한다. 목록에서 코덱이 처음 나타나는 인덱스는 이 단계 전후에 동일하다.
중복된 값을 codecs에서 제거하되 각 값이 처음 나타나는 위치는 유지하도록 한다.
kind를 transceiver의 트랜시버 종류로 둔다.
codecs와
.RTCRtpSendergetCapabilities(kind).codecs의
교집합 또는 codecs와
RTCRtpReceiver.getCapabilities(kind).codecs의
교집합이 RTX, RED 또는 FEC 코덱만 포함하거나 공집합이면
InvalidModificationError
를
던진다. 이로써
transceiver.과 관계없이 항상 제안할 항목이 있도록 보장한다.
direction
codecCapabilities를
RTCRtpSender.getCapabilities(kind).codecs와
RTCRtpReceiver.getCapabilities(kind).codecs의 합집합으로 둔다.
각 codec에 대해, codecs에 속하는 항목마다 다음을 수행한다:
InvalidModificationError를 던진다.
각 codec에 대해, codecs에 속하는 항목마다 다음을 수행한다:
codec의 불일치
조건이 codecCapabilities의 모든 코덱에 대해 성립하면 InvalidModificationError를 던진다.
codecs가 RTX, RED, FEC 또는
Comfort Noise 항목만 포함하거나
공집합이면 InvalidModificationError
를
던진다. 이로써
transceiver.direction과 관계없이 항상 제안할 항목이 있도록 보장한다.
transceiver.[[PreferredCodecs]]를
codecs로 설정한다.
코덱 사전 일치
알고리즘은 두
RTCRtpCodec 사전
first와 second 및
불리언 ignoreLevels를 입력으로 받는다. 이 불리언은 지정되지 않으면 기본값이 false이다.
알고리즘은 다음과 같다:
first.mimeType가
ASCII 대소문자 비구분 비교로
second.mimeType와 일치하지 않으면
false를 반환한다.
first.channels와
second.channels 중 한쪽만 누락
상태이거나, 둘 다 존재하고 first.channels가
second.channels와 다르면
false를 반환한다.
first.sdpFmtpLine와
second.sdpFmtpLine 중 한쪽만
누락
상태이면 false를 반환한다.
first.sdpFmtpLine와
second.sdpFmtpLine가 모두 존재하면 다음 단계를
실행한다:
first.sdpFmtpLine와
second.sdpFmtpLine
중 하나라도
키-값 형식이 아니면
first.sdpFmtpLine와
second.sdpFmtpLine의 동등 비교 결과를 반환한다.
firstMediaFormat을
first.sdpFmtpLine에서 구성한
미디어 형식의 키-값 맵으로 두고, secondMediaFormat을
second.sdpFmtpLine에서 구성한 미디어 형식의 키-값 맵으로 둔다.
어떤 FMTP 매개변수가 미디어 형식을 구성하는지는 코덱에 따라 다르다. 경우에 따라 매개변수를 생략해도 추론할 수 있으며, 이때 해당 매개변수도 그 코덱의 미디어 형식에 포함된다.
firstMediaFormat이
secondMediaFormat과 같지 않으면
false를 반환한다.
ignoreLevels가 false
이고 first.sdpFmtpLine와
second.sdpFmtpLine에서
추론한 최대 적합 비트스트림 레벨이 다르면 false를 반환한다.
ignoreLevels가 true
이어도 일부 코덱(예: H.264)은
미디어 형식에 레벨을 포함하므로, 레벨을 무시하려면
코덱별 파싱이 필요하다.
true를 반환한다.
설정되어 있으면 제안자의 수신 코덱 선호가 제안에 나열되는 코덱의 순서를 결정한다. 응답자에게 코덱 선호가 없으면 응답에도 같은 순서를 사용한다. 그러나 응답자에게도 코덱 선호가 있으면 그 선호가 응답의 순서를 재정의한다. 이 경우 제안자의 선호는 어떤 코덱을 제안하는지에는 영향을 주지만 최종 순서에는 영향을 주지 않는다.
동시
송출 기능은
addTransceiver
메서드의
sendEncodings
인수 또는 동시 송출을 수신하겠다는 원격 제안을 사용하는
setRemoteDescription
메서드로
활성화한다. 두 메서드는 모두
RTCPeerConnection 객체의
메서드이다. 또한
각 setParameters 메서드를 해당
RTCRtpSender
객체에서 사용하여 이 기능을 확인하고 수정할 수 있다.
RTCRtpSender의 동시 송출 엔벌로프
는 해당 송신자가 유니캐스트 대신 동시 송출을
수행하는 최초의 성공적인 협상에서 설정된다. 여기에는 보낼
수 있는 동시 송출 스트림의 최대 수와
encodings의 순서가 포함된다. 이 동시 송출 엔벌로프는
이후 재협상에서 좁힐 수 있지만(계층 수를
줄임), 다시 넓힐 수는 없다. 개별
동시 송출 스트림의 특성은
setParameters 메서드로 수정할 수
있지만 동시 송출 엔벌로프
자체는 이 메서드로 변경할 수 없다.
동시
송출을 구성하는 한 가지 방법은
sendEncodings 옵션을
addTransceiver()
에 사용하는 것이다. addTrack()
메서드에는 동시 송출 구성에 필요한
sendEncodings
인수가 없지만,
사용자 에이전트가 응답자이면 송신자를
동시 송출로 승격할 수 있다.
setRemoteDescription
메서드를 동시 송출을
수신하겠다는 원격 제안으로 호출하면, 제안된 엔벌로프
를 RTCRtpSender에 구성하여
지정된 세션 설명의 계층들을 포함시킨다. 이
설명이 롤백되지 않는 한 제안된 엔벌로프는 협상이 완료될
때 RTCRtpSender의 동시 송출 엔벌로프가 된다.
앞서 설명한 대로 이 동시 송출 엔벌로프는
이후
재협상에서 좁힐 수 있지만 다시 넓힐 수는 없다.
setParameters
는 동시 송출
동시 송출 엔벌로프를 변경할 수 없지만,,
보내는 스트림의 수와 해당
스트림들의 특성은 여전히 제어할 수 있다.
setParameters를
사용하여 동시
송출 스트림의 active 멤버를
false로 설정하면 비활성화할 수 있고,
active 멤버를
true로 설정하면 다시 활성화할 수 있다.
[
RFC7728](RTP 일시 중지/재개)는 지원하지
않으며, SDP 제안/응답을 통한
일시 중지/재개 시그널링도 지원하지 않는다.
setParameters를
사용하여 스트림의 특성을
변경할 수 있으며, 이를 위해
maxBitrate 같은 속성을 수정한다.
동시
송출은 여러 인코딩을 SFU에 보내는 데 자주 사용되며,
SFU는 그중 하나의 동시 송출 스트림을 최종 사용자에게
전달한다. 따라서 사용자 에이전트는 모든 동시 송출 스트림이
각각 독립적으로 사용 가능하도록 인코딩 간에 대역폭을 할당할
것으로 예상된다. 예를 들어 두 동시 송출 스트림의
maxBitrate가
같다면 두
스트림의 비트레이트도 비슷할 것으로 예상된다. 모든 동시 송출
스트림을 사용 가능한 형태로 보내기에 대역폭이 부족하면, 사용자 에이전트는
일부 동시 송출 스트림의 전송을 중단할 것으로 예상된다.
[RFC9429] (section 3.7.)
에 정의된 대로, 사용자
에이전트의 제안은 a=simulcast
행에 "send" 설명만 포함하고 "recv" 설명은 포함하지 않는다. 대안과 제한([
RFC8853
]에 설명됨)은 지원하지 않는다.
이
명세는
createOffer,
createAnswer 또는
addTransceiver로 여러 RTP 인코딩의 수신을 구성하는 방법을
정의하지 않는다. 그러나
setRemoteDescription
이
[RFC9429]에 정의된 대로
여러 RTP 인코딩을 보낼 수
있는 대응하는 원격 설명으로 호출되고 브라우저가 여러 RTP 인코딩의 수신을 지원하면, RTCRtpReceiver
는 여러 RTP 인코딩을 수신할 수
있으며 트랜시버의
receiver.getParameters()로
가져온 매개변수는 협상된 인코딩을 반영한다.
RTCRtpReceiver는 선택적 전달
장치(SFU)가
사용자 에이전트에서 받은 동시 송출 스트림을 전환하는 상황에서
여러 RTP 스트림을 수신할 수 있다. SFU가 전달
전에 전환된 스트림들을 하나의 RTP 스트림으로 정리하도록
RTP 헤더를 다시 쓰지 않으면, RTCRtpReceiver는
각각 자체 SSRC와 시퀀스 번호 공간을 가진 서로 다른 RTP
스트림의 패킷을 받는다. SFU는 어느 시점에서든 하나의 RTP 스트림만 전달할
수 있지만, 순서가 바뀌면서 여러 RTP 스트림의 패킷이 수신자에서 뒤섞일
수 있다. 따라서 여러 RTP 스트림을 수신할 수 있는
RTCRtpReceiver는 받은
패킷을 올바른
순서로 정렬하고 잠재적인 손실 사건을 인식하여
대응할 수 있어야 한다. 이
상황에서 올바르게 동작하는 것은 간단하지 않으므로
이 명세의 구현에서 선택 사항이다.
이 절은 비규범적이다.
인코딩 매개변수로 구현한 동시 송출 시나리오의 예:
// Example of 3-layer spatial simulcast with all but the lowest resolution layer disabled
var encodings = [
{rid: 'q', active: true, scaleResolutionDownBy: 4.0}
{rid: 'h', active: false, scaleResolutionDownBy: 2.0},
{rid: 'f', active: false},
];
이 절은 비규범적이다.
direction 속성과
replaceTrack 메서드를 함께
사용하면 개발자가 "보류" 시나리오를
구현할 수 있다.
피어에게 음악을 보내고 수신한 오디오의 렌더링을 중단하려면(통화 보류 음악):
async function playMusicOnHold() {
try {
// Assume we have an audio transceiver and a music track named musicTrack
await audio.sender.replaceTrack(musicTrack);
// Mute received audio
audio.receiver.track.enabled = false;
// Set the direction to send-only (requires negotiation)
audio.direction = 'sendonly';
} catch (err) {
console.error(err);
}
}
원격 피어의 "sendonly" 제안에 응답하려면:
async function handleSendonlyOffer() {
try {
// Apply the sendonly offer first,
// to ensure the receiver is ready for ICE candidates.
await pc.setRemoteDescription(sendonlyOffer);
// Stop sending audio
await audio.sender.replaceTrack(null);
// Align our direction to avoid further negotiation
audio.direction = 'recvonly';
// Call createAnswer and send a recvonly answer
await doAnswer();
} catch (err) {
// handle signaling error
}
}
음악 전송을 중단하고 마이크에서 캡처한 오디오를 보내며 수신한 오디오도 렌더링하려면:
async function stopOnHoldMusic() {
// Assume we have an audio transceiver and a microphone track named micTrack
await audio.sender.replaceTrack(micTrack);
// Unmute received audio
audio.receiver.track.enabled = true;
// Set the direction to sendrecv (requires negotiation)
audio.direction = 'sendrecv';
}
원격 피어가 통화 보류를 해제한 것에 응답하려면:
async function onOffHold() {
try {
// Apply the sendrecv offer first, to ensure receiver is ready for ICE candidates.
await pc.setRemoteDescription(sendrecvOffer);
// Start sending audio
await audio.sender.replaceTrack(micTrack);
// Set the direction sendrecv (just in time for the answer)
audio.direction = 'sendrecv';
// Call createAnswer and send a sendrecv answer
await doAnswer();
} catch (err) {
// handle signaling error
}
}
RTCDtlsTransport
인터페이스는
RTCRtpSender와 RTCRtpReceiver 객체가 RTP
및 RTCP 패킷을
보내고 받으며, 데이터 채널의 SCTP 패킷 같은 다른 데이터도 보내고 받는 데이터그램 전송
계층 보안(DTLS) 전송에 관한 정보에 애플리케이션이 접근할 수 있도록 한다. 특히 DTLS는 기반 전송에 보안을 추가하며,
RTCDtlsTransport 인터페이스는
기반 전송과 추가된 보안에 관한
정보에 접근할 수 있도록 한다. RTCDtlsTransport
객체는
setLocalDescription()과
setRemoteDescription() 호출의
결과로 생성된다. 각
RTCDtlsTransport
객체는 RTP 또는
RTCP component의 DTLS
전송 계층을 나타낸다. 이는 특정
RTCRtpTransceiver에
속하거나, 여러 RTCRtpTransceiver의
그룹이 [RFC8843]을 통해 협상되었다면 그 그룹에 속한다.
RTCRtpTransceiver 에 대한
연결을 표현하는 객체는 기존 RTCDtlsTransport 객체이며, 해당
state 는 그 연결에 따라 갱신되며,
이때 새
객체를 만들어 연결을 표현하는 것은 아니다.
RTCDtlsTransport에는 [[DtlsTransportState]]
내부 슬롯이 있으며 "new"로 초기화한다. 또한
[[RemoteCertificates]] 슬롯이
있으며 빈 목록으로 초기화한다.
기반 DTLS 전송에서 인증서 검증 실패나 치명적 경고([RFC5246 ] 7.2절 참조) 같은 오류가 발생하면, 사용자 에이전트는 반드시 다음 단계를 실행하는 태스크를 큐에 넣어야 한다:
transport를 상태 갱신과 오류 알림을 받을 RTCDtlsTransport
객체로 둔다.
transport의 상태가 이미 "
failed"이면 이 단계들을 중단한다.
transport.[[DtlsTransportState]]를
"failed"로 설정한다.
이벤트를 발생시킨다. 이름은 error이며
RTCErrorEvent
인터페이스를 사용하고, errorDetail 속성은 적절하게
"dtls-failure" 또는
"fingerprint-failure
"로
설정한다. 다른 필드는 RTCErrorDetailType
열거형의 설명에 지정된 대로 설정하며, 이벤트의 대상은 transport이다.
이벤트를 발생시킨다. 이름은 statechange이며 대상은
transport이다.
다른
이유로 기반 DTLS 전송이 대응하는
RTCDtlsTransport 객체의 상태를 갱신해야 하면,
사용자 에이전트는 반드시 다음 단계를 실행하는 태스크를 큐에 넣어야 한다:
transport를 상태 갱신을 받을 RTCDtlsTransport 객체로
둔다.
newState를 새 상태로 둔다.
transport.[[DtlsTransportState]]를
newState로 설정한다.
newState가 connected이면
newRemoteCertificates를 원격
측에서 사용하는 인증서 체인으로 둔다. 각 인증서는
이진 Distinguished Encoding Rules(DER)[X690]로
인코딩한다. 그리고
transport.[[RemoteCertificates]]를
newRemoteCertificates로 설정한다.
이벤트를 발생시킨다. 이름은 statechange이며 대상은
transport이다.
WebIDL[Exposed=Window]
interface RTCDtlsTransport : EventTarget {
[SameObject] readonly attribute RTCIceTransport iceTransport;
readonly attribute RTCDtlsTransportState state;
sequence<ArrayBuffer> getRemoteCertificates();
attribute EventHandler onstatechange;
attribute EventHandler onerror;
};
iceTransport of type RTCIceTransport,
readonly
iceTransport
속성은 패킷을 보내고
받는 데 사용하는 기반 전송이다.
기반 전송은 여러 활성
RTCDtlsTransport 객체 사이에서 공유될 수 없다.
state of type RTCDtlsTransportState,
readonly
state 속성은 반드시 값을 가져올 때
[[DtlsTransportState]] 슬롯의 값을 반환해야 한다.
onstatechange of type EventHandler
statechange이다.
onerror of type EventHandler
error이다.
getRemoteCertificates
[[RemoteCertificates]]의 값을 반환한다.
WebIDLenum RTCDtlsTransportState {
"new",
"connecting",
"connected",
"closed",
"failed"
};
| Enum value | Description |
|---|---|
new
|
DTLS has not started negotiating yet. |
connecting
|
DTLS는 보안 연결을 협상하는 과정에 있으며 원격 측의 지문을 검증하는 절차도 진행 하고 있는 상태이다. |
connected
|
DTLS는 보안 연결 을 위한 협상 을 완료하였으며 원격 측의 지문도 검증한 상태이다. |
closed
|
전송은 close_notify 경고 를 수신한 결과 또는 다음 메서드 를
호출한 결과 로 의도적 으로 닫힌 상태이다:
close().
|
failed
|
전송은 오류 때문 에 실패한 상태이다. 예를 들면 오류 경고 를 수신한 경우나 원격 측의 지문 을 검증하지 못한 경우 가 이에 해당 한다. |
RTCDtlsFingerprint
사전은 [ RFC4572 ]에 설명된 해시 함수 알고리즘과 인증서 지문을 포함한다.
WebIDLdictionary RTCDtlsFingerprint {
DOMString algorithm;
DOMString value;
};
algorithm of type DOMString
'Hash function Textual Names' 레지스트리 [ IANA-HASH-FUNCTION ]에 정의된 해시 함수 알고리즘 중 하나이다.
value of type DOMString
[ RFC4572 ] 5절의 'fingerprint' 문법을 사용하여 표현한 소문자 16진수 문자열 형식의 인증서 지문 값이다.
RTCIceTransport 인터페이스는
패킷을 보내고 받는
ICE 전송에 관한 정보에 애플리케이션이 접근할 수
있도록 한다. 특히 ICE는 애플리케이션이 접근하려는 상태를
포함하는 피어 간 연결을 관리한다.
RTCIceTransport
객체는
setLocalDescription()과
setRemoteDescription()
호출의 결과로 생성된다.
기반 ICE 상태는 ICE 에이전트가 관리한다. 따라서
RTCIceTransport의 상태는
아래에 설명된 대로 ICE 에이전트가
사용자 에이전트에 알림을 제공할 때 바뀐다. 각
RTCIceTransport
객체는 RTP 또는
RTCP component의 ICE
전송 계층을 나타낸다. 이는 특정
RTCRtpTransceiver에
속하거나, 여러 RTCRtpTransceiver의
그룹이 [RFC8843]을 통해 협상되었다면 그 그룹에 속한다.
RTCRtpTransceiver 에 대한
재시작을 표현하는 객체는 기존 RTCIceTransport 객체이며, 해당
state 는 그 재시작에 따라 갱신되며,
이때 새
객체를 만들어 재시작을 표현하는 것은 아니다.
ICE 에이전트가 후보 세대의 수집을 시작했다고 알리고 그 대상이 RTCIceTransport transport(연결된
객체: RTCPeerConnection
connection)이면, 사용자
에이전트는 반드시 다음 단계를 실행하는 태스크를 큐에 넣어야 한다:
connection를 이 객체와 연결된
객체로
둔다. 이때 이 객체는 ICE 에이전트이다.
RTCPeerConnection
connection.[[IsClosed]]가
true이면 이 단계들을 중단한다.
transport를 후보 수집이 시작된 로
둔다.
RTCIceTransport
transport.[[IceGathererState]]를
gathering로 설정한다.
.
connection.[[IceGatheringState]]를
RTCIceGatheringState 열거형의 설명에 따라 새 상태 값을 도출한 값으로 설정한다.
connectionIceGatheringStateChanged를
true로 두되, 이는
connection.[[IceGatheringState]]가
이전 단계에서 바뀐 경우이다. 그렇지 않으면 false로 둔다.
이 지점 이후에는 상태를 읽거나 변경하지 않는다.
이벤트를 발생시킨다. 이름은 gatheringstatechange이며
대상은
transport이다.
ICE 수집 상태를 갱신하는 절차를 connection에 대해 수행한다.
connectionIceGatheringStateChanged가
true이면 이벤트를 발생시키는. 이름은
icegatheringstatechange이며
대상은 connection이다.
ICE 에이전트가 후보 세대의
수집을 완료하고 그 대상이 RTCIceTransport transport(연결된
객체: RTCPeerConnection
connection)이며 해당 후보들이
애플리케이션에 노출되었으면, 사용자 에이전트는 반드시
다음 다음
단계를 실행하는 태스크를 큐에 넣어야 한다:
connection를 이 객체와 연결된
객체로
둔다. 이때 이 객체는 ICE 에이전트이다.
RTCPeerConnection
connection.[[IsClosed]]가
true이면 이 단계들을 중단한다.
transport를 후보 수집이 완료된 로
둔다.
RTCIceTransport
connection.[[PendingLocalDescription]]가
null이 아니고 수집이 완료된 ICE 세대를
나타내면,
a=end-of-candidates를
connection.[[PendingLocalDescription]].sdp에 추가한다.
connection.[[CurrentLocalDescription]]가
null이 아니고 수집이 완료된 ICE 세대를
나타내면,
a=end-of-candidates를
connection.[[CurrentLocalDescription]].sdp에 추가한다.
newCandidateendOfGatheringCandidate를
RTCIceCandidate를 생성하는 절차의 결과로
둔다. 이때 새 사전의
sdpMid와
sdpMLineIndex는
다음 객체와 연결된 값으로
설정한다: 이 RTCIceTransport.
usernameFragment
는 후보
수집을 완료한 세대의 사용자
이름
조각으로 설정하고, candidate는
빈 문자열""로 설정한다.
이벤트를 발생시킨다. 이름은 icecandidate이고
RTCPeerConnectionIceEvent
인터페이스를 사용하며 candidate
속성은 newCandidateendOfGatheringCandidate로 설정한다. 대상은
connection이다.
다른 세대의 후보를 아직 수집 중이면 이 단계들을 중단한다.
transport.[[IceGathererState]]를
로 설정한다.
complete
이벤트를 발생시킨다. 이름은 이며
대상은
transport이다.
gatheringstatechange
ICE 수집 상태를 갱신하는 절차를 connection에 대해 수행한다.
ICE 에이전트가 위의 태스크를 큐에 넣었고 다른 세대의 후보를 수집하고 있지 않으면, 사용자 에이전트는 반드시 다음 단계를 실행하는 두 번째 태스크도 큐에 넣어야 한다:
connection.[[IsClosed]]가
true이면 이 단계들을 중단한다.
transport.[[IceGathererState]]를
complete로 설정한다.
connection.[[IceGatheringState]]를
RTCIceGatheringState 열거형의 설명에 따라 새 상태 값을 도출한 값으로 설정한다.
connectionIceGatheringStateChanged를
true로 두되, 이는
connection.[[IceGatheringState]]가
이전 단계에서 바뀐 경우이다. 그렇지 않으면 false로 둔다.
이 지점 이후에는 상태를 읽거나 변경하지 않는다.
이벤트를 발생시킨다. 이름은 gatheringstatechange이며
대상은
transport이다.
connectionIceGatheringStateChanged가
true이면 이벤트를 발생시키는. 이름은
icegatheringstatechange이며
대상은 connection이다.
이벤트를 발생시킨다.
이름은 icecandidate이고
RTCPeerConnectionIceEvent
인터페이스를 사용하며 candidate
속성은 null로 설정한다. 대상은 connection이다.
RTCIceTransport 및/또는 RTCPeerConnection입니다.
ICE 에이전트가
RTCIceTransport에 사용할 새 ICE 후보를
ICE 후보 풀에서 가져오거나 처음부터 수집하여
사용할 수 있게 되었음을 나타내면, 사용자 에이전트는 반드시 다음 단계를 실행하는 태스크를
큐에 넣어야 한다:
candidate를 사용 가능해진 ICE 후보로 둔다.
connection를 이 객체와 연결된 RTCPeerConnection 객체로
둔다. 이때 이 객체는 ICE 에이전트이다.
connection.[[IsClosed]]가
true이면 이 단계들을 중단한다.
connection.[[PendingLocalDescription]] 또는
connection.[[CurrentLocalDescription]] 중
하나가
null이 아니고, 후보가 수집된 ICE 세대를 나타내는
설명이라면, 여기서 그 후보는 candidate이다. 후보를 노출하는 절차를 candidate와
connection으로 실행하고
이 단계들을 중단한다.
그렇지
않으면 candidate를
connection.[[EarlyCandidates]]에 추가한다.
ICE 에이전트가
[RFC8445
] 7.3.1.1절에
따른 역할 충돌이 있는 ICE 바인딩 요청으로 인해 ICE 역할이 변경되었음을 알리면, UA는
[[IceRole]]의 값을 새 값으로 설정하는 태스크를 큐에 넣는다.
초기 후보를 해제하는 절차를 connection 에 대해 실행하려면 다음 단계를 실행한다:
각
후보 candidate에 대해,
connection.[[EarlyCandidates]]에 속한 항목마다 태스크를 큐에
넣어 후보를 노출하는 절차를 candidate와
connection로 실행한다.
connection.[[EarlyCandidates]]를 빈 목록으로
설정한다.
후보를 노출하는 절차를 candidate와 connection로 실행하려면 다음 단계를 실행한다:
connection.[[IsClosed]]가
true이면 이 단계들을 중단한다.
transport를 RTCIceTransport로 두며, 이는
candidate가 사용 가능해진 전송이다.
connection.[[PendingLocalDescription]]
가 null이 아니고 해당 ICE 세대를
나타내며 그 세대에서 candidate가 수집되었으면,
candidate를
connection.[[PendingLocalDescription]].sdp에 추가한다.
connection.[[CurrentLocalDescription]]
가 null이 아니고 해당 ICE 세대를
나타내며 그 세대에서 candidate가 수집되었으면,
candidate를
connection.[[CurrentLocalDescription]].sdp에 추가한다.
newCandidate를 RTCIceCandidate를 생성하는 절차의 결과로 둔다.
이때 새 사전을 사용하며, 그
sdpMid와
sdpMLineIndex
는
이 RTCIceTransport와 연결된 값으로 설정하고,
usernameFragment
는 후보의
사용자 이름 조각으로 설정한다. candidate는
candidate-attribute
문법을 사용하여 candidate를 나타내도록 인코딩한 문자열로 설정한다.
newCandidate를 transport의 로컬 후보 집합에 추가한다.
이벤트를 발생시킨다. 이름은 icecandidate이고
RTCPeerConnectionIceEvent
인터페이스를 사용하며 candidate
속성은 newCandidate로 설정한다. 대상은
connection이다.
RTCIceTransportState는 RTCIceTransport에서
사용 가능한 연결을 가진 후보 쌍을 찾아 선택했기 때문에
바뀔 수도 있고, 선택된 후보 쌍이 바뀌지 않아도 바뀔
수 있다. 선택된 쌍과 RTCIceTransportState는 서로
관련이 있으며 같은 태스크에서 처리한다.
ICE 에이전트가 RTCIceTransport
의 선택된 후보 쌍,
RTCIceTransportState 또는 둘 모두가 바뀌었음을 나타내면,
사용자 에이전트는 반드시
선택된 후보 쌍과 상태를 변경하는 절차를 실행하는 태스크를 큐에 넣어야 한다:
connection를 이 객체와 연결된 RTCPeerConnection 객체로
둔다. 이때 이 객체는 ICE 에이전트이다.
connection.[[IsClosed]]가
true이면 이 단계들을 중단한다.
transport를 상태가 변경되는 RTCIceTransport로
둔다.
selectedCandidatePairChanged를
false로 둔다.
transportIceConnectionStateChanged를
false로 둔다.
connectionIceConnectionStateChanged를
false로 둔다.
connectionStateChanged를 false로 둔다.
transport의 선택된 후보 쌍이 변경되었으면 다음 단계를 실행한다:
newCandidatePair를 RTCIceCandidatePair를
생성하는 절차의 결과로 둔다. 이때 local과 remote는 쌍이 선택되어 있으면 해당
쌍의 로컬 및 원격 후보를 나타내고, 그렇지 않으면 null이다.
transport.[[SelectedCandidatePair]]를
newCandidatePair로 설정한다.
selectedCandidatePairChanged를
true로 설정한다.
transport의 RTCIceTransportState가 변경되었으면
다음 단계를 실행한다:
transport.[[IceTransportState]]를
새로 표시된 RTCIceTransportState로 설정한다.
transportIceConnectionStateChanged를
true로 설정한다.
connection.[[IceConnectionState]]
를
RTCIceConnectionState
열거형의 설명에 따라 새 상태 값을 도출한 값으로 설정한다.
connection.[[IceConnectionState]]가
이전 단계에서 바뀌었으면
connectionIceConnectionStateChanged를
true로 설정한다.
connection.[[ConnectionState]]
를
RTCPeerConnectionState
열거형의 설명에 따라 새 상태 값을 도출한 값으로 설정한다.
connection.[[ConnectionState]]가
이전 단계에서 바뀌었으면
connectionStateChanged를 true로 설정한다.
selectedCandidatePairChanged가 true이면
이벤트를 발생시키는. 이름은 selectedcandidatepairchange이며
대상은
transport이다.
transportIceConnectionStateChanged가
true이면 이벤트를 발생시키는. 이름은 statechange이며 대상은
transport이다.
connectionIceConnectionStateChanged가
true이면 이벤트를 발생시키는. 이름은
iceconnectionstatechange이며 대상은
connection이다.
connectionStateChanged가 true이면 이벤트를 발생시키는. 이름은 connectionstatechange이며 대상은
connection이다.
RTCIceTransport 객체에는
다음 내부 슬롯이 있다:
new"로 초기화한다.
new"로 초기화한다.
null로 초기화한다.
unknown"로 초기화한다.
WebIDL[Exposed=Window]
interface RTCIceTransport : EventTarget {
readonly attribute RTCIceRole role;
readonly attribute RTCIceComponent component;
readonly attribute RTCIceTransportState state;
readonly attribute RTCIceGathererState gatheringState;
sequence<RTCIceCandidate> getLocalCandidates();
sequence<RTCIceCandidate> getRemoteCandidates();
RTCIceCandidatePair? getSelectedCandidatePair();
RTCIceParameters? getLocalParameters();
RTCIceParameters? getRemoteParameters();
attribute EventHandler onstatechange;
attribute EventHandler ongatheringstatechange;
attribute EventHandler onselectedcandidatepairchange;
};
role of type RTCIceRole, readonly
role 속성은 반드시 값을 가져올 때 [[IceRole]] 내부
슬롯의 값을 반환해야 한다.
component of type
RTCIceComponent, readonly
component 속성은 반드시 전송의 ICE 구성요소를
반환해야 한다. RTCP mux를 사용하면 하나의
RTCIceTransport가 RTP와
RTCP를 모두 전송하며
component는 "rtp"로 설정된다.
state of type
RTCIceTransportState,
readonly
state 속성은 반드시 값을 가져올 때
[[IceTransportState]] 슬롯의 값을 반환해야 한다.
gatheringState of type RTCIceGathererState,
readonly
gatheringState
속성은 반드시 값을 가져올
때 [[IceGathererState]] 슬롯의 값을 반환해야 한다.
onstatechange of type EventHandler
statechange이며, 반드시 RTCIceTransport의
state가 바뀔 때마다 발생해야 한다.
ongatheringstatechange of type
EventHandler
gatheringstatechange이며,
반드시
RTCIceTransport의
[[IceGathererState]]가 바뀔 때마다 발생해야 한다.
onselectedcandidatepairchange of type
EventHandler
selectedcandidatepairchange이며,
반드시
RTCIceTransport의 선택된 후보
쌍이 바뀔 때마다 발생해야 한다.
getLocalCandidates
로컬
ICE 후보를 설명하는 시퀀스를 반환한다. 이는
이 RTCIceTransport에 대해 수집되어
onicecandidate으로 전송된 후보들이다.
getRemoteCandidates
원격
ICE 후보를 설명하는 시퀀스를 반환한다. 이는
이 RTCIceTransport가
addIceCandidate()로 받은 후보들이다.
getSelectedCandidatePair
패킷을
보내는 데 사용하는 선택된 후보 쌍을 반환한다. 이
메서드는 반드시
[[SelectedCandidatePair]]
슬롯의 값을 반환해야 한다.
RTCIceTransport.state가
"new" 또는
"closed"이면
getSelectedCandidatePair는
null을 반환한다.
getLocalParameters
로컬
ICE 매개변수를 반환한다. 이는 이
RTCIceTransport가
setLocalDescription으로 받은
값이며 아직 받지 않았으면
null을 반환한다.
getRemoteParameters
원격
ICE 매개변수를 반환한다. 이는 이
RTCIceTransport가
setRemoteDescription으로 받은
값이며 아직 받지 않았으면
null을 반환한다.
WebIDLdictionary RTCIceParameters {
DOMString usernameFragment;
DOMString password;
};
RTCIceParameters Members
RTCIceCandidatePair Dictionary
이
인터페이스는 [ RFC8445 ] 4절에 설명된 ICE
후보 쌍을 나타낸다. RTCIceCandidatePair는 로컬
및 원격 RTCIceCandidate를 쌍으로 묶은 것이다.
RTCIceCandidatePair를 생성하는 절차를 RTCIceCandidate 객체 local 및 remote
로 실행하려면 다음 단계를 실행한다:
RTCIceCandidatePair 객체로 둔다.
dictionary[Exposed=Window] interface RTCIceCandidatePair { [SameObject] readonly attribute RTCIceCandidate local; [SameObject] readonly attribute RTCIceCandidate remote; };
RTCIceCandidatePair
Members
local of type RTCIceCandidate로컬 ICE 후보이다.
remote of type RTCIceCandidate원격 ICE 후보이다.
remote
속성은 반드시 값을 가져올 때 [[Remote]] 내부 슬롯의 값을 반환해야 한다.
WebIDLenum RTCIceGathererState {
"new",
"gathering",
"complete"
};
| Enum value | Description |
|---|---|
new
|
해당 RTCIceTransport 는 방금
생성되었으며 아직 후보 를
수집하기 시작하지 않은 상태이다.
|
gathering
|
해당 RTCIceTransport 는 현재 후보를
수집하는 과정에 있는
상태이다.
|
complete
|
해당 RTCIceTransport 는
후보 수집 을 완료했으며
이 전송 에 대한 end-of-candidates 표시도 이미
전송되었다. ICE 재시작 으로 인해 다시 시작하기 전 까지 는
후보 를 다시 수집하지 않는다.
|
WebIDLenum RTCIceTransportState {
"closed",
"failed",
"disconnected",
"new",
"checking",
"completed",
"connected"
};
| Enum value | Description |
|---|---|
closed
|
해당 RTCIceTransport 는 종료되었으며
이제 더 이상 STUN 요청
에 응답하지 않는 상태이다.
|
failed
|
RTCIceTransport는
수집을 완료했고, 더 이상 원격 후보가 없다는
알림을 받았으며,
모든 후보 쌍의 검사를 완료했고, 모든 쌍이
연결 검사에 실패했거나 동의(consent)를 상실했으며,
수집된 로컬 후보가 없거나 PAC 타이머가
만료되었습니다 [RFC8863].
이 상태는 ICE가 재시작될 때까지의 종료 상태입니다.
ICE 재시작으로 연결이 재개될 수 있으므로,
"failed"
상태가 되어도 DTLS 전송,
SCTP 연결 또는 그 위에서 실행되는 데이터 채널이
닫히거나 트랙이 음소거되지는 않습니다.
|
disconnected
|
해당 ICE 에이전트 는 다음 전송의 연결 이
현재 끊어졌다고 판단한 상태이다: RTCIceTransport. 이는 불안정한 네트워크에서
간헐적으로 발생할 수 있는 일시적인 상태이며 아무런
조치 없이도 저절로 해소될 수 있다. 이 상태를 판단하는 방식은
구현에 따라 다르다. 예를 들면 다음과 같은
경우가 있다:
RTCIceTransport 가기존의
모든후보
쌍에 대한 검사를 끝냈지만 연결을 찾지 못한 상태일 수도
있다. 또는 다음 동의 검사[RFC7675]가
이전에는 성공했지만
이제는 실패했을 수도있다. 다만전송은 여전히 후보를 수집하고 있거나 추가적인 원격
후보를 기다리고 있는 상태이다.
|
new
|
해당 RTCIceTransport 는
후보를 수집 하고
있거나 원격 후보가 제공되기 를 기다리고 있으며 아직 검사 를
시작하지 않은 상태이다.
|
checking
|
해당 RTCIceTransport 는하나
이상의원격 후보를받은 상태이다. 이후보는 다음
메서드를 사용하여 받은 것이거나: addIceCandidate()
STUN 바인딩 요청 을
받을 때 peer-reflexive 후보 로 발견한 것이다.
전송 은 후보 쌍을 검사 하고 있으며 아직 연결
을 찾지 못했 거나 다음 동 의 검사 [RFC7675]가
이전에 성공했던 모든후보 쌍에서 실패한 상태이다. 후보 쌍에
대한 검사를 수행하는 동시에 여전히 후보를 수집하고 있을 수도 있다.
|
completed
|
해당 RTCIceTransport 는
후보 수집을 마쳤고 더
이상 원격 후보가 없다는 표시 를 받았으며 모든
후보 쌍에 대한 검사도 끝내고 연결 을 찾은
상태이다. 이후 동의 검사 [RFC7675]
가
성공했던 모든 후보 쌍에서 실패하게 되면 상태가 다음
값으로 바뀐다: "failed".
|
connected
|
해당 RTCIceTransport 는 사용할 수
있는 연결을 찾았지만
더 나은 연결이 있는지 확인하기 위해 다른 후보 쌍도 계속 검사
하는 상태이다. 또한 후보를 수집 하고 있 거나 추가적인 원격
후보 를 기다리고 있을 수도 있다. 동의 검사
[RFC7675]
가 사용 중인 연결 에서 실패 하고 사용할 수
있는 다른 성공한 후보 쌍도 없다면 상태가 다음
값 으로 바뀐다: "checking"이다.
이는아직 검사할 후보쌍이 남아 있는 경우이다. 또는 다음 값으로 바뀐다:
"disconnected"
이다. 이는 검사할 후보
쌍이 없지만 피어가 여전히 후보를 수집 하고 있 거나 추가적인
원격 후보 를 기다리고 있는 경우이다.
|
성공적인
호출에서 가장 흔한 전이는 new -> checking
-> connected -> completed이지만, 특정 상황(마지막으로
확인한 후보만 성공하고, 후보 수집과 더
이상 후보가 없다는 알림이 모두 성공 전에
발생한 경우)에서는 상태가 "
checking"에서 "
completed"로 직접 전이할 수 있다.
ICE
재시작은 후보 수집과 연결성 검사를 새로
시작하게 하며, "
connected" 상태로 전이하게 한다. 이는 "
completed" 상태에서 재시작한 경우이다.
일시적인
"disconnected"
상태에서
재시작하면 "checking" 상태로
전이하여, 이전에 연결성이 상실되었다는 사실을 사실상 잊는다.
"
failed"와 "
completed" 상태에는
추가
원격 후보가 없다는 알림이 필요하다.
이는 addIceCandidate
를 candidate 속성이 빈
문자열인 후보 값으로 호출하거나,
canTrickleIceCandidates를
false로 설정하여 나타낼 수 있다.
상태 전이의 예는 다음과 같다:
RTCIceTransport가
setLocalDescription
또는
setRemoteDescription의 결과로 처음
생성됨): "new"
new
", 원격 후보를 받음): "
checking"
checking", 사용 가능한
연결을 찾음): "
connected"
checking", 검사가 실패했으나
수집은 계속
진행 중임): "disconnected"
checking", 시도를 포기함): "
failed"
disconnected",
새
로컬 후보가 있음): "checking"
connected", 모든 검사를
완료함): "
completed"
completed",
연결성을 잃음): "
disconnected"
disconnected" 또는
"failed
", ICE 재시작 발생):
"checking"
completed", ICE 재시작
발생): "
connected"
RTCPeerConnection.close():
"closed"
WebIDLenum RTCIceRole {
"unknown",
"controlling",
"controlled"
};
| Enum value | Description |
|---|---|
unknown
|
에이전트 의 역할은 다음 문헌을 기준으로 판단한다: [RFC5245], 제3절에 정의된 그 역할이 아직 정해지지 않았다. |
controlling
|
제어하는 에이전트로서 다음 문헌에 정의되어 있다: [RFC5245], 제3절의 정의이다. |
controlled
|
제어받는 에이전트로서 다음 문헌에 정의되어 있다: [RFC5245], 제3절의 정의이다. |
WebIDLenum RTCIceComponent {
"rtp",
"rtcp"
};
| Enum value | Description |
|---|---|
rtp
|
ICE 전송은 RTP 또는 RTCP 다중화에 사용된다. 이는 다음 문헌에
정의 되어 있다: [RFC5245],
제4.1.1.1절이다. RTP와 다중화되
는 프로토콜도 같은 컴포넌트 ID를 공유한다. 데이터 채널이
그 예이다. 이는 다음 필드의 component-id 값이
1 임을나타낸다. 인코딩형식은
다음과같다: candidate-attribute.
|
rtcp
|
ICE 전송 은 다음 문헌 에 정의된 RTCP에 사용 된다: [RFC5245],
제4.1.1.1절이다. 이는 다음 필드 의 component-id 값이
2 임을나타낸다. 인코딩형식은
다음과같다: candidate-attribute.
|
track 이벤트는 RTCTrackEvent 인터페이스를 사용한다.
WebIDL[Exposed=Window]
interface RTCTrackEvent : Event {
constructor(DOMString type, RTCTrackEventInit eventInitDict);
readonly attribute RTCRtpReceiver receiver;
readonly attribute MediaStreamTrack track;
[SameObject] readonly attribute FrozenArray<MediaStream> streams;
readonly attribute RTCRtpTransceiver transceiver;
};
RTCTrackEvent.constructor()
receiver of type
RTCRtpReceiver, readonly
receiver 속성은
이벤트와 연결된 RTCRtpReceiver
객체를 나타낸다.
track of type MediaStreamTrack, readonly
track 속성은
MediaStreamTrack
객체를 나타내며, 이는 RTCRtpReceiver와
연결된 트랙이다. 해당 수신자는 receiver로 식별한다.
streams of type FrozenArray<MediaStream>,
readonly
streams 속성은
MediaStream
객체의 배열을 반환한다. 이는 MediaStream들 중 이 이벤트의
track이 속하는 스트림들을 나타낸다.
transceiver of type
RTCRtpTransceiver,
readonly
transceiver 속성은
이벤트와 연결된
RTCRtpTransceiver
객체를 나타낸다.
WebIDLdictionary RTCTrackEventInit : EventInit {
required RTCRtpReceiver receiver;
required MediaStreamTrack track;
sequence<MediaStream> streams = [];
required RTCRtpTransceiver transceiver;
};
receiver of type RTCRtpReceiver, required
receiver 멤버는
이벤트와 연결된 RTCRtpReceiver
객체를 나타낸다.
track of type MediaStreamTrack, required
track 멤버는
MediaStreamTrack
객체를 나타내며, 이는 RTCRtpReceiver와
연결된 트랙이다. 해당 수신자는 receiver로 식별한다.
streams of
type sequence<MediaStream>,
defaulting to []
streams 멤버는
MediaStream 객체의
배열이며, 이는 MediaStream들 중 이 이벤트의 track이
속하는 스트림들을 나타낸다.
transceiver of type RTCRtpTransceiver,
required
transceiver
속성은 이벤트와 연결된
RTCRtpTransceiver
객체를 나타낸다.
피어 간 데이터 API는 웹 애플리케이션이 일반 애플리케이션 데이터를 피어 간에 보내고 받을 수 있도록 한다. 데이터 송수신 API는 Web Sockets의 동작을 본뜬다.
피어
간 데이터 API는 아래에 설명된 대로 RTCPeerConnection 인터페이스를
확장한다.
WebIDL partial interface RTCPeerConnection {
readonly attribute RTCSctpTransport? sctp;
RTCDataChannel createDataChannel(USVString label,
optional RTCDataChannelInit dataChannelDict = {});
attribute EventHandler ondatachannel;
};
sctp of type RTCSctpTransport,
readonly, nullable
SCTP
데이터를 보내고 받는 SCTP 전송이다. SCTP가
협상되지 않았으면 값은 null이다. 이 속성은
반드시 RTCSctpTransport 객체를 반환해야 하며,
이 객체는 [[SctpTransport]] 내부 슬롯에 저장되어 있다.
ondatachannel of type EventHandler
datachannel이다.
createDataChannel
주어진
레이블로 새 RTCDataChannel 객체를
생성한다.
RTCDataChannelInit 사전을
사용하여 데이터
신뢰성과 같은 기반 채널의 속성을 구성할 수
있다.
createDataChannel
메서드가 호출되면 사용자
에이전트는 반드시 다음 단계를 실행해야 한다.
connection를 메서드가 호출된 RTCPeerConnection
객체로 둔다.
connection.[[IsClosed]]가
true이면 예외를 던지는 절차로
InvalidStateError를 던진다.
RTCDataChannel을 생성하는 절차로 channel을 생성한다.
channel.[[DataChannelLabel]]
을
첫 번째 인수의 값으로 초기화한다.
[[DataChannelLabel]]
의 UTF-8 표현이 65535바이트보다 길면
예외를 던지는 절차로 TypeError를 던진다.
options를 두 번째 인수로 둔다.
channel.[[MaxPacketLifeTime]]를
option.maxPacketLifeTime
가 존재하면 그 값으로, 그렇지 않으면 null로 초기화한다.
channel.[[MaxRetransmits]]를
option.maxRetransmits
가 존재하면 그 값으로, 그렇지 않으면 null로 초기화한다.
channel.[[Ordered]]를
option.ordered로 초기화한다.
channel.[[DataChannelProtocol]]를
option.protocol로 초기화한다.
[[DataChannelProtocol]]의
UTF-8 표현이 65535바이트보다 길면
예외를 던지는 절차로 TypeError를 던진다.
channel.[[Negotiated]]를
option.negotiated로 초기화한다.
channel.[[DataChannelId]]를
option.id가
존재하고 [[Negotiated]]가 true이면 그
값으로, 그렇지 않으면
null로 초기화한다.
[[Negotiated]]가
true이고
[[DataChannelId]]가
null이면 예외를 던지는 절차로 TypeError를 던진다.
[[MaxPacketLifeTime]]와
[[MaxRetransmits]]
속성이 모두 설정되어 있으면(null이 아니면)
예외를 던지는 절차로 TypeError를 던진다.
[[MaxPacketLifeTime]]
또는
[[MaxRetransmits]] 중
한 설정이 비신뢰
모드를 나타내도록 설정되었고 그 값이 사용자 에이전트가 지원하는
최대값을 초과하면, 그 값은 반드시 사용자
에이전트의 최대값으로 설정해야 한다.
[[DataChannelId]]가
65535와 같으면,
이는 허용되는 최대 ID 65534보다
크지만 unsigned
short 범위에는 여전히 속하므로, 예외를 던지는 절차로 TypeError를 던진다.
[[DataChannelId]] 슬롯이
null이고(
createDataChannel에
ID가 전달되지 않았거나 [[Negotiated]]
가 false이기 때문에), SCTP 전송의
DTLS 역할이 이미 협상되었으면,
[[DataChannelId]]
를 사용자
에이전트가 [RFC8832
]에 따라 생성한 값으로 초기화하고 다음 단계로 넘어간다.
사용 가능한 ID를 생성할 수 없거나
[[DataChannelId]] 슬롯의
값을 기존
RTCDataChannel이 사용하고 있으면, 예외를 던지는 절차로
OperationError 예외를 던진다.
transport를
connection.[[SctpTransport]]로 둔다.
[[DataChannelId]] 슬롯이
null이 아니고 transport가 "
connected
" 상태이며
[[DataChannelId]]
가
transport.[[MaxChannels]] 이상이면 예외를 던지는 절차로 OperationError를 던진다.
channel이 RTCDataChannel에서
처음 생성된 connection이면 협상
필요 플래그를 갱신하는 절차를 connection에 대해 실행한다.
추가하는 절차로 channel을
connection.[[DataChannels]]에 추가한다.
channel을 반환하고 다음 단계를 병렬로 계속한다.
channel과 연결된 기반 데이터 전송 을 생성하고 channel의 관련 속성에 따라 구성한다.
RTCSctpTransport 인터페이스는 특정
SCTP 연결에
연결된 SCTP 데이터 채널 정보에 애플리케이션이 접근할 수
있도록 한다.
RTCSctpTransport를 생성하는 절차를 초기
상태 initialState로 실행하려면 다음 단계를 실행한다:
transport를 새 RTCSctpTransport
객체로 둔다.
transport에 [[SctpTransportState]] 내부 슬롯을 두고 initialState로 초기화한다.
transport에 [[MaxMessageSize]] 내부 슬롯을 두고 데이터 최대 메시지 크기를 갱신하는로 표시된 단계를 실행하여 초기화한다.
transport에 [[MaxChannels]]
내부 슬롯을 두고 null로 초기화한다.
transport를 반환한다.
데이터 최대 메시지 크기를 갱신하는 절차를
RTCSctpTransport에 대해 실행하려면 다음
단계를 실행한다:
transport를 갱신할 RTCSctpTransport 객체로
둔다.
remoteMaxMessageSize를
max-message-size SDP 속성의
값으로 둔다. 이는 [ RFC8841
] 6절에 설명된 대로 원격 설명에서 읽은 값이며, 속성이 없으면 65536으로 둔다.
canSendSize를 이 클라이언트가 보낼 수 있는 바이트 수(즉 로컬 송신 버퍼 크기)로 두며, 구현이 모든 크기의 메시지를 처리할 수 있으면 0으로 둔다.
remoteMaxMessageSize와
canSendSize가 모두 0이면 [[MaxMessageSize]]를
양의 Infinity 값으로 설정한다.
그렇지
않고 remoteMaxMessageSize 또는
canSendSize 중 하나가 0이면 [[MaxMessageSize]]를
둘 중 더 큰 값으로 설정한다.
그렇지
않으면 [[MaxMessageSize]]를
remoteMaxMessageSize와 canSendSize 중 더 작은 값으로 설정한다.
SCTP 전송이
연결된 상태가 되면, 즉 RTCSctpTransport의
SCTP 연결이 설정되면, 사용자 에이전트는 반드시 다음 단계를 실행하는
태스크를 큐에 넣는 절차를 수행해야 한다:
transport를 RTCSctpTransport 객체로 둔다.
connection를 RTCPeerConnection 객체로
두며, 이 객체는 transport와 연결되어 있다.
[[MaxChannels]]를 협상된 수신
및 송신
SCTP 스트림 수 중 더 작은 값으로 설정한다.
connection의 각 RTCDataChannel에 대해:
channel를 RTCDataChannel 객체로 둔다.
channel.[[DataChannelId]]가
null이면 [[DataChannelId]]를
기반 SCTP 데이터 채널이
[ RFC8832 ]에 따라 생성한 값으로 초기화한다.
channel.[[DataChannelId]]
가
transport.[[MaxChannels]] 이상이거나
이전 단계에서 ID를 할당하지 못했으면, 실패로 인해 연결을 닫는 절차로
channel
을 닫는다. 그렇지 않으면 채널이 열렸음을 알리는 절차를 실행한다.
이벤트를 발생시킨다. 이름은 statechange이며 대상은
transport이다.
이
이벤트는 open
이벤트보다 먼저 발생한다. 해당 이벤트는 채널이
열렸음을 알리는
절차가 발생시키며, open 이벤트는 별도로
큐에 넣은
태스크에서 발생한다.
WebIDL[Exposed=Window]
interface RTCSctpTransport : EventTarget {
readonly attribute RTCDtlsTransport transport;
readonly attribute RTCSctpTransportState state;
readonly attribute unrestricted double maxMessageSize;
readonly attribute unsigned short? maxChannels;
attribute EventHandler onstatechange;
};
transport of type RTCDtlsTransport,
readonly
데이터 채널의 모든 SCTP 패킷을 보내고 받는 전송이다.
state of type RTCSctpTransportState,
readonly
SCTP
전송의 현재 상태이다. 값을 가져올 때 이 속성은
반드시
[[SctpTransportState]]
슬롯의 값을 반환해야 한다.
maxMessageSize of type unrestricted double, readonly
데이터의
최대 크기로서
RTCDataChannel의 send()
메서드에 전달할 수 있는 한도이다. 값을
가져올 때 이 속성은 반드시
[[MaxMessageSize]] 슬롯의 값을 반환해야 한다.
maxChannels of type unsigned short , readonly, nullable
동시에
사용할 수 있는 RTCDataChannel의 최대
수이다.
값을 가져올 때 이 속성은 반드시
[[MaxChannels]] 슬롯의 값을 반환해야 한다.
null 이며,
SCTP 전송이
"connected"
상태가 될 때까지 유지됩니다.
onstatechange of type EventHandler
이
이벤트 핸들러의 이벤트 유형은
statechange이다.
RTCSctpTransportState는 SCTP
전송의 상태를
나타낸다.
WebIDLenum RTCSctpTransportState {
"connecting",
"connected",
"closed"
};
| Enum value | Description |
|---|---|
connecting
|
|
connected
|
연결
협상이 완료되면 [[SctpTransportState]]
슬롯을 "
|
closed
|
다음
경우 [[SctpTransportState]] 슬롯을 "
마지막 전이는 SCTP 연결에 이미 설정된 DTLS 연결이 필요하다는 점에서 자연스럽다. [RFC8261 ] 6.1절은 DTLS 위의 SCTP가 단일 홈 방식이라고 명시하며, 이 API는 다른 전송으로 전환하는 방법을 정의하지 않는다. |
RTCDataChannel 인터페이스는
두 피어 사이의 양방향
데이터 채널을 나타낸다. RTCDataChannel
은 RTCPeerConnection 객체의 팩터리 메서드로 생성한다.
브라우저 사이에 전송되는 메시지는 [RFC8831]과 [
RFC8832]에 설명되어 있다.
RTCDataChannel
로 연결을 설정하는 방법에는 두 가지가 있다. 첫 번째 방법은 한쪽 피어에서 RTCDataChannel을
생성하되, negotiated라는
RTCDataChannelInit 사전 멤버를 설정하지 않거나
기본값 false로 설정하는
것이다. 이렇게 하면 새 채널을 대역 내에서 알리고 다른 피어에서
RTCDataChannelEvent를 대응하는
RTCDataChannel
객체와 함께 발생시킨다. 두 번째 방법은
애플리케이션이 RTCDataChannel을 협상하도록 하는 것이다. 이를 위해
RTCDataChannel 객체를 생성하되
negotiated라는
RTCDataChannelInit 사전 멤버를 true로 설정하고,
대역 외
신호(예: 웹 서버를 통해)로 다른 쪽에 알린다. 다른 쪽은 가급적
대응하는 RTCDataChannel을 생성하되
negotiated라는 RTCDataChannelInit 사전
멤버를 true로 설정하고 같은 id를 사용해야
한다. 이렇게 하면 별도로 생성한 두 RTCDataChannel 객체가
연결된다. 두 번째 방법을 사용하면
비대칭 속성을 가진 채널을 만들거나,
일치하는 id를 지정하여 선언적인 방식으로 채널을 만들 수 있다.
각
RTCDataChannel에는 다른 피어로
실제 데이터를 전송하는 데 사용하는 기반 데이터 전송이
연결되어 있다. SCTP 연결의 상태를
나타내는 RTCSctpTransport를 사용하는
SCTP 데이터 채널에서는 기반 데이터
전송이 SCTP 스트림 쌍이다. 기반 데이터
전송의 전송 속성(순서대로 전달하는 설정이나 신뢰성
모드 등)은 채널을 생성할 때 피어가 구성한다.
채널을 생성한 뒤에는 채널의 속성을 변경할 수
없다. 피어 사이에서 실제로 사용하는 통신 프로토콜은
WebRTC DataChannel Protocol 명세 [RFC8831]에 지정되어 있다.
RTCDataChannel은
서로 다른 신뢰성
모드로 동작하도록 구성할 수 있다. 신뢰
채널은 재전송을 통해 데이터가 다른 피어에
전달되도록 보장한다. 비신뢰 채널은 재전송 횟수를 제한하거나(
maxRetransmits),
재전송을
포함한 전송이 허용되는 시간을 설정하도록(
maxPacketLifeTime)
구성한다. 이
속성들은 동시에 사용할 수 없으며 그렇게 하려고 하면
오류가 발생한다. 이 속성들을 모두 설정하지 않으면 신뢰
채널이 된다.
RTCDataChannel은
createDataChannel로
생성되거나
RTCDataChannelEvent를 통해 전달되었을 때 반드시 처음에는 "
connecting" 상태여야 한다.
RTCDataChannel 객체의 기반 데이터 전송이 준비되면
사용자 에이전트는 반드시 RTCDataChannel이 열렸음을 알리는 절차를 수행해야 한다.
RTCDataChannel을 생성하는
절차를 실행하려면 다음 단계를
실행한다:
channel를 새로 생성한 RTCDataChannel
객체로 둔다.
channel에 [[ReadyState]]
내부 슬롯을 두고 "
connecting"으로 초기화한다.
channel에 [[BufferedAmount]]
내부 슬롯을 두고 0로 초기화한다.
channel에 [[DataChannelLabel]], [[Ordered]], [[MaxPacketLifeTime]], [[MaxRetransmits]], [[DataChannelProtocol]], [[Negotiated]] 및 [[DataChannelId]]라는 내부 슬롯을 둔다.
true로 초기화한다.[[IsTransferable]]를
false로 설정한다.
이 태스크는 데이터 채널에서 메시지를
수신하는 알고리즘이 channel
에 대해 큐에 넣은 모든 태스크보다 먼저 실행되어야 한다. 이로써 RTCDataChannel을 이전하는 동안 메시지가 손실되지 않도록 보장한다.
channel를 반환한다.
사용자
에이전트가 RTCDataChannel이
열렸음을 알리는 절차를 실행해야 하면, 사용자 에이전트는 반드시 다음 단계를 실행하는 태스크를 큐에 넣어야
한다:
연결된
RTCPeerConnection 객체의
[[IsClosed]] 슬롯이
true이면 이 단계들을
중단한다.
channel를 열렸음을 알릴 RTCDataChannel 객체로
둔다.
channel.[[ReadyState]]가
"closing" 또는
"closed"이면 이 단계들을
중단한다.
channel.[[ReadyState]]를
"open"로 설정한다.
이벤트를 발생시킨다. 이름은 open이며 대상은 channel이다.
기반 데이터 전송을 알려야
하면(다른 피어가 negotiated를
설정하지 않거나 false로 설정하여 채널을 생성한 경우), 생성 프로세스를 시작하지
않은 피어의 사용자 에이전트는 반드시 다음 단계를 실행하는 태스크를
큐에 넣어야 한다:
connection을 RTCPeerConnection 객체로
두며, 이는 기반 데이터 전송과 연결되어 있다.
connection.[[IsClosed]]가
true이면 이 단계들을 중단한다.
RTCDataChannel을 생성하는 절차로 channel을 생성한다.
configuration을 다른 피어에서 받은 정보 묶음으로 둔다. 이는 기반 데이터 전송을 설정하는 과정의 일부로 수신한 것이며, 이 과정은 WebRTC DataChannel Protocol 명세 [RFC8832]에 설명되어 있다.
channel.[[DataChannelLabel]],
[[Ordered]], [[MaxPacketLifeTime]],
[[MaxRetransmits]], [[DataChannelProtocol]]
및 [[DataChannelId]]
내부
슬롯을 configuration의 대응하는 값으로 초기화한다.
channel.[[Negotiated]]를
false로 초기화한다.
추가하는 절차로
channel을
connection.[[DataChannels]]에 추가한다.
channel.[[ReadyState]]를
"open
"으로 설정한다(그러나 open
이벤트는 아직 발생시키지 않는다).
datachannel event handler prior to
the open event being
fired.
이벤트를 발생시킨다. 이름은 datachannel이고
RTCDataChannelEvent 인터페이스를
사용하며
channel 속성은
channel로 설정한다. 대상은 connection이다.
데이터 채널이 열렸음을 알리는 절차를 실행한다.
RTCDataChannel 객체의 기반 데이터 전송
은 닫기 절차를 실행하여
갑작스럽지 않은 방식으로 해제할 수 있다. 이 경우 사용자 에이전트는 반드시 다음 단계를 실행하는 태스크를 큐에 넣어야
한다:
channel를 RTCDataChannel 객체로 두며, 이 객체의
기반 데이터 전송가 닫힌 것이다.
connection를 RTCPeerConnection 객체로
두며, 이 객체는 channel와 연결되어 있다.
제거하는 절차로
channel을 connection.[[DataChannels]]에서 제거한다.
프로세스가
channel.close에 의해 시작된 것이 아니면
channel.[[ReadyState]]를
"closing"으로 설정하고 이벤트를 발생시키는 절차를 실행한다. 이름은
closing이며 대상은 channel이다.
다음
단계를 병렬
병렬로 실행한다:
RTCDataChannel 객체의 기반 데이터 전송이
닫힌 상태가 되면, 사용자 에이전트는 반드시 다음 단계를 실행하는 태스크를
큐에 넣어야 한다:
channel를 RTCDataChannel 객체로 두며, 이 객체의
기반 데이터 전송가 닫힌 것이다.
[[ReadyState]]가
"closed
"이면 이 단계들을 중단한다.
channel.[[ReadyState]]를
"closed"로 설정한다.
제거하는 절차로
channel을 connection.[[DataChannels]]에서
아직 그 안에 있으면 제거한다.
transport가
오류 발생 상태로 닫혔으면 이벤트를 발생시키는 절차를 실행한다. 이름은 error이고 RTCErrorEvent
인터페이스를 사용하며 errorDetail
속성은 "
sctp-failure"로 설정한다. 대상은
channel이다.
이벤트를 발생시킨다. 이름은 연결을 닫는이며 대상은 channel이다.
RTCDataChannel의 이전 단계는 value와
dataHolder가 주어지면 다음과 같다:
value.[[IsTransferable]]가
false이면 DataCloneError DOMException을 던진다.
dataHolder.[[ReadyState]]를 value.[[ReadyState]]로 설정한다.
dataHolder.[[DataChannelLabel]]를
value.[[DataChannelLabel]]로 설정한다.
dataHolder.[[Ordered]]를 value.[[Ordered]]로 설정한다.
dataHolder.[[MaxPacketLifeTime]]를
value..[[MaxPacketLifeTime]]로 설정한다.
dataHolder.[[MaxRetransmits]]를
value.[[MaxRetransmits]]로 설정한다.
dataHolder.[[DataChannelProtocol]]를
value.[[DataChannelProtocol]]로 설정한다.
dataHolder.[[Negotiated]]를 value.[[Negotiated]]로 설정한다.
dataHolder.[[DataChannelId]]를
value.[[DataChannelId]]로 설정한다.
value.[[IsTransferable]]를
false로 설정한다.
value.[[ReadyState]]를 "closed"로 설정한다.
RTCDataChannel의 이전 수신 단계는 dataHolder와
channel가 주어지면 다음과 같다:
channel.[[ReadyState]]를
dataHolder.[[ReadyState]]로 초기화한다.
channel.[[DataChannelLabel]]를
dataHolder.[[DataChannelLabel]]로 초기화한다.
channel.[[Ordered]]를 dataHolder.[[Ordered]]로 초기화한다.
channel.[[MaxPacketLifeTime]]를
dataHolder.[[MaxPacketLifeTime]]로 초기화한다.
channel.[[MaxRetransmits]]를
dataHolder.[[MaxRetransmits]]로 초기화한다.
channel.[[DataChannelProtocol]]를
dataHolder.[[DataChannelProtocol]]로 초기화한다.
channel.[[Negotiated]]를
dataHolder.[[Negotiated]]로 초기화한다.
channel.[[DataChannelId]]를
dataHolder.[[DataChannelId]]로 초기화한다.
위 단계들은 [[BufferedAmount]]를 이전할 필요가
없다. 이 값은 항상 0
이기 때문이다. 이는 RTCDataChannel을 이전하기 전에
그 send() 알고리즘이 호출되지 않은 경우에만 이전할 수 있기 때문이다.
기반 데이터 전송이
이전 수신 단계 시점에
닫혀 있으면, RTCDataChannel 객체는
데이터 채널이
닫혔음을 알리는 알고리즘을 이전 수신 단계 직후에 실행하여 닫힌다.
경우에
따라 사용자 에이전트는
RTCDataChannel을 생성할 수 없는 상황에 놓일 수 있으며, 생성하지 못하는 대상은 그 채널의 기반
데이터 전송이다.
예를 들어 데이터 채널의 id가
SCTP 핸드셰이크에서 [RFC8831] 구현들이 협상한
범위를 벗어날 수 있다. 사용자 에이전트가
RTCDataChannel의 기반 데이터 전송을 생성할
수 없다고 판단하면, 사용자 에이전트는 반드시 다음 단계를 실행하는 태스크를 큐에 넣어야
한다:
channel을 RTCDataChannel 객체로
두며, 이는 사용자 에이전트가 기반 데이터 전송을 생성할 수 없었던 채널이다.
channel.[[ReadyState]]를
"closed"로 설정한다.
이벤트를 발생시킨다. 이름은 error이고
RTCErrorEvent 인터페이스를 사용하며 errorDetail
속성은 "data-channel-failure"로
설정한다. 대상은 channel이다.
이벤트를 발생시킨다. 이름은 연결을 닫는이며 대상은 channel이다.
RTCDataChannel
메시지를 기반 데이터 전송으로 수신하였고
그 유형이 type이며 데이터가 rawData이면, 사용자 에이전트는
반드시 다음 단계를 실행하는 태스크를 큐에 넣어야 한다:
channel을 사용자 에이전트가 메시지를 수신한 RTCDataChannel
객체로 둔다.
connection를 RTCPeerConnection 객체로
두며, 이 객체는 channel와 연결되어 있다.
channel.[[ReadyState]]가 "
open
"이 아니면 이 단계들을 중단하고
rawData를 버린다.
type와
channel.binaryType에 따라 분기하여 하위 단계를 실행한다:
type이 rawData의
string 형식을 나타내면:
data를 DOMString 으로 두며, 이는 rawData를 UTF-8로 디코딩한 결과를 나타낸다.
type가 rawData의
이진 형식을 나타내고 binaryType가 "blob"이면:
data를 새 Blob 객체로 두며, 원시 데이터 소스로
rawData를 포함한다.
type가 rawData의
이진 형식을 나타내고 binaryType가 "arraybuffer"이면:
data를 새 ArrayBuffer 객체로 두며,
원시 데이터 소스로 rawData를 포함한다.
이벤트를 발생시킨다. 이름은 message이며
MessageEvent 인터페이스를 사용하고, 그 origin 속성은
출처의 직렬화의 결과로 초기화한다. 직렬화할 출처는
connection.[[DocumentOrigin]]이다.
data 속성은
data로 초기화하며, 이벤트의 대상은 channel이다.
WebIDL[Exposed=(Window,DedicatedWorker), Transferable]
interface RTCDataChannel : EventTarget {
readonly attribute USVString label;
readonly attribute boolean ordered;
readonly attribute unsigned short? maxPacketLifeTime;
readonly attribute unsigned short? maxRetransmits;
readonly attribute USVString protocol;
readonly attribute boolean negotiated;
readonly attribute unsigned short? id;
readonly attribute RTCDataChannelState readyState;
readonly attribute unsigned long bufferedAmount;
[EnforceRange] attribute unsigned long bufferedAmountLowThreshold;
attribute EventHandler onopen;
attribute EventHandler onbufferedamountlow;
attribute EventHandler onerror;
attribute EventHandler onclosing;
attribute EventHandler onclose;
undefined close();
attribute EventHandler onmessage;
attribute BinaryType binaryType;
undefined send(USVString data);
undefined send(Blob data);
undefined send(ArrayBuffer data);
undefined send(ArrayBufferView data);
};
label of type
USVString, readonly
label 속성은
이
RTCDataChannel 객체를 다른
RTCDataChannel 객체와 구별하는 데 사용할 수
있는 레이블을 나타낸다. 스크립트는 같은 레이블을
가진 여러 RTCDataChannel 객체를 생성할 수
있다. 값을
가져올 때 이 속성은 반드시
[[DataChannelLabel]] 슬롯의 값을 반환해야 한다.
ordered of type
boolean, readonly
ordered 속성은
RTCDataChannel이 순서대로 전달되면
true를, 순서가 바뀐 전달이
허용되면 false를 반환한다. 값을 가져올 때 이 속성은 반드시
[[Ordered]] 슬롯의 값을 반환해야 한다.
maxPacketLifeTime of
type unsigned short, readonly,
nullable
maxPacketLifeTime
속성은 비신뢰 모드에서 전송과
재전송이 일어날 수 있는 시간 범위의 길이를
밀리초 단위로 반환한다. 값을 가져올 때 이
속성은 반드시
[[MaxPacketLifeTime]] 슬롯의 값을 반환해야 한다.
maxRetransmits
of type unsigned short,
readonly, nullable
maxRetransmits
속성은 비신뢰 모드에서 시도하는
최대 재전송 횟수를 반환한다. 값을 가져올 때
이 속성은 반드시
[[MaxRetransmits]] 슬롯의 값을 반환해야 한다.
protocol of type
USVString, readonly
protocol 속성은
이
RTCDataChannel과 함께 사용하는 하위 프로토콜의 이름을
반환한다. 값을 가져올 때 이 속성은 반드시
[[DataChannelProtocol]]
슬롯의 값을 반환해야 한다.
negotiated of type
boolean, readonly
negotiated 속성은
이
RTCDataChannel을 애플리케이션이 협상했으면
true를, 그렇지 않으면
false를 반환한다. 값을 가져올 때 이 속성은 반드시
[[Negotiated]] 슬롯의 값을 반환해야 한다.
id of type unsigned
short, readonly, nullable
id 속성은 이
RTCDataChannel의
ID를 반환한다.
초기값은 null이며, 채널 생성 시 ID를
제공하지 않았고 SCTP 전송의 DTLS 역할도
아직 협상되지 않았으면 이 값을
반환한다. 그렇지 않으면 스크립트가 선택하거나 사용자
에이전트가 [RFC8832]에 따라
생성한
ID를 반환한다. ID를 null이 아닌 값으로 설정한 뒤에는 변경되지 않는다. 값을
가져올 때 이 속성은 반드시
[[DataChannelId]] 슬롯의 값을 반환해야 한다.
readyState of type
RTCDataChannelState,
readonly
readyState
속성은
RTCDataChannel 객체의 상태를
나타낸다. 값을 가져올 때 이 속성은 반드시
[[ReadyState]] 슬롯의 값을 반환해야 한다.
bufferedAmount
of type unsigned long,
readonly
bufferedAmount
속성은 반드시 값을 가져올
때 [[BufferedAmount]]
슬롯의 값을 반환해야
한다. 이 속성은
send()로 큐에
넣은 애플리케이션 데이터(UTF-8 텍스트와 이진 데이터)의 바이트 수를
노출한다. 데이터 전송이 병렬로 일어날 수 있더라도, 반환되는 값은 절대로
경쟁 상태를 방지하기 위해 현재 태스크가
이벤트 루프에 제어를 돌려주기 전에 감소해서는
안 된다. 이 값에는 프로토콜의 프레이밍
오버헤드나 운영체제 또는 네트워크 하드웨어의 버퍼링은 포함되지 않는다.
[[BufferedAmount]] 슬롯의
값은
send() 메서드를 호출할
때마다 증가하며, 이는
[[ReadyState]]
슬롯이 "
open"인 동안에만
해당한다. 그러나
채널이 닫혀도 슬롯은 0으로 재설정되지 않는다. 기반 데이터 전송이 큐에서 데이터를
보내면, 사용자 에이전트는
반드시 [[BufferedAmount]]를
전송한 바이트 수만큼 줄이는 태스크를 큐에 넣어야 한다.
bufferedAmountLowThreshold of type
unsigned long
bufferedAmountLowThreshold
속성은 bufferedAmount
가 낮다고 간주되는 임계값을 설정한다.
bufferedAmount가
이 임계값보다 큰
값에서 임계값 이하로 감소하면 bufferedamountlow
이벤트가 발생한다.
bufferedAmountLowThreshold는
새
RTCDataChannel마다 처음에는
0이지만, 애플리케이션은 언제든지
그 값을 변경할 수 있다.
onopen of type EventHandler
open이다.
onbufferedamountlow of type EventHandler
bufferedamountlow이다.
onerror of type EventHandler
이
이벤트 핸들러의 이벤트 유형은 RTCErrorEvent이다.
errorDetail은
"sctp-failure"를 포함하고,
sctpCauseCode는
SCTP Cause Code
값을 포함하며, message는
SCTP Cause-Specific-Information을
포함하고 추가 텍스트가 있을 수도 있다.
onclosing of type EventHandler
이
이벤트 핸들러의 이벤트 유형은 closing이다.
onclose of type EventHandler
이 이벤트 핸들러의 이벤트 유형은 연결을 닫는이다.
onmessage of type EventHandler
이
이벤트 핸들러의 이벤트 유형은 message이다.
binaryType of type
BinaryType
binaryType 속성은
마지막으로
설정된 값을 반환한다.
RTCDataChannel 객체가
생성되면
binaryType 속성은
반드시 문자열
"arraybuffer"로 초기화해야 한다.
이
속성은 이진 데이터를 스크립트에 노출하는 방식을 제어한다.
Web Socket의 binaryType을 참조한다.
close()
RTCDataChannel을
닫는다.
해당 RTCDataChannel 객체를 이
피어가 생성했는지 원격
피어가 생성했는지와 관계없이 호출할 수 있다.
close 메서드가 호출되면 사용자
에이전트는 반드시 다음
단계를 실행해야 한다:
channel을 닫으려는 RTCDataChannel
객체로 둔다.
channel.[[ReadyState]]가
"closing" 또는
"closed"이면
이 단계들을 중단한다.
channel.[[ReadyState]]를
"closing"로 설정한다.
닫기 절차가 아직 시작되지 않았으면 시작한다.
send
send()
알고리즘에
설명된 단계를 실행하며, 인수 유형은 string 객체이다.
send
send()
알고리즘에
설명된 단계를 실행하며, 인수 유형은 Blob 객체이다.
send
send()
알고리즘에
설명된 단계를 실행하며, 인수 유형은 ArrayBuffer 객체이다.
send
send()
알고리즘에
설명된 단계를 실행하며, 인수 유형은 ArrayBufferView 객체이다.
send() 메서드는 서로 다른
데이터 인수 유형을 처리하도록 오버로드되어 있다. 어떤 버전의
메서드든 호출되면 사용자 에이전트는 반드시 다음
단계를
실행하는 절차를 실행해야 한다:
channel을 데이터를 전송할 RTCDataChannel 객체로
둔다.
channel.[[IsTransferable]]를
false로 설정한다.
channel.[[ReadyState]]가 "
open"이 아니면 예외를 던지는 절차로
InvalidStateError를 던진다.
메서드 인수의 유형에 해당하는 하위 단계를 실행한다:
string object:
data를 메서드의 인수를 UTF-8로 인코딩한 결과를 나타내는 바이트 버퍼로 둔다.
Blob object:
data를
Blob 객체가 나타내는 원시 데이터로 둔다.
ArrayBuffer object:
data를
ArrayBuffer 객체가 설명하는 버퍼에 저장된 데이터로 둔다.
ArrayBufferView object:
data를
ArrayBuffer 객체가 설명하는 버퍼
중 ArrayBufferView 객체가 참조하는
부분에 저장된 데이터로 둔다.
data의 바이트 크기가
maxMessageSize
값을 초과하면, 이는 channel
와 연결된 RTCSctpTransport의 값이다. 이 경우 예외를 던지는 절차로
TypeError를 던진다.
data를
channel의 기반 데이터
전송으로
전송하도록 큐에 넣는다. data를 넣기에 버퍼 공간이 부족하여
큐에 넣을 수 없으면 예외를 던지는 절차로
OperationError를 던진다.
[[BufferedAmount]] 슬롯의
값을 data의 바이트 크기만큼 늘린다.
WebIDLdictionary RTCDataChannelInit {
boolean ordered = true;
[EnforceRange] unsigned short maxPacketLifeTime;
[EnforceRange] unsigned short maxRetransmits;
USVString protocol = "";
boolean negotiated = false;
[EnforceRange] unsigned short id;
};
ordered of type boolean, defaulting to true
false로 설정하면 데이터가 순서와 다르게 전달되어도 된다. 기본값 true는 데이터가 순서대로 전달되도록 보장한다.
maxPacketLifeTime of type unsigned short
확인 응답을 받지 못했을 때 채널이 데이터를 전송하거나 재전송할 수 있는 시간을 밀리초 단위로 제한한다. 이 값이 사용자 에이전트가 지원하는 최대값을 초과하면 제한될 수 있다.
maxRetransmits of type unsigned short
성공적으로 전달되지 않았을 때 채널이 데이터를 재전송하는 횟수를 제한한다. 사용자 에이전트가 지원하는 최대값을 초과하면 이 값이 제한될 수 있다.
protocol of type USVString, defaulting to ""
이 채널에서 사용하는 하위 프로토콜 이름이다.
negotiated of type boolean, defaulting to
false
기본값
false는 사용자 에이전트가 채널을 대역
내에서 알리고 다른 피어가 대응하는
RTCDataChannel 객체를 전달하도록
지시한다.
true로 설정하면 애플리케이션이 채널을 협상하고 다른 피어에서
RTCDataChannel 객체를 같은
id로 생성해야 한다.
id of
type unsigned short
negotiated
가 true이면 채널 ID를 설정한다. negotiated가
false이면 무시한다.
WebIDLenum RTCDataChannelState {
"connecting",
"open",
"closing",
"closed"
};
| Enum value | Description |
|---|---|
connecting
|
사용자
에이전트가 기반 데이터 전송을 설정하려고
시도하고 있다. 이는
|
open
|
기반 데이터 전송이 설정되었으며 통신할 수 있다. |
closing
|
|
closed
|
datachannel 이벤트는 RTCDataChannelEvent 인터페이스를 사용한다.
WebIDL[Exposed=Window]
interface RTCDataChannelEvent : Event {
constructor(DOMString type, RTCDataChannelEventInit eventInitDict);
readonly attribute RTCDataChannel channel;
};
RTCDataChannelEvent.constructor()
channel of type
RTCDataChannel, readonly
channel 속성은
이벤트와 연결된 RTCDataChannel
객체를 나타낸다.
WebIDLdictionary RTCDataChannelEventInit : EventInit {
required RTCDataChannel channel;
};
channel of type RTCDataChannel, required
이
이벤트가 알릴 RTCDataChannel
객체이다.
RTCDataChannel 객체는 반드시 다음 조건 중 하나를 만족하면 가비지 컬렉션으로 수거되어서는 안 된다:
[[ReadyState]] 슬롯이 "
connecting
"이고, open,
message,
error, closing
또는 연결을 닫는 이벤트에 대해 이벤트 리스너가 하나 이상 등록되어 있다.
[[ReadyState]] 슬롯이 "
open
"이고,
message, error,
closing 또는
연결을 닫는 이벤트에 대해 이벤트 리스너가 하나 이상 등록되어 있다.
[[ReadyState]] 슬롯이 "
closing
"이고,
error 또는 연결을 닫는
이벤트에 대해 이벤트 리스너가 하나 이상 등록되어 있다.
기반 데이터 전송이 설정되어 있고 전송할 데이터가 큐에 들어 있다.
이
절은 RTCRtpSender
에서 RTCPeerConnection을 통해 DTMF(전화 키패드)
값을 보내는 인터페이스를 설명한다. DTMF를 다른 피어로 보내는 세부 사항은 [ RFC7874 ]에 설명되어 있다.
피어
간 DTMF API는 아래에 설명된 대로 RTCRtpSender 인터페이스를
확장한다.
WebIDL partial interface RTCRtpSender {
readonly attribute RTCDTMFSender? dtmf;
};
dtmf of type RTCDTMFSender, readonly,
nullable
값을
가져올 때 dtmf 속성은
[[Dtmf]] 내부 슬롯의 값을 반환한다. 이 값은 DTMF를 보내는 데 사용할 수 있는
RTCDTMFSender를 나타내며,
설정되지 않았으면
null이다. [[Dtmf]]
내부 슬롯은 RTCRtpSender의
[[SenderTrack]]의
종류가 "audio"일 때 설정된다.
RTCDTMFSender를 생성하는 절차를 실행하려면 사용자 에이전트는 반드시 다음 단계를 실행해야 한다:
dtmf를 새로 생성한 RTCDTMFSender 객체로 둔다.
dtmf에 [[Duration]] 내부 슬롯을 둔다.
dtmf에 [[InterToneGap]] 내부 슬롯을 둔다.
dtmf에 [[ToneBuffer]] 내부 슬롯을 둔다.
WebIDL[Exposed=Window]
interface RTCDTMFSender : EventTarget {
undefined insertDTMF(DOMString tones, optional unsigned long duration = 100, optional unsigned long interToneGap = 70);
attribute EventHandler ontonechange;
readonly attribute boolean canInsertDTMF;
readonly attribute DOMString toneBuffer;
};
ontonechange of type EventHandler
이
이벤트 핸들러의 이벤트 유형은 tonechange이다.
canInsertDTMF of type boolean, readonly
RTCDTMFSender
dtmfSender
가 DTMF를 보낼 수 있는지 나타낸다. 값을 가져올 때 사용자 에이전트는 반드시
DTMF 송신 가능 여부를 판단하는
절차를 dtmfSender에 대해 실행한 결과를 반환해야 한다.
toneBuffer of type
DOMString, readonly
toneBuffer 속성은
반드시 재생할 톤의 남은
목록을 반환해야 한다. 이 목록의 문법,
내용 및 해석은 insertDTMF를 참조한다.
insertDTMF
RTCDTMFSender 객체의 insertDTMF 메서드는 DTMF
톤을
보내는 데 사용한다.
tones 매개변수는 일련의 문자로 취급한다. 0부터 9, A부터 D, # 및 * 문자는 대응하는 DTMF 톤을 생성한다. a부터 d 문자는 반드시 입력 시 대문자로 정규화해야 하며 A부터 D와 동등하다. [RTCWEB-AUDIO ] 3절에 설명된 대로 0부터 9, A부터 D, # 및 * 문자의 지원은 필수이다. ',' 문자는 반드시 지원해야 하며, tones 매개변수의 다음 문자를 처리하기 전에 2초 지연을 나타낸다. 그 밖의 모든 문자(그리고 오직 그 밖의 문자만)는 반드시 인식되지 않는 문자로 간주해야 한다.
duration 매개변수는 tones 매개변수로 전달된 각 문자에 사용할 지속 시간을 ms 단위로 나타낸다. 지속 시간은 6000 ms를 초과하거나 40 ms 미만일 수 없다. 기본 지속 시간은 각 톤마다 100 ms이다.
interToneGap 매개변수는 톤 사이의 간격을 ms 단위로 나타낸다. 사용자 에이전트는 최소 30 ms, 최대 6000 ms로 제한한다. 기본값은 70 ms이다.
브라우저는 경우에 따라 duration과 interToneGap 시간을 늘려 DTMF의 시작 및 종료 시점이 RTP 패킷 경계에 맞도록 할 수 있다. 그러나 반드시 어느 쪽도 단일 RTP 오디오 패킷의 지속 시간보다 더 많이 늘려서는 안 된다.
insertDTMF()
메서드가 호출되면 사용자 에이전트는
반드시 다음 단계를 실행해야 한다:
RTCRtpSender로
둔다.
transceiver를 RTCRtpTransceiver
객체로 두며, 이 객체는 sender와 연결되어 있다.
RTCDTMFSender로 두며, 이는
sender와 연결되어 있다.
false를 반환하면 예외를 던지는 절차로 InvalidStateError를 던진다.
unrecognized 문자가 하나라도 포함되어 있으면 예외를 던지는 절차로 InvalidCharacterError를 던진다.
[[ToneBuffer]] 슬롯을
tones로 설정한다.
[[Duration]]
를
duration의 값으로 설정한다.
[[InterToneGap]]를
interToneGap의 값으로 설정한다.
[[Duration]]를 40 ms로 설정한다.
[[Duration]]를
6000 ms로 설정한다.
[[InterToneGap]]를 30 ms로 설정한다.
[[InterToneGap]]를 6000 ms로 설정한다.
sendrecv
"도
"sendonly"도 아니false를 반환하면 이 단계들을
중단한다.
[[ToneBuffer]] 슬롯이
빈 문자열을
포함하면 이벤트를 발생시키는 절차를 실행한다. 이름은 tonechange이고
RTCDTMFToneChangeEvent
인터페이스를 사용하며
tone
속성을 빈 문자열로
설정하고 대상은 RTCDTMFSender 객체로
한다. 그리고 이
단계들을 중단한다.
[[ToneBuffer]] 슬롯에서 첫
문자를 제거하고 그 문자를
tone으로 둔다.
","이면 연결된 RTP 미디어
스트림에서 톤 전송을 2000 ms
동안 지연시키고, 현재부터
2000 ms 뒤에
DTMF
재생 태스크 단계를 실행할 태스크를 큐에 넣는다.
","가 아니면 대응하는
RTP 미디어 스트림에서 적절한 코덱을 사용하여 tone을 [[Duration]]
ms 동안 재생하기 시작한다.
그런 다음 현재부터
[[Duration]] + [[InterToneGap]] ms
뒤에
실행될 태스크를 큐에 넣으며, 이 태스크는 DTMF 재생 태스크 단계를 실행한다.
tonechange이고
RTCDTMFToneChangeEvent
인터페이스를 사용하며
tone
속성을
tone으로 설정한다. 대상은 RTCDTMFSender 객체이다.
insertDTMF는
톤 버퍼를 대체하므로,
재생 중인 DTMF 톤에 톤을 추가하려면
insertDTMF
를 호출할 때
남은 톤([[ToneBuffer]] 슬롯에 저장됨)과 새
톤을 이어 붙인 문자열을 전달해야 한다. insertDTMF를
빈
tones 매개변수로 호출하면 현재 재생 중인 톤 이후에 재생하도록 큐에
넣은 모든 톤을 취소할 수 있다.
DTMF 송신 가능 여부를 판단하는 절차를 RTCDTMFSender
인스턴스 dtmfSender에 대해 실행하려면 사용자 에이전트는 반드시 다음 단계를 실행해야
한다:
RTCRtpSender로 두며,
이는 dtmfSender와 연결되어 있다.
RTCRtpTransceiver로 두며, 이는
sender와 연결되어 있다.
RTCPeerConnection로 두며, 이는
transceiver와 연결되어 있다.
RTCPeerConnectionState가 "
connected"가 아니면
false를 반환한다.
[[Stopping]]가
true이면 false를 반환한다.
[[SenderTrack]]가 null이면
false를 반환한다.
[[CurrentDirection]]가 "
sendrecv"도 "
sendonly
"도 아니면 false를 반환한다.
[[SendEncodings]][0].active가
false이면 false를 반환한다.
"audio/telephone-event"
인 코덱이
이 sender의 송신용으로 협상되지 않았으면 false를 반환한다.
true를 반환한다.
tonechange 이벤트는 RTCDTMFToneChangeEvent
인터페이스를 사용한다.
WebIDL[Exposed=Window]
interface RTCDTMFToneChangeEvent : Event {
constructor(DOMString type, optional RTCDTMFToneChangeEventInit eventInitDict = {});
readonly attribute DOMString tone;
};
RTCDTMFToneChangeEvent.constructor()
tone of type DOMString, readonly
tone 속성은
방금 재생을 시작한 톤의
문자("," 포함)를 포함한다(
insertDTMF 참조).
값이
빈 문자열이면 [[ToneBuffer]] 슬롯이
빈 문자열이고 이전 톤들의 재생이 완료되었음을
나타낸다.
WebIDL dictionary RTCDTMFToneChangeEventInit : EventInit {
DOMString tone = "";
};
tone of type DOMString, defaulting to ""
tone 속성은
방금 재생을 시작한 톤의
문자("," 포함)를 포함한다(
insertDTMF 참조).
값이
빈 문자열이면 [[ToneBuffer]] 슬롯이
빈 문자열이고 이전 톤들의 재생이 완료되었음을
나타낸다.
기본 통계 모델은 브라우저가 모니터링되는 객체의 통계 집합을 통계 객체 형태로 유지하는 것이다.
관련
객체들의 그룹은 선택자로 참조할 수 있다. 예를 들어 선택자는
MediaStreamTrack일 수 있다. 트랙이 유효한 선택자이려면
반드시
MediaStreamTrack이어야 하며, 통계 요청이 발행된
RTCPeerConnection 객체에서
송신하거나 수신하는 트랙이어야
한다. 호출하는 웹 애플리케이션은 선택자를
getStats()
메서드에
제공하며, 브라우저는
통계 선택 알고리즘에
따라 선택자와
관련된 통계 집합을 JavaScript로 내보낸다. 이 알고리즘은 선택자의 송신자 또는 수신자를 입력으로 받는다.
통계 객체에서 반환하는
통계는 반복된 질의를 RTCStats의
id 사전 멤버로 연결할 수 있도록 설계되어 있다.
따라서
웹 애플리케이션은 주어진 기간의 시작과 끝에서 측정을 요청하여 그 기간에
걸친 측정을 수행할 수 있다.
일부
예외를 제외하면 모니터링되는 객체는
생성된 뒤 연결된 RTCPeerConnection이
존재하는 동안 유지된다. 따라서 해당 피어 연결이 닫힌 뒤에도
getStats()
결과에서 그 통계를 사용할 수 있다.
여기서 연결을 닫는 것은 close 절차를 뜻한다.
일부 모니터링되는 객체만 더 짧은 수명을 가진다. 이러한 객체의 통계는 이후 getStats() 결과에서 더 이상 사용할 수 없다. [ WEBRTC-STATS]의 객체 설명에는 이러한 모니터링되는 객체가 언제 삭제되는지 설명되어 있다.
통계
API는 아래에 설명된 대로 RTCPeerConnection 인터페이스를
확장한다.
WebIDL partial interface RTCPeerConnection {
Promise<RTCStatsReport> getStats(optional MediaStreamTrack? selector = null);
};
getStats
주어진 선택자에 대한 통계를 수집하고 결과를 비동기적으로 보고한다.
getStats()
메서드가 호출되면 사용자 에이전트는
반드시 다음 단계를 실행해야 한다:
selectorArg를 메서드의 첫 번째 인수로 둔다.
connection를 메서드가 호출된 RTCPeerConnection
객체로 둔다.
selectorArg가 null이면
selector를 null로 둔다.
selectorArg가 MediaStreamTrack이면
selector를 RTCRtpSender 또는
RTCRtpReceiver로 두되,
connection에 속하며
track 속성이
selectorArg와 일치하는 것으로 한다.
그러한 송신자나 수신자가 없거나 이 조건에 맞는 송신자
또는 수신자가 둘 이상이면, 거부된 상태인 프로미스를 반환한다. 이때 거부 사유는 새로 생성한 InvalidAccessError이다.
p를 새 프로미스로 둔다.
다음 단계를 병렬로 실행한다:
selector가 나타내는 통계를 통계 선택 알고리즘에 따라 수집한다.
전역 태스크를 큐에 넣는다. 이 태스크의 소스는 네트워킹 태스크 소스이고,
현재 렐름의 전역 객체를
global로 사용한다. 태스크는 결정 절차로
p를 결정하며, 그 값은 수집한 통계를 포함하는 결과 RTCStatsReport
객체이다.
p를 반환한다.
getStats()
메서드는 성공
결과를 RTCStatsReport 객체 형태로 전달한다.
RTCStatsReport 객체는
검사한 객체를 식별하는
문자열(id 속성으로서 RTCStats
인스턴스에 존재함)과 대응하는 RTCStats 파생 사전
사이의 맵이다.
RTCStatsReport
는 여러 RTCStats 파생
사전으로 구성될 수 있으며, 각
사전은 구현이 선택자와
관련 있다고 판단한 기반 객체 하나의 통계를 보고한다. 선택자에 대한 합계는 특정
유형의 통계를 모두 더하여 구한다. 예를 들어 RTCRtpSender가
네트워크로 트랙을 전달하는 데 여러 SSRC를 사용하면,
RTCStatsReport에는 SSRC마다
하나의 RTCStats 파생
사전이 포함될 수 있다(
ssrc 통계 속성의 값으로 구별할 수 있음).
RTCStats 사전은
통계
객체를
나타내며, 이 객체는 특정 모니터링되는 객체를 검사하여 구성된다.
RTCStats
사전은 timestamp와
type 같은 기본 속성의 집합을 지정하는 기반 유형이다. 구체적인 통계는
RTCStats 사전을 확장하여 추가한다.
통계 이름은 표준화되어 있지만, 특정 구현은 실험적인 값이나 웹 애플리케이션이 아직 알지 못하는 값을 사용할 수 있다. 따라서 애플리케이션은 반드시 알 수 없는 통계를 처리할 준비가 되어 있어야 한다.
계산에서
타당한 값을 얻으려면 통계가 서로 동기화되어야
한다. 예를 들어
bytesSent와
packetsSent를 모두 보고한다면,
"평균 패킷 크기"를 "바이트 / 패킷"으로 계산할 수
있도록 둘 다 같은 구간에 대해 보고해야 한다.
구간이 다르면 오류가 생긴다. 따라서 구현은 반드시
RTCStats 파생 사전의 모든 통계에
대해 동기화된 값을 반환해야 한다.
WebIDLdictionary RTCStats {
required DOMHighResTimeStamp timestamp;
required RTCStatsType type;
required DOMString id;
};
RTCStats Members
timestamp of type DOMHighResTimeStamp
타임스탬프는
의 유형은 timestampDOMHighResTimeStamp
이며, 이 객체와 연결된 타임스탬프이다. 시각은
UNIX
에포크(1월 1일, [HIGHRES-TIME]1970년, 로 표현되며 다음 값으로 정의한다:
Performance.timeOrigin UTC)를 기준으로 한다 +
Performance.now() (정보를
수집하는 시점에 평가한 값). 원격 소스에서 온 통계(예:
수신한 RTCP 패킷에서 온 통계)의 경우,
timestamp는
정보가 로컬 끝점에 도착한
시각을 나타낸다. 해당되는 경우 원격
타임스탬프는 RTCStats 파생 사전의
추가 필드에서 찾을 수 있다.
type of type RTCStatsType
이 객체의 유형이다.
id of type DOMString
고유
id로서,
이 RTCStats 객체를 생성하기 위해 검사한 객체와 연결되어 있다. 서로 다른 두
RTCStats 객체를
서로 다른 두
RTCStatsReport 객체에서 가져왔을 때, 반드시 같은 기반 객체를
검사하여 생성된 것이라면 같은 ID를 가져야 한다.
통계 ID는 절대로 애플리케이션이 예측할 수 있어서는 안 된다. 이는 애플리케이션이 특정 사용자 에이전트의 ID 생성 방식에 의존하지 못하게 한다. 특정 통계 객체의 ID를 이미 읽지 않았다면 그 ID로 통계 객체를 가져올 수 없기 때문이다.
사용자 에이전트는 위 요건을 충족하는 한 ID의 형식을 자유롭게 선택할 수 있다.
사용자 에이전트는 피어 연결마다 고유한 솔트를 사용하는 한 해시 함수로 예측 가능하게 생성된 문자열을 예측할 수 없는 문자열로 바꿀 수 있다. 따라서 구현은 내부적으로 예측 가능한 ID를 사용할 수 있으며, 이는 getStats() 호출 전반에 걸쳐 통계 객체가 안정적인 ID를 유지하도록 보장하기 쉽게 만들 수 있다.
RTCStatsType의 유효한 값
집합과 그 값이 나타내는 RTCStats 파생 사전은 [
WEBRTC-STATS ]에 문서화되어 있다.
통계 선택 알고리즘은 다음과 같다:
RTCStatsReport로 둔다.
null
이면 전체 connection의 통계를 수집하여
result에 추가하고 result를 반환한 다음 이 단계들을 중단한다.
RTCRtpSender, 다음 객체들에 대한 통계를
수집하여 다음 결과에 추가 한다: result:
RTCOutboundRtpStreamStats
객체로서 selector가 송신하는 RTP 스트림을 나타내는 객체들이다.
RTCOutboundRtpStreamStats 객체가 직접 또는 간접으로
참조하는 모든 통계 객체이다.
RTCRtpReceiver, 다음 객체들에 대한 통계를
수집하여 다음 결과에 추가 한다: result:
RTCInboundRtpStreamStats
객체로서 selector가 수신하는 RTP 스트림을 나타내는 객체들이다.
RTCInboundRtpStreamStats가 직접 또는 간접으로 참조하는 모든 통계 객체이다.
[ WEBRTC-STATS ]에 나열된 통계는 다양한 사용 사례를 다루기 위한 것이다. 모든 WebRTC 구현이 그 전부를 구현해야 하는 것은 아니다.
구현은
반드시 다음
type의 통계 생성을 지원해야 한다. 이는 대응하는 객체가
RTCPeerConnection
에
존재할 때
적용되며, RTCStats 사전에 정의된 일반 필드 외에 해당 객체에 유효한 경우 나열된 필드들도 포함해야 한다:
구현은 경우에 따라 [ WEBRTC-STATS ]에 정의된 다른 어떤 통계의 생성도 지원할 수 있으며, 경우에 따라 문서화되지 않은 통계를 생성할 수도 있다.
사용자가 좋지 않은 음질을 경험하고 있으며 애플리케이션이 그 원인이 패킷 손실인지 판단하려는 경우를 생각해 보자. 다음 예제 코드를 사용할 수 있다:
async function gatherStats(pc) {
try {
const [sender] = pc.getSenders();
const baselineReport = await sender.getStats();
await new Promise(resolve => setTimeout(resolve, aBit)); // wait a bit
const currentReport = await sender.getStats();
// compare the elements from the current report with the baseline
for (const now of currentReport.values()) {
if (now.type != 'outbound-rtp') continue;
// get the corresponding stats from the baseline report
const base = baselineReport.get(now.id);
if (!base) continue;
const remoteNow = currentReport.get(now.remoteId);
const remoteBase = baselineReport.get(base.remoteId);
const packetsSent = now.packetsSent - base.packetsSent;
const packetsReceived = remoteNow.packetsReceived -
remoteBase.packetsReceived;
const fractionLost = (packetsSent - packetsReceived) / packetsSent;
if (fractionLost > 0.3) {
// if fractionLost is > 0.3, we have probably found the culprit
}
}
} catch (err) {
console.error(err);
}
}
MediaStreamTrack 인터페이스는 [
GETUSERMEDIA] 명세에 정의된 대로 일반적으로 오디오
또는
비디오 데이터의 스트림을 나타낸다. 하나 이상의 MediaStreamTrack
을 MediaStream에 모을 수 있다(엄밀히 말하면, MediaStream은
[GETUSERMEDIA]에 정의된 대로 0개 이상의
MediaStreamTrack 객체를 포함할 수 있다).
MediaStreamTrack은 예를 들어 로컬
카메라뿐
아니라 원격 피어에서 오거나 원격 피어로 보내는
미디어 흐름도 나타내도록 확장할 수 있다.
이 절에서는 MediaStreamTrack 객체에서 이 기능을 활성화하는
데 필요한 확장을 설명한다. 미디어를 피어로 전송하는 방식은 [
RFC8834], [RFC7874] 및 [RFC8835]에 설명되어 있다.
다른 피어로
전송된 MediaStreamTrack은 수신자에게 정확히
하나의 MediaStreamTrack으로 나타난다. 피어는 이
명세를 지원하는 사용자 에이전트로 정의된다. 또한
송신 측 애플리케이션은 어떤 MediaStream 객체에 해당
MediaStreamTrack이 속하는지 나타낼 수 있다. 수신 측의 대응하는
MediaStream
객체는 아직 없으면 생성되며
그에 따라 내용이 채워진다.
이
문서의 앞부분에서도 설명한 대로, 애플리케이션은
RTCRtpSender와 RTCRtpReceiver
객체를
사용하여 MediaStreamTrack의 전송과 수신을 더 세밀하게 제어할 수 있다.
채널은
Media Capture and Streams 명세에서 다루는 가장 작은
단위이다. 채널들은 함께 인코딩되어 예를 들어 하나의 RTP
페이로드 유형으로 전송되도록 의도되어 있다. 코덱이 함께 인코딩해야
하는 모든 채널은 반드시 같은
MediaStreamTrack에 있어야 하며, 코덱은 가급적 트랙의 모든 채널을
인코딩하거나 버릴 수 있어야 한다.
주어진
MediaStreamTrack의
입력과 출력이라는 개념은 네트워크로 전송되는 MediaStreamTrack 객체에도
적용된다. MediaStreamTrack이
RTCPeerConnection 객체에
의해 생성되면(이 문서의 앞부분에 설명된
대로), 원격 피어에서 받은 데이터를 입력으로 사용한다. 마찬가지로 로컬 소스에서
온 MediaStreamTrack(예:
[GETUSERMEDIA]를
통한 카메라)은
RTCPeerConnection
객체와 함께 사용되면 원격 피어로 전송되는 것을 나타내는 출력을 갖는다.
MediaStream과 MediaStreamTrack
객체의 복제라는 개념은 [GETUSERMEDIA]에 설명된 대로
여기에도 적용된다. 예를 들어 화상 회의에서 이
기능을 사용하면 사용자의 카메라와 마이크에서 온 로컬
비디오를 로컬 모니터에 표시하면서 원격 피어에는 오디오만
전송할 수 있다(예: 사용자가 "비디오 음소거" 기능을
사용한 경우). 서로 다른 MediaStreamTrack 객체를 새로운
MediaStream
객체로 조합하는 것은 특정 상황에서 유용하다.
이
문서에서는 다음 객체들에
대해 RTCPeerConnection
과 함께 사용할 때 관련된 측면만 지정한다. [
GETUSERMEDIA] 문서에 있는 객체의 원래
정의에서
MediaStream과
MediaStreamTrack의 사용에 관한 일반 정보를 참조하기 바란다.
id 속성은 MediaStream에
지정되어 있으며 이 스트림에 고유한 ID를
반환한다. 따라서 RTCPeerConnection API의 원격 끝점에서 스트림을 알아볼 수 있다.
MediaStream이 원격 피어에서 얻은 스트림을
나타내기 위해 생성되면 id 속성은
원격
소스가 제공한 정보로 초기화한다.
id는 MediaStream 객체에서 스트림의
소스에 대해 고유하지만, 그렇다고 중복이 생길 수
없다는 뜻은 아니다. 예를 들어 로컬에서
생성된 스트림의 트랙을 한 사용자 에이전트에서 원격
피어로 RTCPeerConnection을 사용하여
보낸 다음, 같은
방식으로 원래 사용자 에이전트에 돌려보낼 수 있다. 그러면
원래 사용자 에이전트에는 같은 id를 가진 여러 스트림(로컬에서 생성한
스트림과 원격 피어에서 받은 스트림)이 존재한다.
MediaStreamTrack 객체의 MediaStream
에 대한 참조는 비로컬 미디어 소스의 경우 항상 강한 참조이다.
이는 MediaStreamTrack마다 존재하는 RTP 소스의 경우이며 해당 트랙은 RTCRtpReceiver와
연결되어 있다.
RTCRtpReceiver가 RTP 소스에서 데이터를
받을
때마다, 대응하는 MediaStreamTrack이 음소거되어 있으나 종료되지는 않았고,
[[Receptive]] 슬롯이 해당 RTCRtpTransceiver 객체에서, 즉 이
RTCRtpReceiver가 속하는
객체에서 true이면, 반드시 태스크를
큐에 넣어 음소거 상태를 설정하는 절차로 대응하는
MediaStreamTrack의 음소거 상태를 false로 설정해야 한다.
RTCRtpReceiver가 수신하는
RTP 소스 미디어 스트림의 SSRC 중 하나가 BYE 수신이나
시간 초과로 제거되면, 반드시 태스크를 큐에 넣어 음소거 상태를 설정하는
절차로
대응하는 MediaStreamTrack의 음소거 상태를 true로 설정해야 한다.
setRemoteDescription
도 음소거 상태 설정을 유발할 수 있으며, 이때
track의 음소거 상태를 true로 설정한다.
트랙을 추가하는, 트랙을 제거하는 및 트랙의 음소거 상태를 설정하는 절차는 [ GETUSERMEDIA ]에 지정되어 있다.
MediaStreamTrack인 track이 RTCRtpReceiver
receiver에 의해 생성되었고 ended
상태가 되면[GETUSERMEDIA](예:
receiver.track.stop 호출을 통해), 사용자 에이전트는 경우에 따라 수신 스트림에
할당한 리소스를 해제하도록 선택할 수 있다. 예를
들어 receiver의 디코더를 끌 수 있다.
제약
및 제약 가능한 속성의 개념은
MediaTrackConstraints(MediaStreamTrack.getConstraints(), MediaStreamTrack.applyConstraints())와 MediaTrackSettings(
MediaStreamTrack.getSettings())를
포함하여 [GETUSERMEDIA]에 개략적으로 설명되어
있다. 그러나 피어 연결에서 온 트랙의 제약
가능한 속성은 getUserMedia()에서
온 트랙의 속성과 다르다. MediaStreamTrack
중 원격 소스에서 온 트랙에 적용되는 제약과 설정은
여기에서 정의한다. 원격 트랙의 설정은 가장 최근에 받은 프레임을 나타낸다.
MediaStreamTrack.getCapabilities()는
반드시 항상 빈 집합을 반환해야 하며,
MediaStreamTrack.applyConstraints()는
반드시 여기에서 정의한 제약에 대해 원격 트랙에서 항상 OverconstrainedError
로 거부되어야
한다.
다음의
제약 가능한 속성은 비디오
MediaStreamTrack 중 원격 소스에서 온 트랙에 적용되도록 정의된다:
| Property Name | Values | Notes |
|---|---|---|
| width |
ConstrainULong
|
설정으로서 는 가장 최근에 수신한 프레임의 너비를 나타내 는 값이며 이 너비의 단위는 픽셀이다. |
| height |
ConstrainULong
|
설정으로서 는 가장 최근에 수신한 프레임의 높이를 나타내 는 값이며 이 높이의 단위는 픽셀이다. |
| frameRate |
ConstrainDouble
|
설정으로서 는 최근에 수신된 프레임들 을 기준 으로 계산한 프레임 속도의 추정값 을 나타내 는 설정값이다. |
| aspectRatio |
ConstrainDouble
|
설정으로서 는 가장 최근 프레임 의 종횡비 를 나타낸다. 이는 픽셀 단위의 너비를 픽셀 단위 의 높이 로 나눈 값이며 소수점 아래 열 번째 자리 까지 반올림한 double 값 으로 표현 된다. |
이
문서는 오디오
MediaStreamTrack 중 원격 소스에서 온 트랙에 적용되는 제약 가능한 속성을 정의하지 않는다.
이 절은 비규범적이다.
두 피어가 서로 연결을 설정하기로 결정하면 양쪽 모두 다음 단계를 거친다. STUN/TURN 서버 구성은 공개 IP 주소 등을 알아내거나 NAT 통과를 설정하는 데 사용할 수 있는 서버를 설명한다. 또한 두 피어는 처음에 통신하기로 합의하는 데 사용한 것과 같은 대역 외 메커니즘을 사용하여 시그널링 채널의 데이터를 서로에게 보내야 한다.
const signaling = new SignalingChannel(); // handles JSON.stringify/parse
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);
// send any ice candidates to the other peer
pc.onicecandidate = ({candidate}) => signaling.send({candidate});
// let the "negotiationneeded" event trigger offer generation
pc.onnegotiationneeded = async () => {
try {
await pc.setLocalDescription();
// send the offer to the other peer
signaling.send({description: pc.localDescription});
} catch (err) {
console.error(err);
}
};
pc.ontrack = ({track, streams}) => {
// once media for a remote track arrives, show it in the remote video element
track.onunmute = () => {
// don't set srcObject again if it is already set.
if (remoteView.srcObject) return;
remoteView.srcObject = streams[0];
};
};
// call start() to initiate
function start() {
addCameraMic();
}
// add camera and microphone to connection
async function addCameraMic() {
try {
// get a local stream, show it in a self-view and add it to be sent
const stream = await navigator.mediaDevices.getUserMedia(constraints);
for (const track of stream.getTracks()) {
pc.addTrack(track, stream);
}
selfView.srcObject = stream;
} catch (err) {
console.error(err);
}
}
signaling.onmessage = async ({data: {description, candidate}}) => {
try {
if (description) {
await pc.setRemoteDescription(description);
// if we got an offer, we need to reply with an answer
if (description.type == 'offer') {
if (!selfView.srcObject) {
// blocks negotiation on permission (not recommended in production code)
await addCameraMic();
}
await pc.setLocalDescription();
signaling.send({description: pc.localDescription});
}
} else if (candidate) {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
};
두 피어가 서로 연결을 설정하기로 결정하고, 미디어를 즉시 보내고 받을 준비가 되도록 ICE, DTLS 및 미디어 연결을 미리 준비하려는 경우 양쪽 모두 다음 단계를 거친다.
const signaling = new SignalingChannel(); // handles JSON.stringify/parse
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
let pc;
let audio;
let video;
let started = false;
// Call warmup() before media is ready, to warm-up ICE, DTLS, and media.
async function warmup(isAnswerer) {
pc = new RTCPeerConnection(configuration);
if (!isAnswerer) {
audio = pc.addTransceiver('audio');
video = pc.addTransceiver('video');
}
// send any ice candidates to the other peer
pc.onicecandidate = ({candidate}) => signaling.send({candidate});
// let the "negotiationneeded" event trigger offer generation
pc.onnegotiationneeded = async () => {
try {
await pc.setLocalDescription();
// send the offer to the other peer
signaling.send({description: pc.localDescription});
} catch (err) {
console.error(err);
}
};
pc.ontrack = async ({track, transceiver}) => {
try {
// once media for the remote track arrives, show it in the video element
event.track.onunmute = () => {
// don't set srcObject again if it is already set.
if (!remoteView.srcObject) {
remoteView.srcObject = new MediaStream();
}
remoteView.srcObject.addTrack(track);
}
if (isAnswerer) {
if (track.kind == 'audio') {
audio = transceiver;
} else if (track.kind == 'video') {
video = transceiver;
}
if (started) await addCameraMicWarmedUp();
}
} catch (err) {
console.error(err);
}
};
try {
// get a local stream, show it in a self-view and add it to be sent
selfView.srcObject = await navigator.mediaDevices.getUserMedia(constraints);
if (started) await addCameraMicWarmedUp();
} catch (err) {
console.error(err);
}
}
// call start() after warmup() to begin transmitting media from both ends
function start() {
signaling.send({start: true});
signaling.onmessage({data: {start: true}});
}
// add camera and microphone to already warmed-up connection
async function addCameraMicWarmedUp() {
const stream = selfView.srcObject;
if (audio && video && stream) {
await Promise.all([
audio.sender.replaceTrack(stream.getAudioTracks()[0]),
video.sender.replaceTrack(stream.getVideoTracks()[0]),
]);
}
}
signaling.onmessage = async ({data: {start, description, candidate}}) => {
if (!pc) warmup(true);
try {
if (start) {
started = true;
await addCameraMicWarmedUp();
} else if (description) {
await pc.setRemoteDescription(description);
// if we got an offer, we need to reply with an answer
if (description.type == 'offer') {
await pc.setLocalDescription();
signaling.send({description: pc.localDescription});
}
} else {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
};
클라이언트가 여러 RTP 인코딩(동시 송출)을 서버로 보내려고 한다.
const signaling = new SignalingChannel(); // handles JSON.stringify/parse
const constraints = {audio: true, video: true};
const configuration = {'iceServers': [{'urls': 'stun:stun.example.org'}]};
let pc;
// call start() to initiate
async function start() {
pc = new RTCPeerConnection(configuration);
// let the "negotiationneeded" event trigger offer generation
pc.onnegotiationneeded = async () => {
try {
await pc.setLocalDescription();
// send the offer to the other peer
signaling.send({description: pc.localDescription});
} catch (err) {
console.error(err);
}
};
try {
// get a local stream, show it in a self-view and add it to be sent
const stream = await navigator.mediaDevices.getUserMedia(constraints);
selfView.srcObject = stream;
pc.addTransceiver(stream.getAudioTracks()[0], {direction: 'sendonly'});
pc.addTransceiver(stream.getVideoTracks()[0], {
direction: 'sendonly',
sendEncodings: [
{rid: 'q', scaleResolutionDownBy: 4.0}
{rid: 'h', scaleResolutionDownBy: 2.0},
{rid: 'f'},
]
});
} catch (err) {
console.error(err);
}
}
signaling.onmessage = async ({data: {description, candidate}}) => {
try {
if (description) {
await pc.setRemoteDescription(description);
// if we got an offer, we need to reply with an answer
if (description.type == 'offer') {
await pc.setLocalDescription();
signaling.send({description: pc.localDescription});
}
} else if (candidate) {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
};
이
예제는 RTCDataChannel 객체를
생성하고 채널을 다른 피어에 연결하는 데 필요한 제안/응답 교환을
수행하는 방법을 보여 준다. RTCDataChannel은
사용자 입력용 input 필드를 사용하는 간단한
채팅 애플리케이션에서 사용된다.
const signaling = new SignalingChannel(); // handles JSON.stringify/parse
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
let pc, channel;
// call start() to initiate
function start() {
pc = new RTCPeerConnection(configuration);
// send any ice candidates to the other peer
pc.onicecandidate = ({candidate}) => signaling.send({candidate});
// let the "negotiationneeded" event trigger offer generation
pc.onnegotiationneeded = async () => {
try {
await pc.setLocalDescription();
// send the offer to the other peer
signaling.send({description: pc.localDescription});
} catch (err) {
console.error(err);
}
};
// create data channel and setup chat using "negotiated" pattern
channel = pc.createDataChannel('chat', {negotiated: true, id: 0});
channel.onopen = () => input.disabled = false;
channel.onmessage = ({data}) => showChatMessage(data);
input.onkeydown = ({key}) => {
if (key != 'Enter') return;
channel.send(input.value);
}
}
signaling.onmessage = async ({data: {description, candidate}}) => {
if (!pc) start();
try {
if (description) {
await pc.setRemoteDescription(description);
// if we got an offer, we need to reply with an answer
if (description.type == 'offer') {
await pc.setLocalDescription();
signaling.send({description: pc.localDescription});
}
} else if (candidate) {
await pc.addIceCandidate(candidate);
}
} catch (err) {
console.error(err);
}
};
이는 두 브라우저 사이에서 가능한 호출 흐름의 한 예를 보여 준다. 로컬 미디어에 접근하는 절차나 발생하는 모든 콜백을 보여 주는 대신, 주요 이벤트와 메시지만 보여 주도록 단순화한다.
예제들은
sender가 RTCRtpSender라고 가정한다.
DTMF 신호 "1234"를 각 톤당 500 ms의 지속 시간으로 전송한다:
if (sender.dtmf.canInsertDTMF) {
const duration = 500;
sender.dtmf.insertDTMF('1234', duration);
} else {
console.log('DTMF function not available');
}
DTMF 신호 "123"을 보내고 "2"를 보낸 뒤 중단한다.
async function sendDTMF() {
if (sender.dtmf.canInsertDTMF) {
sender.dtmf.insertDTMF('123');
await new Promise(r => sender.dtmf.ontonechange = e => e.tone == '2' && r());
// empty the buffer to not play any tone after "2"
sender.dtmf.insertDTMF('');
} else {
console.log('DTMF function not available');
}
}
DTMF
신호 "1234"를 보내고, 톤이 재생되는 동안
lightKey(key)를 사용하여 활성 키에
불을 켠다(lightKey("")가 모든 키의
불을 끈다고 가정함):
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
if (sender.dtmf.canInsertDTMF) {
const duration = 500; // ms
sender.dtmf.insertDTMF(sender.dtmf.toneBuffer + '1234', duration);
sender.dtmf.ontonechange = async ({tone}) => {
if (!tone) return;
lightKey(tone); // light up the key when playout starts
await wait(duration);
lightKey(''); // turn off the light after tone duration
};
} else {
console.log('DTMF function not available');
}
톤 버퍼에 추가하는 것은 언제나 안전하다. 이 예제는 톤 재생이 시작되기 전과 재생 중에 모두 추가한다.
if (sender.dtmf.canInsertDTMF) {
sender.dtmf.insertDTMF('123');
// append more tones to the tone buffer before playout has begun
sender.dtmf.insertDTMF(sender.dtmf.toneBuffer + '456');
sender.dtmf.ontonechange = ({tone}) => {
// append more tones when playout has begun
if (tone != '1') return;
sender.dtmf.insertDTMF(sender.dtmf.toneBuffer + '789');
};
} else {
console.log('DTMF function not available');
}
1초 길이의 "1" 톤에 이어 2초 길이의 "2" 톤을 보낸다:
if (sender.dtmf.canInsertDTMF) {
sender.dtmf.ontonechange = ({tone}) => {
if (tone == '1') {
sender.dtmf.insertDTMF(sender.dtmf.toneBuffer + '2', 2000);
}
};
sender.dtmf.insertDTMF(sender.dtmf.toneBuffer + '1', 1000);
} else {
console.log('DTMF function not available');
}
완전
협상은 이 비대칭 작업을 애플리케이션의
다른 부분에서 추상화하여 협상을 투명하게
관리하기 위한 권장 패턴이다. 이
패턴은 한쪽이 항상 제안자인
방식보다 장점이 있다. 충돌(glare, "
stable" 상태가 아닐 때
제안이 들어오는 것)의 위험 없이 애플리케이션이 양쪽 피어 연결 객체에서 동시에 작업할 수 있기 때문이다. 애플리케이션의
다른 부분은 시그널링 상태의 경쟁을 걱정하지 않고 모든 수정 메서드와 속성을 사용할 수 있다.
두 피어에 서로 다른 역할을 부여하고 그 사이의 시그널링 충돌을 해결하는 동작을 지정한다:
양보 측 피어는 수신 제안과의 충돌을 피하기 위해 롤백을 사용한다.
비양보 측 피어는 자신의 제안과 충돌하는 수신 제안을 무시한다.
두 피어는 함께 애플리케이션의 다른 부분을 위해 교착 상태가 생기지 않도록 시그널링을 관리한다. 예제는 지정된 역할을 나타내는 polite 불리언 변수가 있다고 가정한다:
const signaling = new SignalingChannel(); // handles JSON.stringify/parse
const constraints = {audio: true, video: true};
const configuration = {iceServers: [{urls: 'stun:stun.example.org'}]};
const pc = new RTCPeerConnection(configuration);
// call start() anytime on either end to add camera and microphone to connection
async function start() {
try {
const stream = await navigator.mediaDevices.getUserMedia(constraints);
for (const track of stream.getTracks()) {
pc.addTrack(track, stream);
}
selfView.srcObject = stream;
} catch (err) {
console.error(err);
}
}
pc.ontrack = ({track, streams}) => {
// once media for a remote track arrives, show it in the remote video element
track.onunmute = () => {
// don't set srcObject again if it is already set.
if (remoteView.srcObject) return;
remoteView.srcObject = streams[0];
};
};
// - The perfect negotiation logic, separated from the rest of the application ---
// keep track of some negotiation state to prevent races and errors
let makingOffer = false;
let ignoreOffer = false;
let isSettingRemoteAnswerPending = false;
// send any ice candidates to the other peer
pc.onicecandidate = ({candidate}) => signaling.send({candidate});
// let the "negotiationneeded" event trigger offer generation
pc.onnegotiationneeded = async () => {
try {
makingOffer = true;
await pc.setLocalDescription();
signaling.send({description: pc.localDescription});
} catch (err) {
console.error(err);
} finally {
makingOffer = false;
}
};
signaling.onmessage = async ({data: {description, candidate}}) => {
try {
if (description) {
// An offer may come in while we are busy processing SRD(answer).
// In this case, we will be in "stable" by the time the offer is processed
// so it is safe to chain it on our Operations Chain now.
const readyForOffer =
!makingOffer &&
(pc.signalingState == "stable" || isSettingRemoteAnswerPending);
const offerCollision = description.type == "offer" && !readyForOffer;
ignoreOffer = !polite && offerCollision;
if (ignoreOffer) {
return;
}
isSettingRemoteAnswerPending = description.type == "answer";
await pc.setRemoteDescription(description); // SRD rolls back as needed
isSettingRemoteAnswerPending = false;
if (description.type == "offer") {
await pc.setLocalDescription();
signaling.send({description: pc.localDescription});
}
} else if (candidate) {
try {
await pc.addIceCandidate(candidate);
} catch (err) {
if (!ignoreOffer) throw err; // Suppress ignored offer's candidates
}
}
} catch (err) {
console.error(err);
}
}
이는
타이밍에 민감하며, 처리 중인 다른 시그널링 메시지와의 경쟁을 피하기 위해 의도적으로
setLocalDescription의
인수 없는 버전과
setRemoteDescription
의
암묵적 롤백 버전을 사용한다.
ignoreOffer 변수는 비양보 측의
RTCPeerConnection 객체에
무시된 제안을 알리지 않기 때문에
필요하다. 따라서 그러한 제안에 속한 수신 후보에서
발생하는 오류를 억제해야 한다.
일부
연산은 RTCError를 던지거나 이벤트로 발생시킨다.
이는 WebRTC에 특화된 추가 정보를 담는
DOMException
의 확장이다.
WebIDL[Exposed=Window]
interface RTCError : DOMException {
constructor(RTCErrorInit init, optional DOMString message = "");
readonly attribute RTCErrorDetailType errorDetail;
readonly attribute long? sdpLineNumber;
readonly attribute long? sctpCauseCode;
readonly attribute unsigned long? receivedAlert;
readonly attribute unsigned long? sentAlert;
};
constructor()
다음 단계를 실행한다:
errorDetail of type RTCErrorDetailType, readonly
발생한 오류 유형을 나타내는 WebRTC 전용 오류 코드이다.
sdpLineNumber of type long, readonly, nullable
errorDetail이
"
sdp-syntax-error
"이면
오류가 감지된 행 번호이다(첫 행의 번호는
1).
sctpCauseCode of type long, readonly, nullable
errorDetail이
"sctp-failure"이면
실패한 SCTP
협상의 SCTP 원인 코드이다.
receivedAlert of type unsigned long, readonly, nullable
errorDetail이
"dtls-failure"이고
치명적 DTLS
경고를 받았으면 수신한 DTLS 경고의 값이다.
sentAlert of type unsigned long, readonly, nullable
errorDetail이
"dtls-failure"이고
치명적 DTLS
경고를 보냈으면 전송한 DTLS 경고의 값이다.
RTCError에 정의된 모든 속성은 구현 부족으로
인해 제거될 수 있는 항목(at risk)으로 표시되어 있다(errorDetail,
sdpLineNumber, sctpCauseCode, receivedAlert 및
sentAlert).
여기에는
DOMException에서 상속한 속성은 포함되지 않는다.
WebIDLdictionary RTCErrorInit {
required RTCErrorDetailType errorDetail;
long sdpLineNumber;
long sctpCauseCode;
unsigned long receivedAlert;
unsigned long sentAlert;
};
errorDetail, sdpLineNumber, sctpCauseCode,
receivedAlert 및 sentAlert는 RTCErrorInit
의 멤버이며, RTCError의 같은 이름의 속성과 정의가 동일하다.
WebIDLenum RTCErrorDetailType {
"data-channel-failure",
"dtls-failure",
"fingerprint-failure",
"sctp-failure",
"sdp-syntax-error",
"hardware-encoder-not-available",
"hardware-encoder-error"
};
| Enum value | Description |
|---|---|
data-channel-failure
|
데이터 채널이 실패한 상태가 되었다. |
dtls-failure
|
DTLS 협상 이 실패했 거나 치명적인 오류 로 인해 연결
이 종료된 상태이다. 다음 필드 는: message
이며 여기에 오류의 성격 과 관련된 정보 가 들어 있다.
치명적인 DTLS 경고 를 수신했다면 다음 receivedAlert
속성의 값으로 는 수신한 해당 DTLS 경고의 값이 설정 된다. 반대로 치명적인 DTLS
경고 가 송신된 경우 에는 다음 sentAlert 속성의
값으로는 전송한 해당 DTLS 경고가 나타내는 경고의 값이 그대로 설정된다.
|
fingerprint-failure
|
해당 RTCDtlsTransport의 원격
인증서 가 SDP에 제공된 어떠한
지문과도 일치하지 않았다. 원격 피어가 제공된 지문 으로 로컬 인증서 를
대조하지 못한 경우 에는 이 오류를 발생시키지 않는다.
대신 원격 피어로 부터 "bad_certificate" (42) DTLS 경고를
받을 수 있으며 그 결과 로 발생할 수 있는
오류 는 다음 과 같다:
"dtls-failure".
|
sctp-failure
|
SCTP 협상 이 실패했 거나 치명 적인 오류 로 인해
연결 이 종료된 상태 이다. 다음 sctpCauseCode
속성의 값은해당 SCTP 오류의 원인 코드 값으로 설정된다.
|
sdp-syntax-error
|
SDP 구문 이 유효하지 않은 상태이다. 다음 sdpLineNumber
속성의 값은 SDP 안에서 구문 오류가 감지된 위치에 해당 하는 줄의 번호 를
나타내도록 설정 된다.
|
hardware-encoder-not-available
|
요청된 동작을 수행하는 데 필요한 하드웨어 인코더의 자원을 사용할 수 없는 상태이다. |
hardware-encoder-error
|
하드웨어 인코더 는 제공된 매개변수 를 지원하지 않는 상태이다. |
RTCErrorEvent
인터페이스는
RTCError가 이벤트로 발생하는 경우를 위해 정의된다:
WebIDL[Exposed=Window]
interface RTCErrorEvent : Event {
constructor(DOMString type, RTCErrorEventInit eventInitDict);
[SameObject] readonly attribute RTCError error;
};
constructor()
새
RTCErrorEvent를 생성한다.
error of type RTCError,
readonly
이벤트를
발생시킨 오류를 설명하는 RTCError
이다.
WebIDL dictionary RTCErrorEventInit : EventInit {
required RTCError error;
};
error of type
RTCError
이벤트와 연결된
오류가 있으면 그 오류를 설명하는 RTCError
이다.
이 절은 비규범적이다.
다음
이벤트는 RTCDataChannel 객체에서 발생한다:
| Event name | Interface | Fired when... |
|---|---|---|
| open |
Event
|
해당 RTCDataChannel 객체의 기반 데이터 전송
연결이 수립되었 거나 다시 수립되었다.
|
| message |
MessageEvent
[html]
|
메시지를 성공적으로 수신한 상태가 되었다. |
| bufferedamountlow |
Event
|
해당 RTCDataChannel 객체의 bufferedAmount
값이다음 임계값보다 높은상태에서 감소한다:
bufferedAmountLowThreshold
그 결과 다음 임계값
이하 가 된다: bufferedAmountLowThreshold.
|
| error |
RTCErrorEvent
|
데이터 채널 에서 오류가 발생한 상태가 되었다. |
| closing |
Event
|
해당 RTCDataChannel 객체가 다음 상태로 전이한다.
그값은"closing"
상태이다
|
| close |
Event
|
해당 RTCDataChannel 객체의 기반 데이터 전송
이 닫힌 상태이다.
|
다음
이벤트는 RTCPeerConnection 객체에서 발생한다:
| Event name | Interface | Fired when... |
|---|---|---|
| track |
RTCTrackEvent
|
새로 수신할 미디어 에 대한 협상 대상 은 특정
RTCRtpReceiver이며 그 수신기 의 track
이관련된 모든원격 스트림에 추가되었다. 그스트림의 형식은다음과 같다: MediaStream이다.
|
| negotiationneeded |
Event
|
브라우저 는 해당 애플리케이션 에게 세션 협상이 이루어져야 한다는 사실을 알리려 한다. 즉 createOffer 호출 다음에 setLocalDescription 호출이 수행되어야 한다는 뜻이다. |
| signalingstatechange |
Event
|
연결의다음 상태인 [[SignalingState]] 가 변경되었다.
이러한 상태 변경은 다음두 메서드
중 어느 하나가 setLocalDescription
또는
setRemoteDescription
호출된 결과이다.
|
| iceconnectionstatechange |
Event
|
해당 RTCPeerConnection의 [[IceConnectionState]] 가
변경되었다.
|
| icegatheringstatechange |
Event
|
해당 RTCPeerConnection의 [[IceGatheringState]] 가
변경되었다.
|
| icecandidate |
RTCPeerConnectionIceEvent
|
새로운 한 RTCIceCandidate 가 스크립트에서 사용할 수있는
상태가 되었다.
|
| connectionstatechange |
Event
|
해당 RTCPeerConnection.connectionState
가 변경되었다.
|
| icecandidateerror |
RTCPeerConnectionIceErrorEvent
|
ICE 후보를 수집하는 도중 실패가 발생한 상태이다. |
| datachannel |
RTCDataChannelEvent
|
새로운 한 RTCDataChannel 이 다른 피어 의
채널 생성 에
대한 응답 으 로 스크립트 에 전달되었다.
|
다음
이벤트는 RTCDTMFSender 객체에서 발생한다:
| Event name | Interface | Fired when... |
|---|---|---|
| tonechange |
RTCDTMFToneChangeEvent
|
해당 RTCDTMFSender 객체 가 방금 톤
의 재생 을 시작했으며
그 톤 은 다음 tone 속성으로
반환된다. 또는다음 버퍼에 들어 있는 톤들의 재생을 방금 끝냈으며:
toneBuffer 이 경우에는 다음
속성에서 빈 값이 반환된다:
tone 속성이다.
|
다음
이벤트는 RTCIceTransport 객체에서 발생한다:
| Event name | Interface | Fired when... |
|---|---|---|
| statechange |
Event
|
해당 RTCIceTransport 상태가 변경된다.
|
| gatheringstatechange |
Event
|
해당 RTCIceTransport 후보수집 상태가
변경된다.
|
| selectedcandidatepairchange |
Event
|
해당 RTCIceTransport에서 선택된 후보
쌍이 변경된다.
|
다음
이벤트는 RTCDtlsTransport 객체에서 발생한다:
| Event name | Interface | Fired when... |
|---|---|---|
| statechange |
Event
|
해당 RTCDtlsTransport 상태가 변경된다.
|
| error |
RTCErrorEvent
|
다음 전송에서 오류가 발생 했다: RTCDtlsTransport (유형은
"dtls-failure" 또는
"fingerprint-failure"이다).
|
다음
이벤트는 RTCSctpTransport 객체에서 발생한다:
| Event name | Interface | Fired when... |
|---|---|---|
| statechange |
Event
|
해당 RTCSctpTransport 상태가 변경된다.
|
이 절은 비규범적이다.
이 절은 비규범적이다. 새로운 동작을 지정하지 않고 명세의 다른 부분에 이미 있는 정보를 요약한다. WebRTC에서 사용하는 일반적인 API 및 프로토콜 집합의 전반적인 보안 고려 사항은 [ RFC8827]에 설명되어 있다.
이 문서는 브라우저와 다른 장치(다른 브라우저 포함) 사이에 실시간 직접 통신을 설정하는 기능으로 웹 플랫폼을 확장한다.
이는 서로 다른 브라우저에서 실행되는 애플리케이션 사이 또는 같은 브라우저에서 실행되는 애플리케이션과 브라우저가 아닌 대상 사이에서 데이터와 미디어를 공유할 수 있다는 뜻이다. 이는 출처가 다른 주체 사이의 데이터 전송을 제한하는 웹 모델의 일반적인 경계를 넘어서는 것이다.
WebRTC 명세는 통신에 대한 사용자 프롬프트나 브라우저 UI 표시를 제공하지 않는다. 웹 페이지가 미디어 접근을 허용받으면 그 미디어를 원하는 다른 주체와 자유롭게 공유할 수 있다고 가정한다. 따라서 WebRTC 데이터 채널을 통한 피어 간 데이터 교환은 사용자의 명시적 동의나 관여 없이 일어날 수 있으며, 이는 서버를 매개로 하는 교환(예: Web Sockets를 통한 교환)이 사용자 관여 없이 일어날 수 있는 것과 비슷하다.
WebRTC를 사용하지 않더라도 웹 애플리케이션을 제공하는 웹 서버는 애플리케이션이 전달되는 공개 IP 주소를 알게 된다. 통신을 설정하면 브라우저의 네트워크 환경에 관한 추가 정보가 웹 애플리케이션에 노출되며, 여기에는 브라우저가 WebRTC에 사용할 수 있는 IP 주소(사설 주소일 수도 있음)의 집합이 포함될 수 있다. 통신 세션을 설정하려면 이 정보의 일부를 상대방에게 전달해야 한다.
IP 주소를 드러내면 위치와 연결 방식이 누출될 수 있으며 이는 민감한 정보일 수 있다. 네트워크 환경에 따라 핑거프린팅 가능 범위를 늘리고 사용자가 쉽게 지울 수 없는 지속적인 교차 출처 상태를 만들 수도 있다.
연결은
항상 통신에 제안된
IP 주소를 상대방에게
드러낸다. 애플리케이션은
RTCIceTransportPolicy 사전이 노출하는
설정으로 특정 주소를 사용하지 않도록 선택하고, 참여자 사이의
직접 연결 대신 중계(예: TURN 서버)를 사용하여 이러한 노출을
제한할 수 있다. 일반적으로 TURN 서버의 IP 주소는
민감한 정보가 아니라고 가정한다. 예를 들어 애플리케이션은 사용자가 상대방과
미디어 연결을 시작하는 데 동의했는지에 따라 이러한 선택을 할
수 있다.
IP 주소가 애플리케이션 자체에 노출되는 것을 완화하려면 사용할 수 있는 IP 주소를 제한해야 하며, 이는 끝점 사이의 가장 직접적인 경로로 통신하는 능력에 영향을 준다. 브라우저는 사용자가 원하는 보안 태세에 따라 어떤 IP 주소를 애플리케이션에 제공할지 결정하는 적절한 제어 수단을 제공하도록 권장된다. 어떤 주소를 노출할지는 로컬 정책이 제어한다(자세한 내용은 [ RFC8828] 참조).
브라우저는 신뢰할 수 있는 네트워크 환경(방화벽 내부)에서 실행되는 능동적인 플랫폼이므로, 브라우저가 로컬 네트워크의 다른 요소에 가할 수 있는 피해를 제한하는 것이 중요하다. 또한 신뢰할 수 없는 참여자의 가로채기, 조작 및 변경으로부터 데이터를 보호하는 것이 중요하다.
완화 조치에는 다음이 포함된다:
이 조치들은 관련 IETF 문서에 지정되어 있다.
통신이 진행 중이라는 사실은 네트워크를 관찰할 수 있는 공격자에게 숨길 수 없으므로 공개 정보로 간주해야 한다.
향후
필요에 대비하여 통신 인증서를
postMessage(message, options)로
내부 내용을 드러내지 않고 공유할
수 있다. 메모리 공격 표면을 줄이기 위해, 사용자
에이전트는 이러한 객체가 핸들을 보유한 비밀 키 자료를
RTCCertificate 객체에 접근할 수 있는 프로세스와 격리하도록
강하게 권장된다.
앞서 설명한 대로 WebRTC API가 노출하는 IP 주소 목록은 지속적인 교차 출처 상태로 사용될 수 있다.
IP
주소 외에도 WebRTC
API는
RTCRtpSender.getCapabilities와
RTCRtpReceiver.getCapabilities 메서드로
기반 미디어 시스템의 정보를 노출한다. 여기에는
시스템이 생성하고 소비할 수 있는 코덱의
상세하고 순서가 있는 정보가 포함된다.
그 정보의 부분집합은 세션 협상
중에
생성되고 노출되며 전송되는 SDP 세션 설명에 표현될 가능성이 크다. 이 정보는 대부분 시간과
출처를 넘어 지속되며 해당 장치의 핑거프린팅 가능 범위를 늘린다.
DTLS 연결을 설정할 때 WebRTC API는 애플리케이션이 예를 들어 IndexedDB에 지속적으로 저장할 수 있는 인증서를 생성할 수 있다. 이러한 인증서는 출처 간에 공유되지 않으며 해당 출처의 영구 저장소를 지우면 함께 지워진다.
setRemoteDescription은
예외를 던져
잘못된 형식의 SDP와 유효하지 않은 SDP를 방어하지만, 애플리케이션이
예상하지 못할 수 있는 SDP를 방어하려고 하지는 않는다.
원격 설명을 설정하면 이미지 버퍼와 네트워크 포트를 비롯한
상당한 리소스가 할당되거나 미디어가 흐르기 시작하는 등 여러
결과가 생길 수 있으며, 개인정보 보호와 대역폭에 영향을
줄 수 있다. 악의적인 SDP에 대비하지 않은 애플리케이션은
리소스 고갈이나 의도치 않은 수신 미디어 허용의 위험에
노출될 수 있고, 다른 끝점이 송신을 협상하지 않으면
ontrack 같은 특정 이벤트가
발생하지 않을 위험도 있다. 애플리케이션은 악의적인 SDP에
대비해야 한다.
이 절은 비규범적이다.
WebRTC 1.0 명세는 실시간 오디오, 비디오 및 데이터 교환을 설정하는 데 필요한 프로토콜(IETF에서 정의됨)을 제어하는 API를 노출한다.
청각장애인용 통신 장치(TDD/TTY)는 청각 또는 언어 장애가 있는 사람 등을 포함한 사용자가 전화선을 통해 통신할 수 있도록 한다. [ RFC4103]에 정의된 실시간 텍스트는 RTP에 캡슐화된 T.140을 사용하여 TDD/TTY 장치에서 IP 기반 통신으로 전환할 수 있도록 하며, 여기에는 공공 안전 접수점(PSAP)과의 긴급 통신도 포함된다.
실시간 텍스트는 거의 실시간으로 데이터를 보내고 받을 수 있어야 하므로 WebRTC 1.0 데이터 채널 API로 지원하는 것이 가장 적합하다. IETF가 정의한 데이터 채널 프로토콜은 신뢰 및 비신뢰 데이터 채널을 모두 지원하는 SCTP/DTLS/UDP 프로토콜 스택을 사용한다. IETF는 SRTP 키 관리에 의존하고 비신뢰 통신에 초점을 맞춘 RTP 데이터 채널 제안보다 SCTP/DTLS/UDP를 표준화하는 것을 선택했다.
IETF는 WebRTC 프로토콜 집합의 일부로 RTP 데이터 채널과 다른 접근 방식을 선택했으므로, 이 문서 발행 시점에는 IETF가 정의하고 미국 FCC 규정에서 구현한 실시간 텍스트를 WebRTC API가 직접 지원하는 표준화된 방법이 없다. WebRTC 작업 그룹은 이 분야에서 개발 중인 IETF 프로토콜을 브라우저 API에 직접 노출할 필요가 있는지 평가할 것이며, 이 잠재적인 공백에 관해 관련 사용자 커뮤니티의 의견을 구하고 있다.
IETF MMUSIC 작업 그룹에서는 WebRTC 데이터 채널을 통한 실시간 텍스트 전송을 가능하게 하는 작업이 진행 중이다. 이를 통해 SCTP 데이터 채널 프로토콜과 RFC 4103 실시간 텍스트 사이를 변환하는 게이트웨이를 배포할 수 있다. 이 작업이 완료되면 게이트웨이를 통하거나 다른 방식으로 브라우저를 포함한 WebRTC 사용자 에이전트에 실시간 텍스트를 통합하는, 통일되고 상호운용 가능한 접근 방식을 제공할 것으로 예상된다.
이 문서 발행 시점에는 사용자 정의 WebRTC 데이터 채널 등을 통해 WebRTC 클라이언트에서 RTT를 효과적으로 지원하는 게이트웨이를 개발할 수 있다. SCTP 데이터 채널 프로토콜과 RFC 4103 실시간 텍스트 같은 IETF 프로토콜로 향후 표준화된 게이트웨이를 사용할 수 있게 될 때까지는 이것으로 충분하다고 간주한다. RTT 지원을 국제적으로 효과적이고 일관되게 표준화하려면 W3C 그룹의 관련 작업과 함께 IETF에서 이를 정의해야 한다.
W3C의 2021년 1월 권고안으로 발행된 이후 다음 후보 개정 사항이 이 문서에 통합되었다.
RTCRtpEncodingParameters Members
(PR #2985) -
Changes to Web Platform Tests: #47663 The editors wish to thank the Working Group chairs and Team Contact, Harald Alvestrand, Stefan Håkansson, Erik Lagerway and Dominique Hazaël-Massieux, for their support. Substantial text in this specification was provided by many people including Martin Thomson, Harald Alvestrand, Justin Uberti, Eric Rescorla, Peter Thatcher, Jan-Ivar Bruaroey and Peter Saint-Andre. Dan Burnett would like to acknowledge the significant support received from Voxeo and Aspect during the development of this specification.
The RTCRtpSender and RTCRtpReceiver objects were
initially
described in the W3C ORTC
CG, and have been adapted for use in this specification.
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in:
Referenced in: