在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問(wèn)答/Java  Linux  HTML/ webrtc + socket.io 實(shí)現(xiàn)一個(gè)視頻分享的功能

webrtc + socket.io 實(shí)現(xiàn)一個(gè)視頻分享的功能

寫(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。

回答
編輯回答
冷溫柔

沒(méi)有人用過(guò)嗎?給個(gè)webRtc的群也行啊。

2017年9月12日 11:35