写了很简单的一个demo
,多次调试之后所有的报错都已经解决了,但是现在还是没能实现想要的效果。各位大佬帮看下是哪里出问题了。
// server.js
const express = require('express')
const app = express()
const path = require('path')
app.use(express.static(path.join(__dirname, 'public')))
app.get('/phone', function (req, res) {
res.sendfile(__dirname + '/phone.html')
})
app.get('/', function (req, res) {
res.sendfile(__dirname + '/index.html')
})
const server = require('http').createServer(app)
const io = require('socket.io')(server)
let clients = []
io.on('connection', function (socket) {
clients.push(socket)
const referer = socket.handshake.headers.referer
if(referer.match('/phone')) {
// phone
socket.on('phone_ice_candidate', function (res) {
socket.broadcast.emit('pc_add_ice', { ice: res.ice })
})
// phone
socket.on('send_phone_sdp', function (data) {
socket.broadcast.emit('set_pc_remote_sdp', { desc: data.desc })
})
}
// pc 获取 ice 后推送给 phone
socket.on('remote_ice_candidate', function (ice) {
socket.to(getId(clients, '/phone')).emit('send_ice_to_pc', {ice: ice})
})
// pc 获取 sdp 后推送给 phone
socket.on('send_pc_sdp', function (data) {
// 推送给 phone
socket.to(getId(clients, '/phone')).emit('set_phone_remote_sdp', {desc: data})
})
// 断开
socket.on('disconnect', () => {
let id = socket.id
clients.forEach((client, index) => {
if(client.id === id) {
clients.splice(index, 1)
}
})
})
})
function getId(sockets, exp) {
let id
sockets.forEach(socket => {
if(socket.handshake.headers.referer.match(exp)) {
id = socket.id
}
})
return id
}
server.listen(3000, function () {
console.log('port listening at 3000')
})
// phone.js
var socket = io();
var server = {
// "iceServers": [{
// "url": "stun:stun.l.google.com:19302"
// }]
},
pc = new RTCPeerConnection(server),
v = document.querySelector('#video1')
// 候选列表
pc.onicecandidate = function (event) {
if (event.candidate) {
socket.emit('phone_ice_candidate', {
ice: event.candidate
})
}
}
// 接收远端 ice
socket.on('send_ice_to_pc', function (event) {
pc.addIceCandidate(new RTCIceCandidate(event.ice.ice))
})
// 获取用户本地设备
navigator.mediaDevices.getUserMedia({
video: {width: 400, height: 300},
audio: false
})
.then(function (stream) {
v.src = window.URL.createObjectURL(stream);
pc.addStream(stream);
})
.catch(function (err) {
console.log(err.name + ": " + err.message);
})
// create offer
pc.createOffer({offerToReceiveVideo: 1}).then(function (e) {
// pc setLocalDescription
pc.setLocalDescription(e).then(
function () {
socket.emit('send_phone_sdp', {desc: e})
},
function () {
console.log('pc setLocalDescription error')
}
)
});
socket.on('set_phone_remote_sdp', function (e) {
pc.setRemoteDescription(e.desc.desc).then(
function () {
console.log('pc setRemoteDescription success')
}, function (err) {
console.log(err)
})
})
// index.js
var socket = io();
var server = {
// "iceServers": [{
// "url": "stun:stun.l.google.com:19302"
// }]
},
pc = new RTCPeerConnection(server),
v = document.querySelector('#video2')
pc.onicecandidate = function (event) {
if (event.candidate) {
socket.emit('remote_ice_candidate', {
ice: event.candidate
})
}
}
socket.on('pc_add_ice', function (event) {
pc.addIceCandidate(new RTCIceCandidate(event.ice))
})
//
pc.ontrack = function (e) {
// v.srcObject = e.streams[0];
console.log(e, 'pc.ontrack')
}
// 远端 sdp 设置到本地
socket.on('set_pc_remote_sdp', function (e) {
pc.setRemoteDescription(e.desc).then(
function () {
console.log('remote setRemoteDescription success')
pc.createAnswer().then(function (desc) {
pc.setLocalDescription(desc).then(
function () {
socket.emit('send_pc_sdp', {desc: desc})
},
function (err) {
console.log(err)
}
);
})
},
function () {
console.log('pc setLocalDescription error')
}
)
})
需求:
1.用户进入一个web
网站,该网站有一个没有视频源的video
标签。
2.用户通过手机打开一个该网站的子页面,调用手机摄像头
拍摄影像并传递到web
网站的video
标签上。
补充:
1.在console
中打印的iceConnectionState
时发现,phone.js
内部的iceConnectionState
触发过程:checking -> connected -> completed
;而index.js
中触发过程仅有checking -> connected
。
2.在firefox
下访问时,控制台内会提示ICE failed, add a STUN server and see about:webrtc for more details
。
没有人用过吗?给个webRtc的群也行啊。