이 기사는 원래 Metered 블로그에 게시되었습니다: WebRTC WHIP & WHEP 튜토리얼: 라이브 스트리밍 앱 구축
WHIP(WebRTC-HTTP Ingestion Protocol) 및 WHEP(WebRTC-HTTP Egress Protocol)은 표준 HTTP 방법을 사용하여 WebRTC의 신호 처리를 간소화하도록 설계된 프로토콜입니다
WHIP 정의: WHIP는 클라이언트 장치가 미디어 스트림을 서버에 보내는 방법을 단순화합니다.
WHEP 정의: WHEP 프로토콜은 서버에서 클라이언트로 미디어 스트림을 전달하는 데 사용됩니다. HTTP 프로토콜을 사용하여 미디어 소비에 대한 신호를 처리하므로 클라이언트 장치가 복잡한 설정 없이 미디어 스트림을 수신할 수 있습니다
WebRTC 시그널링 단순화의 역할
구현 용이성: WHEP 및 WHIP는 HTTP 프로토콜을 사용하므로 이러한 프로토콜은
상태 비저장 통신: 이는 HTTP가 상태 비저장 프로토콜이기 때문에 서버가 요청 간에 지속적인 세션 정보를 유지할 필요가 없기 때문입니다.
향상된 호환성: HTTP는 보편적인 호환성을 갖기 때문에 신호 전달에 HTTP를 사용하는 것이 플랫폼과 기기 간 호환성에 가장 좋습니다.
빠른 개발: 개발자는 기존 신호 방법의 복잡한 세부 사항을 고려할 필요가 없기 때문에 WebRTC 앱을 보다 효율적으로 구현할 수 있습니다
WHIP 프로토콜은 HTTP 신호 방식을 사용하여 미디어 스트림을 클라이언트 장치에서 서버로 전송하는 방식을 혁신했습니다
일반적으로 WebRTC를 설정하려면 웹 소켓이나 기타 프로토콜을 사용하여 복잡한 신호 메커니즘을 설정해야 합니다. WHIP을 사용하면 WebRTC 세션 신호 및 시작을 위해 HTTP 프로토콜을 사용하여 이 프로세스가 간단해집니다
HTTP POST 요청: 여기서 클라이언트 기기는 SDP 또는 본문의 세션 설명 프로토콜 제공과 함께 HTTP POST 요청을 WHIP 엔드포인트로 보냅니다.
서버 응답: 그런 다음 미디어 서버는 SDP 제안을 처리하고 요청 본문의 SDP 응답을 포함하여 200 상태 코드로 응답합니다
ICE 후보 교환: WHIP 프로토콜은 새로운 ICE 후보가 사용 가능해질 때마다 클라이언트가 추가 HTTP PATCH 요청을 보낼 수 있도록 허용하여 ICE 프로토콜을 지원합니다.
연결 설정: SDP 교환이 완료되면 P2P 연결이 설정되어 클라이언트가 미디어를 서버로 스트리밍할 수 있습니다.
단순성: WHIP 방법을 사용하여 WHIP는 지속적인 연결 및 신호 서버의 필요성을 줄입니다.
구현 용이성: 개발자는 범용 호환성을 갖춘 HTTP를 사용하여 개발 프로세스 속도를 높일 수 있습니다
확장성: 상태 비저장 HTTP 요청을 통해 서버는 여러 연결 요청을 동시에 처리할 수 있으므로 많은 수의 연결을 쉽게 관리할 수 있습니다.
방화벽 및 프록시 친화적: HTTP는 방화벽 친화적이며 거의 모든 유형의 방화벽이 HTTP 트래픽을 허용합니다.
비용 효율성: HTTP를 통한 단순화된 신호로 신호 서버 추가와 관련된 비용이 절감됩니다.
WHEP 프로토콜은 서버에서 클라이언트 장치로 미디어를 전달하는 프로세스를 단순화합니다.
따라서 WHEP 프로토콜을 사용하면 HTTP를 사용하여 서버와 클라이언트 장치로부터 미디어를 수신하기 위한 신호를 설정할 수 있습니다.
HTTP GET 요청: 클라이언트는 서버 WHEP 엔드포인트에 HTTP GET 요청을 전송하여 미디어 스트림을 요청합니다
SDP 교환: 서버는 HTTP 응답으로 SDP 제안으로 응답하고 클라이언트는 후속 POST 요청에서 SDP 응답을 다시 보냅니다.
미디어 수신: 연결이 설정되면 설정된 WebRTC 연결을 통해 미디어 스트림이 수신됩니다. 참고: WebRTC 연결을 설정하려면
TURN 서버ICE 지원: WHEP를 사용하면 추가 HTTP 패치 요청을 통해 ICE 후보를 교환할 수 있으므로 더 나은 연결이 가능합니다.
단순화된 클라이언트 구현: HTTP 요청을 사용하여 복잡한 신호 메커니즘의 필요성 감소
향상된 호환성: HTTP 프로토콜에 대한 범용 지원으로 기기 간 향상된 호환성 보장
향상된 확장성: HTTP는 상태 비저장 프로토콜이므로 서버의 확장성이 향상되고 적은 리소스로 매우 많은 수의 사용자로 확장할 수 있습니다.
더 나은 네트워크 통과: HTTP로 신호를 보낼 수 있고 웹 소켓이나 기타 메커니즘이 필요하지 않기 때문에 연결을 위한 NAT 통과가 향상됩니다. 연결이 설정되면 WebRTC용 TURN 서버
지연 시간 단축: HTTP를 사용하여 신호를 보내면 연결 속도가 빨라져 사용자 경험이 향상됩니다.
WHIP과 WHEP를 결합하여 개발자는 WebRTC를 위한 포괄적인 신호 솔루션을 만들 수 있습니다
이 조합은 미디어 스트림의 수집 및 전달을 단순화하여 WebRTC의 원활한 구현을 보장합니다
통합 신호 접근 방식: 수집과 전달 모두에 HTTP를 사용하면 일관된 신호 방법론이 생성됩니다.
복잡성 감소: 개발자는 HTTP 프로토콜만 다루면 되므로 학습 곡선과 코드 유지 관리가 줄어듭니다
향상된 성능: 신호용 단일 프로토콜로 코드를 간소화하면 미디어 전송 시 연결 시간이 빨라지고 대기 시간이 단축됩니다.
라이브 스트리밍 플랫폼:
대화형 애플리케이션
확장 가능한 아키텍처
WebRTC 앱에서 WHIP 및 WHEP를 구현하는 것은 매우 쉽습니다. 이 섹션에서는 WHIP 서버를 설정하고 노드 및 도커와 같은 최신 기술을 사용하여 이를 애플리케이션에 통합합니다
여기에서는 NAT 통과를 위해 Metered.ca TURN 서버 서비스를 사용할 예정입니다
전제 조건 및 환경 설정:
Node.js 및 NPM: 최신 Node 및 nvm이 설치되어 있는지 확인하세요
Metered.ca 계정: Metered TURN 서버
공개 IP 주소: 인터넷에서 서버에 액세스하려면 이 주소가 필요합니다. 애플리케이션에 클라우드 제공업체를 사용하는 경우 해당 서비스를 통해 무료 공용 IP 주소를 얻을 수 있습니다
WebRTC 미디어 서버: WHIP을 지원하는 GStreamer 또는 Janus와 같은 미디어 서버가 필요합니다
WHIP를 지원하는 GStreamer 설치
GStreamer로 WHIP 서버 설정
gst-launch-1.0 whipserversrc name=whip \ ! queue ! videoconvert ! autovideosink
위 명령은 수신 미디어 스트림을 허용하고 이를 표시하는 WHIP 서버를 시작합니다.
Metered.ca TURN 서버
를 사용하도록 서버 구성gst-launch-1.0 whipserversrc name=whip ice-server="turn://YOUR_USERNAME:YOUR_CREDENTIAL@relay.metered.ca:80" \ ! queue ! videoconvert ! autovideosink
Node.JS로 역방향 프록시 설정(선택 사항):
const express = require('express'); const httpProxy = require('http-proxy'); const app = express(); const proxy = httpProxy.createProxyServer(); app.post('/whip', (req, res) => { proxy.web(req, res, { target: 'http://localhost:PORT_WHERE_GSTREAMER_IS_RUNNING' }); }); app.listen(3000, () => { console.log('Proxy server running on port 3000'); });
WHIP 통합을 위한 코드 조각:
클라이언트 측에서는 RTCPeerConnection의 도움으로 미디어 스트림을 캡처하고 HTTP 요청을 사용하여 연결 설정에 필요한 신호를 처리할 수 있습니다.
미디어 스트림 캡처:
const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
Metered TURN 서버의 도움으로 RTCPeerConnection을 생성할 수 있습니다
var myPeerConnection = new RTCPeerConnection({ iceServers: [ { urls: "stun:stun.relay.metered.ca:80", }, { urls: "turn:global.relay.metered.ca:80", username: "your-username", credential: "your-credential", }, { urls: "turn:global.relay.metered.ca:80?transport=tcp", username: "your-username", credential: "your-credential", }, { urls: "turn:global.relay.metered.ca:443", username: "your-username", credential: "your-credential", }, { urls: "turns:global.relay.metered.ca:443?transport=tcp", username: "your-username", credential: "your-credential", }, ], });
mediaStream.getTracks().forEach((track) => { pc.addTrack(track, mediaStream); });
const offer = await pc.createOffer(); await pc.setLocalDescription(offer); const response = await fetch('http://YOUR_SERVER_IP:3000/whip', { method: 'POST', headers: { 'Content-Type': 'application/sdp' }, body: pc.localDescription.sdp, }); const sdpAnswer = await response.text(); await pc.setRemoteDescription({ type: 'answer', sdp: sdpAnswer });
클라이언트측:
HTTP POST 요청:
응답 기대:
서버측:
SDP 제안 받기:
SDP 답변 생성
직접 P2P 연결이 불가능할 때 NAT 및 방화벽을 통해 미디어 통과를 촉진합니다
TURN 서버 자격 증명과 ICE 서버는 다음과 같습니다
gst-launch-1.0 whipserversrc name=whip \ ! queue ! videoconvert ! autovideosink
WHIP 클라이언트가 있으면 앱이 HTTP 신호를 사용하여 서버로부터 미디어 스트림을 수신할 수 있습니다.
Javascript의 WebRTC API에 대한 기본 이해
WHEP GStreamer Janus 또는 기타를 지원하는 미디어 서버
Metered.ca TURN 서버 자격 증명
RTCPeerConnection 초기화
gst-launch-1.0 whipserversrc name=whip ice-server="turn://YOUR_USERNAME:YOUR_CREDENTIAL@relay.metered.ca:80" \ ! queue ! videoconvert ! autovideosink
서버에서 원격 트랙을 재생하기 위한 이벤트 리스너 설정
const express = require('express'); const httpProxy = require('http-proxy'); const app = express(); const proxy = httpProxy.createProxyServer(); app.post('/whip', (req, res) => { proxy.web(req, res, { target: 'http://localhost:PORT_WHERE_GSTREAMER_IS_RUNNING' }); }); app.listen(3000, () => { console.log('Proxy server running on port 3000'); });
서버에 GET 요청 보내기
const mediaStream = await navigator.mediaDevices.getUserMedia({ video: true, audio: true });
var myPeerConnection = new RTCPeerConnection({ iceServers: [ { urls: "stun:stun.relay.metered.ca:80", }, { urls: "turn:global.relay.metered.ca:80", username: "your-username", credential: "your-credential", }, { urls: "turn:global.relay.metered.ca:80?transport=tcp", username: "your-username", credential: "your-credential", }, { urls: "turn:global.relay.metered.ca:443", username: "your-username", credential: "your-credential", }, { urls: "turns:global.relay.metered.ca:443?transport=tcp", username: "your-username", credential: "your-credential", }, ], });
SDP 응답을 생성하고 HTTP POST 요청을 통해 서버로 보냅니다
mediaStream.getTracks().forEach((track) => { pc.addTrack(track, mediaStream); });
ICE 후보를 별도로 보내야 하는 경우 icecandidate 이벤트를 처리하세요
const offer = await pc.createOffer(); await pc.setLocalDescription(offer); const response = await fetch('http://YOUR_SERVER_IP:3000/whip', { method: 'POST', headers: { 'Content-Type': 'application/sdp' }, body: pc.localDescription.sdp, }); const sdpAnswer = await response.text(); await pc.setRemoteDescription({ type: 'answer', sdp: sdpAnswer });
var myPeerConnection = new RTCPeerConnection({ iceServers: [ { urls: "stun:stun.relay.metered.ca:80", }, { urls: "turn:global.relay.metered.ca:80", username: "e13b9bsdfdsfsdfb0676cc5b6", credential: "dedewdewfer+gq5iT", }, { urls: "turn:global.relay.metered.ca:80?transport=tcp", username: "e13bdfdsfds6b0676cc5b6", credential: "dewfrefre+gq5iT", }, { urls: "turn:global.relay.metered.ca:443", username: "e13b9fsdfdsfsd86b0676cc5b6", credential: "csdfwefeer+gq5iT", }, { urls: "turns:global.relay.metered.ca:443?transport=tcp", username: "e13b9dsfsdfe6b0676cc5b6", credential: "sdfewtrererer+gq5iT", }, ], });
트랙 이벤트가 실행되면 수신된 스트림을 비디오 요소에 첨부합니다
미디어 스트림 이벤트 처리
var myPeerConnection = new RTCPeerConnection({ iceServers: [ { urls: "stun:stun.relay.metered.ca:80", }, { urls: "turn:global.relay.metered.ca:80", username: "e13b9bsdfdsfsdfb0676cc5b6", credential: "dedewdewfer+gq5iT", }, { urls: "turn:global.relay.metered.ca:80?transport=tcp", username: "e13bdfdsfds6b0676cc5b6", credential: "dewfrefre+gq5iT", }, { urls: "turn:global.relay.metered.ca:443", username: "e13b9fsdfdsfsd86b0676cc5b6", credential: "csdfwefeer+gq5iT", }, { urls: "turns:global.relay.metered.ca:443?transport=tcp", username: "e13b9dsfsdfe6b0676cc5b6", credential: "sdfewtrererer+gq5iT", }, ], });
ㄴ. 협상이 필요합니다
pc.addEventListener('track', (event) => { const [remoteStream] = event.streams; // Attach the remote stream to a video element const remoteVideo = document.getElementById('remoteVideo'); remoteVideo.srcObject = remoteStream; });
const whepServerEndpoint = 'http://YOUR_SERVER_IP:3000/whep'; // Replace with your server's WHEP endpoint const response = await fetch(whepEndpoint, { method: 'GET', headers: { Accept: 'application/sdp', }, }); const sdpOffer = await response.text();
측정된 TURN 서버
API: 강력한 API로 서버 관리를 시작하세요. API를 통해 자격 증명 추가/제거, API를 통해 사용자별/자격 증명 및 사용자 지표 검색, API를 통해 자격 증명 활성화/비활성화, API를 통해 날짜별 사용량 데이터 검색 등의 작업을 수행할 수 있습니다.
글로벌 지리적 위치 타겟팅: 자동으로 트래픽을 가장 가까운 서버로 전달하여 지연 시간을 최소화하고 성능을 최고화합니다. 전 세계 어디에서나 50ms 미만의 지연 시간
전 세계 모든 지역의 서버: 토론토, 마이애미, 샌프란시스코, 암스테르담, 런던, 프랑크푸르트, 방갈로르, 싱가포르, 시드니, 서울, 달라스, 뉴욕
낮은 지연 시간: 전 세계 어디에서나 50ms 미만의 지연 시간.
비용 효율적: 대역폭 및 볼륨 할인이 가능한 종량제 가격.
손쉬운 관리: 사용 로그, 계정이 임계값 한도에 도달할 때 이메일, 청구 기록, 이메일 및 전화 지원을 받으세요.
다중 테넌시:
여러 개의 자격 증명을 생성하고 고객 또는 다른 앱별로 사용량을 구분합니다. 사용 로그, 청구 기록 및 임계값 알림을 받으세요.엔터프라이즈 신뢰성:
SLA를 통한 99.999% 가동 시간.엔터프라이즈 규모:
동시 트래픽 또는 총 트래픽에 제한이 없습니다. 계량형 TURN 서버는 엔터프라이즈 확장성을 제공합니다5GB/월 무료:
무료 플랜으로 매월 5GB 무료 TURN 서버 사용량을 받으세요포트 80 및 443에서 실행
다른 기사도 고려해 보세요.
WebRTC 데이터 채널: 가이드
간단한 피어 튜토리얼: 비디오용 TURN 서버, DataChannel 추가
Metered를 사용하여 WebRTC TURN 서버 설정 가이드
WebRTC와 HLS: 어느 것이 귀하에게 가장 적합합니까?
위 내용은 WebRTC WHIP 및 WHEP 튜토리얼: 라이브 스트리밍 앱 구축의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!