寫(xiě)了很簡(jiǎn)單的一個(gè)demo,多次調(diào)試之后所有的報(bào)錯(cuò)都已經(jīng)解決了,但是現(xiàn)在還是沒(méi)能實(shí)現(xiàn)想要的效果。各位大佬幫看下是哪里出問(wèn)題了。
// 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})
})
// 斷開(kāi)
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
})
}
}
// 接收遠(yuǎn)端 ice
socket.on('send_ice_to_pc', function (event) {
pc.addIceCandidate(new RTCIceCandidate(event.ice.ice))
})
// 獲取用戶(hù)本地設(shè)備
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')
}
// 遠(yuǎn)端 sdp 設(shè)置到本地
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.用戶(hù)進(jìn)入一個(gè)web網(wǎng)站,該網(wǎng)站有一個(gè)沒(méi)有視頻源的video標(biāo)簽。
2.用戶(hù)通過(guò)手機(jī)打開(kāi)一個(gè)該網(wǎng)站的子頁(yè)面,調(diào)用手機(jī)攝像頭拍攝影像并傳遞到web網(wǎng)站的video標(biāo)簽上。
補(bǔ)充:
1.在console中打印的iceConnectionState時(shí)發(fā)現(xiàn),phone.js內(nèi)部的iceConnectionState觸發(fā)過(guò)程:checking -> connected -> completed;而index.js中觸發(fā)過(guò)程僅有checking -> connected。
2.在firefox下訪問(wèn)時(shí),控制臺(tái)內(nèi)會(huì)提示ICE failed, add a STUN server and see about:webrtc for more details。
北大青鳥(niǎo)APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國(guó)IT技能型緊缺人才,是大數(shù)據(jù)專(zhuān)業(yè)的國(guó)家
達(dá)內(nèi)教育集團(tuán)成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機(jī)構(gòu),是中國(guó)一站式人才培養(yǎng)平臺(tái)、一站式人才輸送平臺(tái)。2014年4月3日在美國(guó)成功上市,融資1
北大課工場(chǎng)是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國(guó)家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國(guó)制造2025”,實(shí)現(xiàn)中華民族偉大復(fù)興的升級(jí)產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國(guó)職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開(kāi)發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項(xiàng)目經(jīng)理從事移動(dòng)互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團(tuán)項(xiàng)目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺(tái)面向?qū)ο箝_(kāi)發(fā)經(jīng)驗(yàn),技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點(diǎn)難點(diǎn)突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫(kù),具有快速界面開(kāi)發(fā)的能力,對(duì)瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁(yè)制作和網(wǎng)頁(yè)游戲開(kāi)發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開(kāi)發(fā)經(jīng)驗(yàn)。曾經(jīng)歷任德國(guó)Software AG 技術(shù)顧問(wèn),美國(guó)Dachieve 系統(tǒng)架構(gòu)師,美國(guó)AngelEngineers Inc. 系統(tǒng)架構(gòu)師。