首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用simple-peer直播网络摄像头视频。NodeJs

使用simple-peer直播网络摄像头视频。NodeJs
EN

Stack Overflow用户
提问于 2020-01-01 00:58:50
回答 3查看 2.9K关注 0票数 0

我正在尝试使用simple-peer库将实时视频流从网络摄像头广播到服务器,并从服务器广播到多个用户。我目前在stun/turn服务器上遇到了问题。我正在使用Xirsys。该程序在本地运行没有任何问题,但当我在Heroku上运行它时,它就没有问题了。我是NodeJs的新手。

有人知道为什么它在本地运行,而不是全局运行吗?

客户端:

代码语言:javascript
复制
let Peer = require('simple-peer')
let socket = io()
const video = document.querySelector('video')
let client = {}

var configuration={
    iceServers: [{
        urls: [ "stun:sp-turn1.xirsys.com" ]
     }, {
        username: "LdzgXD2MWspU8qKuKIa9nYv02AqPhqD_qOeFSCsJfBjaCwq5mN-LsbrHReCmgGLwAAAAAF4HabRjYW1pbG9oaW5vam9zYQ==",
        credential: "320899dc-2980-11ea-810a-06374c00029e",
        urls: [
            "turn:sp-turn1.xirsys.com:80?transport=udp",
            "turn:sp-turn1.xirsys.com:3478?transport=udp",
            "turn:sp-turn1.xirsys.com:80?transport=tcp",
        ]
     }]
}

function CreateVideo(stream){
    video.srcObject = stream
    video.play()
}

document.getElementById('stream').onclick=function(){
    navigator.mediaDevices.getUserMedia({ video: true, audio: true })
    .then(stream=>{
        socket.emit('NewClientStreamer')
        video.srcObject = stream
        video.play()

        socket.on('CreateClientStreamerPeer',function(){
            let peer = new Peer({ 
                initiator:true,
                config:configuration,
                iceTransportPolicy: 'relay', 
                stream: stream, 
                trickle:true
            })
            peer.on('stream',function(stream){
                CreateVideo(stream)
            })
            peer.on('close',function(){
                document.getElementById("peerVideo").remove()
                peer.destroy()
            })
            peer.on('signal', function(data){
                if(!client.gotAnswer)
                    socket.emit('Offer',data)
            })
            client.peer=peer
        })

        socket.on('Answer',function(answer){
            client.gotAnswer=true
            client.peer.signal(answer)        
        })

    })
    .catch(err=>document.write(err))
}

document.getElementById('receive').onclick=function(){

    socket.emit('NewClientReceiver')

    socket.on('Offer',function(offer){
        let peer = new Peer({ 
            initiator: false,
            trickle:true
         })
        peer.on('stream',function(stream){
            CreateVideo(stream)
        })
        peer.on('signal', function(data){
            socket.emit('ClientAnswer',data)
        })
        peer.signal(offer)
        client.peer=peer
    })
}

服务器端:

代码语言:javascript
复制
const express = require('express')
const app = express()
const http = require('http').Server(app)
const io = require('socket.io')(http)
const port = process.env.PORT || 3000

const Peer=require('simple-peer')
const wrtc=require('wrtc')

var Streamer={}
var Receiver={}



var configuration={
    iceServers: [{
        urls: [ "stun:sp-turn1.xirsys.com" ]
     }, {
        username: "LdzgXD2MWspU8qKuKIa9nYv02AqPhqD_qOeFSCsJfBjaCwq5mN-LsbrHReCmgGLwAAAAAF4HabRjYW1pbG9oaW5vam9zYQ==",
        credential: "320899dc-2980-11ea-810a-06374c00029e",
        urls: [
            "turn:sp-turn1.xirsys.com:80?transport=udp",
            "turn:sp-turn1.xirsys.com:3478?transport=udp",
            "turn:sp-turn1.xirsys.com:80?transport=tcp",
        ]
     }]
}

app.use(express.static(__dirname + "/public"))

io.on('connection', function(socket){

    socket.on('NewClientStreamer',function(){
        socket.emit('CreateClientStreamerPeer')
    })

    function InitializeReceiver(offer){
        var receiver={}
        let peer = new Peer({
            initiator:false,
            config:configuration,
            iceTransportPolicy: 'any',
            wrtc:wrtc,
            trickle:true
         })
        peer.on('signal', (data) => {
            socket.emit('Answer',data)
        })
        peer.on('close',function(){
            //
        })
        peer.on('stream',function(stream){
            receiver.stream=stream
            receiver.peer=peer
            Receiver=receiver
        })
        peer.signal(offer)
    }

    socket.on('Offer',function(offer){
        InitializeReceiver(offer)
    })

    socket.on('NewClientReceiver',function(){
        var streamer={}
        streamer.gotAnswer=false
        let peer = new Peer({
            initiator:true,
            config:configuration,
            iceTransportPolicy: 'any',
            wrtc:wrtc,
            stream: Receiver.stream, 
            trickle:true
        })
        peer.on('signal', function(offer){
            if(!streamer.gotAnswer)
                socket.emit('Offer',offer)
        })
        peer.on('connect',function(){
            Streamer=streamer
        })
        streamer.peer=peer

        socket.on('ClientAnswer',function(data){    
            streamer.gotAnswer=true
            streamer.peer.signal(data)  
        })
    })




})

http.listen(port,() => console.log(`Active on ${port} port`))

WebRTC-Chrome-webRTC internals

EN

回答 3

Stack Overflow用户

发布于 2020-01-04 00:49:55

所以你最初的问题的答案是:为什么它在本地运行,而不是在服务器上运行:这是因为在本地运行,你可以在同一网络中运行服务器和客户端,或者通过简单的NAT和STUN服务器可以解决客户端和服务器的外部IP。当您在服务器上运行时,您的服务器或客户端位于双NAT或对称NAT之后。根据你的代码,这应该不是问题,因为你配置了TURN服务器,但是如果你查看你的WebRTC统计数据,这个配置没有被应用,使用了一些其他的配置,见截图。当我从我的计算机上运行它时,根本没有配置TURN服务器,显然我的IP地址没有被解析,因为我在双NAT之后,连接失败,请参阅我的日志:

代码语言:javascript
复制
https://bolxmultitest.herokuapp.com/, { iceServers: [stun:stun.l.google.com:19302, stun:global.stun.twilio.com:3478?transport=udp], iceTransportPolicy: all, bundlePolicy: balanced, rtcpMuxPolicy: require, iceCandidatePoolSize: 0, sdpSemantics: "unified-plan" },
iceconnectionstatechange (legacy)
checking
03/01/2020, 16:10:42    
connectionstatechange
connecting
03/01/2020, 16:10:42    
icecandidate (host)
sdpMid: 0, sdpMLineIndex: 0, candidate: candidate:1416191245 1 udp 2113937151 cb0baca2-665d-45a9-9c92-5fd0accdbb0f.local 51937 typ host generation 0 ufrag 9Gjl network-cost 999
03/01/2020, 16:10:42    
icecandidate (srflx)
sdpMid: 0, sdpMLineIndex: 0, candidate: candidate:842163049 1 udp 1677729535 37.24.130.114 51937 typ srflx raddr 0.0.0.0 rport 0 generation 0 ufrag 9Gjl network-cost 999
03/01/2020, 16:10:42    
icegatheringstatechange
complete
03/01/2020, 16:10:57    
iceconnectionstatechange
disconnected
03/01/2020, 16:10:57    
iceconnectionstatechange (legacy)
failed
03/01/2020, 16:10:57    
connectionstatechange
failed

STUN/TURN配置应该类似于日志中的配置,因为这是在上面的代码中配置的:

代码语言:javascript
复制
{ iceServers: [stun:sp-turn1.xirsys.com:3478, turns:sp-turn1.xirsys.com:443?transport=tcp], iceTransportPolicy: all, bundlePolicy: balanced, rtcpMuxPolicy: require, iceCandidatePoolSize: 0, sdpSemantics: "unified-plan" }

你需要调试为什么你的代码中的配置没有被应用,为什么你和我有不同的配置,以及这个配置来自哪里。

票数 0
EN

Stack Overflow用户

发布于 2020-01-04 04:08:26

I have detected the problem why my credentials were not the same as the code, it was because I had forgotten to run watchify to modify the bundle.js script based on the main.js

这些是我新的webRTC chrome内饰。现在凭据匹配,但它仍然不能运行。谢谢你,伊戈尔·赫沃斯滕科夫

这是运行新存储库的应用程序的链接:https://bolx-tests.herokuapp.com/

票数 0
EN

Stack Overflow用户

发布于 2020-01-04 05:01:32

您修复了服务器上用于从客户端到服务器的流的STUN/TURN服务器问题,但您也需要在客户端修复此问题。如果您在尝试接收流时查看日志,您将看到一个

STUN/TURN服务器的配置与代码中的配置不同。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59546739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档