WebRtc10: 端对端1v1传输基本流程

媒体能力协商过程

RTCPeerConnection(核心类)

  • 基本格式
    pc = new RTCPeerConnection(configiration);

RTCPeerConnection方法分类

  • 媒体协商
  • Stream/Track
  • 传输相关方法
  • 统计相关方法

媒体协商过程

协商状态变化

媒体协商方法

  • createOffer
  • createAnswer
  • setLocalDescription
  • setRemoeteDescription

createOffer

  • 基本格式
    aPromise = myPeerConnection.createOffer(options);

createAnswer

  • 基本格式
    aPromise = myPeerConnection.createAnswer(options);

setLocalDescription

  • 基本格式
    aPromise = myPc.setLocalDescription(sessionDescription);

setRemoeteDescription

  • 基本格式
    aPromise = myPc.setRemoeteDescription(sessionDescription);

Track方法

  • addTrack
  • removeTrack

addTrack

  • 基本格式
    rtpSender = myPc.addTrack(track, stream...);
  • 参数
    track: 添加到RTCPeerConnection中的媒体轨
    stream:指定track所在的stream

removeTrack

  • 基本格式
    myPc.removeTrack(rtpSender);

重要事件

  • onnegotiationneeded
  • onicecandidate

1:1连接的基本流程

实战:本机内的1:1音视频互通

index.html

html 复制代码
<html>
    <head>
        <title>WebRTC PeerConnection</title>
    </head>
    <body>
        <div>
            <video id="localvideo" autoplay playsinline></video>
            <video id="remotevideo" autoplay playsinline></video>
            <div>
                <button id="start">Start</button>
                <button id="call">Call</button>
                <button id="hangup">HangUp</button>
            </div>
        </div>

        <script src="https://webrtc.github.io/adapter/adapter-latest.js"></script>
        <script src="js/main.js"></script>
    </body>
</html>

main.js

js 复制代码
'use strict'

var localVideo = document.querySelector('video#localVideo');
var remoteVideo = document.querySelector('video#remoteVideo');
var btnStart = document.querySelector('button#start');
var btnCall = document.querySelector('button#call');
var btnHangUp= document.querySelector('button#hangup');


var localStream;
var pc1;
var pc2;

function gotMediaStream(stream){
	localVideo.srcObject = stream;
	localStream = stream;
}

function handleError(err){
	console.log("Failed to call getUserMedia", err);
}

function start(){
	var constraints = {
		video: true,
		audio: false 
	}

	if(!navigator.mediaDevices ||
		!navigator.mediaDevices.getUserMedia){
		return;
	}else {
		navigator.mediaDevices.getUserMedia(constraints)
					.then(gotMediaStream)
					.catch(handleError);
	}

}

function gotAnswerDescription(desc){
	pc2.setLocalDescription(desc);

	//send sdp to caller
	//recieve sdp from callee
	
	pc1.setRemoteDescription(desc);

}

function gotLocalDescription(desc){
	pc1.setLocalDescription(desc);

	//send sdp to callee
	
	//receive sdp from caller 
 	pc2.setRemoteDescription(desc);	
	pc2.createAnswer().then(gotAnswerDescription)
			 .catch(handleError);
}

function gotRemoteStream(e){

	if(remoteVideo.srcObject !== e.streams[0]){
		remoteVideo.srcObject = e.streams[0];
	}
}

function call(){
	var offerOptions = {
		offerToReceiveAudio: 0,
		offerToReceiveVideo: 1 
	}

	pc1 = new RTCPeerConnection();
	pc1.onicecandidate = (e) => {
	
		// send candidate to peer
		// receive candidate from peer

		pc2.addIceCandidate(e.candidate)
			.catch(handleError);
		console.log('pc1 ICE candidate:', e.candidate);
	}

	pc1.iceconnectionstatechange = (e) => {
		console.log(`pc1 ICE state: ${pc.iceConnectionState}`);
		console.log('ICE state change event: ', e);
	}


	pc2 = new RTCPeerConnection();
	pc2.onicecandidate = (e)=> {
	
		// send candidate to peer
		// receive candidate from peer

		pc1.addIceCandidate(e.candidate)
			.catch(handleError);
		console.log('pc2 ICE candidate:', e.candidate);
	}

	pc2.iceconnectionstatechange = (e) => {
		console.log(`pc2 ICE state: ${pc.iceConnectionState}`);
		console.log('ICE state change event: ', e);
	}

	pc2.ontrack = gotRemoteStream;

	//add Stream to caller
	localStream.getTracks().forEach((track)=>{
		pc1.addTrack(track, localStream);
	});

	pc1.createOffer(offerOptions)
		.then(gotLocalDescription)
		.catch(handleError);

}


function hangup(){
	pc1.close();
	pc2.close();
	pc1 = null;
	pc2 = null;

}

btnStart.onclick = start;
btnCall.onclick = call;
btnHangUp.onclick = hangup;
相关推荐
微信开发api-视频号协议2 天前
企业微信二次开发中的文件系统设计:媒体资源、临时文件与业务附件
前端·微信·企业微信·媒体·ipad·微信开放平台
doiito(Do It Together)3 天前
我用 Rust 写了个 AI 媒体管家:Gliding Horse 赋能 media_agent,目标是让 ComfyUI 工作流彻底自动化
人工智能·架构·rust·媒体
RTC实战笔记19 天前
Android 实时音视频接入教程:媒体补充增强信息(SEI)
音视频·媒体·rtc
dayuOK630720 天前
写作卡壳怎么办?我的“5分钟启动法”
人工智能·职场和发展·自动化·新媒体运营·媒体
福大大架构师每日一题21 天前
mediamtx v1.19.1 最新更新发布:安全增强、RTSP/RTMP协议支持升级、媒体处理修复与依赖全面更新
java·安全·媒体
北***字21 天前
新文科/新工科背景下数字媒体创新实训中心建设方案
媒体·虚拟现实·虚拟拍摄·数字媒体
EasyDSS21 天前
跳出播放器思维,私有化视频会议平台EasyDSS一站式视频平台,重塑企业私有化融媒体/视频会议系统需求!
音视频·媒体
傻啦嘿哟21 天前
自动化养号:利用代理池模拟人工操作,进行社交媒体账号维护
运维·自动化·媒体
十六年开源服务商23 天前
2026社交媒体营销×WordPress运维:实战避坑指南
运维·媒体
音乐宝贝家23 天前
1000-2000元入门面单吉他横评:面板/背侧板/琴颈/指板/桶型全维度技术拆解
新媒体运营·音视频·社交电子·业界资讯·媒体·零售·内容运营