目录
- 环境搭建
- SRS4.0 WebRTC1对1通话逻辑分析
环境搭建
1. 安装go语⾔环境
- 在Go语言官网找到对应的安装包(https://golang.google.cn/dl/)
- 下载和解析(使用的是阿里云的Ubuntu系统):
cd /usr/local/
wget https://dl.google.com/go/go1.16.5.linux-amd64.tar.gz --no-check-certificate
tar -C /usr/local -xzf go1.16.5.linux-amd64.tar.gz
3.需要配置 GOROOT 和 PATH环境变量,在/etc/profile中配置。
vim /etc/profile
# 将环境变量添加到/etc/profile⽂件末尾。
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin:$GOBIN
4.然后使⽤ source /etc/profile 命令使配置文件生效,就可以在任意⽬录使用Go语⾔命令。
source /etc/profile
5.执行go version可以查看安装go是否成功。
2. 编译和启动srs
git clone -b v4.0.123 https://gitee.com/winlinvip/srs.oschina.git
srs.4.0.123
cd srs.4.0.123/trunk
./configure
make
./objs/srs -c conf/rtc.conf
3. 编译和启动信令服务器
- 进行srs/trunk目录下。
cd 3rdparty/signaling
make
./objs/signaling
- 注意:云服务器需要先开通1989端口。
相关视频推荐:
webrtc流媒体服务器,音视频通话,推流和拉流教程_哔哩哔哩_bilibiliwww.bilibili.com/video/BV16Y411P7b7/ 流媒体服务器开发,SRS 4.0与WebRTC音视频通话_哔哩哔哩_bilibiliwww.bilibili.com/video/BV1TL4y1c7Hs/LinuxC++音视频开发视频:免费】FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【文章福利】:音视频面试题、学习资料、教学视频和学习路线图资料(资料包括C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等),qun994289133免费分享,有需要的可以加群领取哦!~学习交流裙994289133加入领取资料
企鹅群994289133领取资料 企鹅群994289133领取资料4. 编译和启动web服务器
- 需要server.crt和server.key,如果没有则⽤openssl⽣成。
- 进入srs/trunk/3rdparty/httpx-static目录,执行:
# ⽣成 server.key
openssl genrsa -out server.key 2048
# ⽣成 server.crt
openssl req -new -x509 -key server.key -out server.crt -days 3650
3.编译和启动web服务器
cd 3rdparty/httpx-static
make
./objs/httpx-static -http 80 -https 443 -ssk server.key -ssc server.crt \
-proxy http://127.0.0.1:1989/sig -proxy http://127.0.0.1:1985/rtc \
-proxy http://127.0.0.1:8080/
5. 进入测试页面
- 打开demo地址:
https://localhost/demos/
https://192.xxx.3.6/demos/ #公网ip
2.输入Room和Display就可以进行1对1通话。
3. SRS4.0 WebRTC1对1通话逻辑分析
按f12打开一对一通话http页面源码,在 one2one.html?autostart=true&room=fbe219e 中可以看到,“开始通话”按钮id是btn_start,当点击按钮后,执行startDemo函数。
startDemo函数如下:
var startDemo = async function () {
var host = $('#txt_host').val(); //获取ip或者域名,房间id,参与者名字
var room = $('#txt_room').val();
var display = $('#txt_display').val();
// Connect to signaling first. //关闭先前的websock连接
if (sig) {
sig.close(); //见srs.sig.js close部分
}
sig = new SrsRtcSignalingAsync(); //创建SrsRtcSignalingAsync,RTC信令
sig.onmessage = function (msg) { //onmessage订阅新的信令消息
console.log('Notify: ', msg);
if (msg.event === 'leave') {
$('#player').hide();
}
if (msg.event === 'publish') { //房间已经存在的参与者,收到publish信令后再去订阅新加入者
if (msg.peer && msg.peer.publishing && msg.peer.display !== display) {
startPlay(host, room, msg.peer.display);
}
}
if (msg.event === 'control') {
if (msg.param === 'refresh') {
setTimeout(function () {
window.location.reload();
}, 500);
} else if (msg.param === 'alert') {
alert('From ' + msg.peer.display + ': ' + msg.data);
}
}
if (msg.participants.length >= 2) {
$('.srs_merge').show();
} else {
$('.srs_merge').hide();
}
};
await sig.connect(conf.wsSchema, conf.wsHost, room, display); //连接websock,见下面SrsRtcSignalingAsync代码
control_refresh_peer = async function () {
let r1 = await sig.send({action:'control', room:room, display:display, call:'refresh'});
console.log('Signaling: control peer to refresh ok', r1);
};
control_alert_peer = async function () {
let r1 = await sig.send({action:'control', room:room, display:display, call:'alert', data:$('#txt_alert').val()});
console.log('Signaling: control peer to alert ok', r1);
};
let r0 = await sig.send({action:'join', room:room, display:display}); //向信令服务器发送join信令,会返回房间列表,包括当前房间id,房间人数和每个display的名字和是否推流,见下图。
console.log('Signaling: join ok', r0);
// For one to one demo, alert and ignore when room is full. 判断房间人数是否超过2个,因为是1v1场景
if (r0.participants.length > 2) {
alert('Room is full, already ' + (r0.participants.length - 1) + ' participants');
sig.close();
return;
}
// Start publish media if signaling is ok.
await startPublish(host, room, display); //向srs流媒体服务器开始推流,代码见下面
let r1 = await sig.send({action:'publish', room:room, display:display}); //向信令服务器发送publish信令
console.log('Signaling: publish ok', r1);
// Play the stream already in room. 对于新建的房间,会拉取房间内另一个人的流
r0.participants.forEach(function(participant) {
if (participant.display === display || !participant.publishing) return;
startPlay(host, room, participant.display); //向srs流媒体拉房间内另一个人的流
});
if (r0.participants.length >= 2) {
$('.srs_merge').show();
}
};
2.SrsRtcSignalingAsync代码:
// Async-await-promise based SRS RTC Signaling.
function SrsRtcSignalingAsync() {
var self = {};
// The schema is ws or wss, host is ip or ip:port, display is nickname
// of user to join the room.
self.connect = async function (schema, host, room, display) {
var url = schema + '://' + host + '/sig/v1/rtc'; //如:wss://8.xxx.75.248/sig/v1/rtc
self.ws = new WebSocket(url + '?room=' + room + '&display=' + display); //建立websock连接,地址为:wss://8.xxx.75.248/sig/v1/rtc?room=123&display=zhangsan
self.ws.onmessage = function(event) {
var r = JSON.parse(event.data);
var promise = self._internals.msgs[r.tid];
if (promise) {
promise.resolve(r.msg);
delete self._internals.msgs[r.tid];
} else {
self.onmessage(r.msg);
}
};
return new Promise(function (resolve, reject) {
self.ws.onopen = function (event) {
resolve(event);
};
self.ws.onerror = function (event) {
reject(event);
};
});
};
// The message is a json object.
self.send = async function (message) {
return new Promise(function (resolve, reject) {
var r = {tid: Number(parseInt(new Date().getTime()*Math.random()*100)).toString(16).substr(0, 7), msg: message};
self._internals.msgs[r.tid] = {resolve: resolve, reject: reject};
self.ws.send(JSON.stringify(r));
});
};
self.close = function () {
self.ws && self.ws.close();
self.ws = null;
for (const tid in self._internals.msgs) {
var promise = self._internals.msgs[tid];
promise.reject('close');
}
};
// The callback when got messages from signaling server.
self.onmessage = function (msg) {
};
self._internals = {
// Key is tid, value is object {resolve, reject, response}.
msgs: {}
};
return self;
}
3.join信息返回信息。
4.startPublish和startPlay代码。
var startPublish = function (host, room, display) {
$(".ff_first").each(function(i,e) {
$(e).text(display);
});
var url = 'webrtc://' + host + '/' + room + '/' + display + conf.query; //如: webrtc://8.xxx.75.248/123/wangwu
$('#rtc_media_publisher').show();
$('#publisher').show();
if (publisher) {
publisher.close();
}
publisher = new SrsRtcPublisherAsync(); //创建RTC异步推流
$('#rtc_media_publisher').prop('srcObject', publisher.stream);
return publisher.publish(url).then(function(session){
$('#self').text('Self: ' + url);
}).catch(function (reason) {
publisher.close();
$('#rtc_media_publisher').hide();
console.error(reason);
});
};
var startPlay = function (host, room, display) {
$(".ff_second").each(function(i,e) {
$(e).text(display);
});
var url = 'webrtc://' + host + '/' + room + '/' + display + conf.query; //
$('#rtc_media_player').show();
$('#player').show();
if (player) {
player.close();
}
player = new SrsRtcPlayerAsync();
$('#rtc_media_player').prop('srcObject', player.stream);
player.play(url).then(function(session){
$('#peer').text('Peer: ' + display);
$('#rtc_media_player').prop('muted', false);
}).catch(function (reason) {
player.close();
$('#rtc_media_player').hide();
console.error(reason);
});
};
标签:function,room,self,SRS4.0,display,SRS,sig,msg,WebRTC
From: https://www.cnblogs.com/kn-zheng/p/17063639.html