Remote-Videostreams funktioniert nicht mit WebRTC

EDIT: ich schrieb eine detaillierte Anleitung, die erklärt, wie man ein einfaches Videochat-Anwendung einschließlich eines signaling-server:

Tutorial: Erstellen Sie Ihre eigenen Videochat-Anwendung mit HTML und JavaScript

Bitte sagen Sie mir, wenn Sie finden es hilfreich, die & verständlich. Danke!


ich versuche Streams zu arbeiten, über WebRTC und Websocket (nodejs-server). Soweit ich sehen kann der handshake über SDP-Werke und die Peerconnection etabliert ist.
Das problem ist, die Remote-Video nicht wiedergegeben wird. Das src-Attribut wird der Blob und die automatische Wiedergabe ist gesetzt, aber es will einfach nicht spielen.
Vielleicht bin ich etwas falsch mit dem ICE-Kandidaten (Sie sind für media-streaming, richtig?).
Gibt es eine Möglichkeit zu überprüfen, ob die PeerConnection richtig eingerichtet ist?

EDIT: Vielleicht sollte ich erklären, wie der code funktioniert

  1. Beim laden der website eine Verbindung zum websocket-server hergestellt ist, eine PeerConnection mit googles STUN-server erstellt und die Video-und Audio-Streams werden gesammelt & Hinzugefügt, um die PeerConnection

  2. Wenn ein Benutzer klickt auf "Angebot erstellen"-button eine Nachricht mit seiner Session-Beschreibung (SDP) wird an den server senden (client func sendOffer()), was sendet es an den anderen Benutzer

  3. Der andere Benutzer erhält die Nachricht und speichert die SDP erhielt er

  4. Wenn der Benutzer klickt auf "Angebot akzeptieren", das SDP Hinzugefügt RemoteDescription (func createAnswer ()), die sendet dann eine Antwort-Nachricht (mit der SDP von der Beantwortung-Benutzer), um das Angebot-Nutzer

  5. Beim Angebot-user-Seite das func offerAccepted() ausgeführt wird, fügt die SDP von den anderen user seinen RemoteDesription.

Ich bin nicht sicher, an welchem Punkt genau die icecandidate-Handler aufgerufen werden, aber ich denke, Sie sollten arbeiten, weil ich beide Protokolle auf beiden Seiten.

Hier mein Code (dies ist nur für Testzwecke, also selbst wenn es eine Funktion namens broadcast bedeutet es, dass nur 2 user können auf der gleichen website zu einem Zeitpunkt):

Markup index.html:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <style>
            #acceptOffer  {
                display: none;
            }
        </style>
    </head>
    <body>
        <h2>Chat</h2>
        <div>
            <textarea class="output" name="" id="" cols="30" rows="10"></textarea>
        </div>
        <button id="createOffer">create Offer</button>
        <button id="acceptOffer">accept Offer</button>

        <h2>My Stream</h2>
        <video id="myStream" autoplay src=""></video>
        <h2>Remote Stream</h2>
        <video id="remoteStream" autoplay src=""></video>

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
        <script src="websocketClient.js"></script>
</body>
</html>

Hier ist der Server-Code:

"use strict";

var webSocketsServerPort = 61122;

var webSocketServer = require('websocket').server,
http = require('http'),
clients = [];


var server = http.createServer(function(request, response) {
    //Not important for us. We're writing WebSocket server, not HTTP server
});
server.listen(webSocketsServerPort, function() {
    console.log((new Date()) + " Server is listening on port " + webSocketsServerPort);
});

var wsServer = new webSocketServer({
    httpServer: server
});

wsServer.on('request', function(request) {
    console.log((new Date()) + ' Connection from origin ' + request.origin + '.');

    var connection = request.accept(null, request.origin),
    index = clients.push(connection) - 1,
    userName=false;
    console.log((new Date()) + ' Connection accepted from '+connection.remoteAddress);

    //user sent some message
    connection.on('message', function(message) {
        var json = JSON.parse(message.utf8Data);

        console.log(json.type);
        switch (json.type) {
            case 'broadcast':
                broadcast(json);
            break;

            case 'emit':
                emit({type:'offer', data:json.data.data});
            break;

            case 'client':
                respondToClient(json, clients[index]);
            break;

            default:
                respondToClient({type:'error', data:'Sorry, i dont understand that.'}, clients[index]);
            break;

        }

    });

    connection.on('close', function(connection) {
        clients.splice(index,1);
        console.log((new Date()) + " Peer " + connection.remoteAddress + " disconnected.");
        broadcast({type:'text', data: userName+' has left the channel.'});
    });

    var respondToClient = function(data, client){
        client.sendUTF(JSON.stringify( data ));
    };

    var broadcast = function(data){
        for(var i = 0; i < clients.length; i++ ) {
            if(i != index ) {
                clients[i].sendUTF(JSON.stringify( data ));
            }
        }
    };
    var emit = function(){
        //TBD
    };
});

Und hier den Client-Code:

$(function () {
    "use strict";

    /**
    * Websocket Stuff
    **/

    window.WebSocket = window.WebSocket || window.MozWebSocket;

    //open connection
    var connection = new WebSocket('ws://url-to-node-server:61122'),
    myName = false,
    mySDP = false,
    otherSDP = false;

    connection.onopen = function () {
        console.log("connection to WebSocketServer successfull");
    };

    connection.onerror = function (error) {
        console.log("WebSocket connection error");
    };

    connection.onmessage = function (message) {
        try {
            var json = JSON.parse(message.data),
            output = document.getElementsByClassName('output')[0];

            switch(json.callback) {
                case 'offer':
                    otherSDP = json.data;
                    document.getElementById('acceptOffer').style.display = 'block';
                break;

                case 'setIceCandidate':
                console.log('ICE CANDITATE ADDED');
                    peerConnection.addIceCandidate(json.data);
                break;

                case 'text':
                    var text = output.value;
                    output.value = json.data+'\n'+output.value;
                break;

                case 'answer':
                    otherSDP = json.data;
                    offerAccepted();
                break;

            }

        } catch (e) {
            console.log('This doesn\'t look like a valid JSON or something else went wrong.');
            return;
        }
    };
    /**
    * P2P Stuff
    **/
    navigator.getMedia = ( navigator.getUserMedia ||
       navigator.webkitGetUserMedia ||
       navigator.mozGetUserMedia ||
       navigator.msGetUserMedia);

    //create Connection
    var peerConnection = new webkitRTCPeerConnection(
        { "iceServers": [{ "url": "stun:stun.l.google.com:19302" }] }
    );


    var remoteVideo = document.getElementById('remoteStream'),
        myVideo = document.getElementById('myStream'),

        //get local video-Stream and add to Peerconnection
        stream = navigator.webkitGetUserMedia({ audio: false, video: true }, function (stream) {
            myVideo.src = webkitURL.createObjectURL(stream);
            console.log(stream);
            peerConnection.addStream(stream);
    });

    //executes if other side adds stream
    peerConnection.onaddstream = function(e){
        console.log("stream added");
        if (!e)
        {
            return;
        }
        remoteVideo.setAttribute("src",URL.createObjectURL(e.stream));
        console.log(e.stream);
    };

    //executes if my icecandidate is received, then send it to other side
    peerConnection.onicecandidate  = function(candidate){
        console.log('ICE CANDITATE RECEIVED');
        var json = JSON.stringify( { type: 'broadcast', callback:'setIceCandidate', data:candidate});
        connection.send(json);
    };

    //send offer via Websocket
    var sendOffer = function(){
        peerConnection.createOffer(function (sessionDescription) {
            peerConnection.setLocalDescription(sessionDescription);
            //POST-Offer-SDP-For-Other-Peer(sessionDescription.sdp, sessionDescription.type);
            var json = JSON.stringify( { type: 'broadcast', callback:'offer',data:{sdp:sessionDescription.sdp,type:'offer'}});
            connection.send(json);

        }, null, { 'mandatory': { 'OfferToReceiveAudio': true, 'OfferToReceiveVideo': true } });
    };

    //executes if offer is received and has been accepted
    var createAnswer = function(){

        peerConnection.setRemoteDescription(new RTCSessionDescription(otherSDP));

        peerConnection.createAnswer(function (sessionDescription) {
            peerConnection.setLocalDescription(sessionDescription);
            //POST-answer-SDP-back-to-Offerer(sessionDescription.sdp, sessionDescription.type);
            var json = JSON.stringify( { type: 'broadcast', callback:'answer',data:{sdp:sessionDescription.sdp,type:'answer'}});
            connection.send(json);
        }, null, { 'mandatory': { 'OfferToReceiveAudio': true, 'OfferToReceiveVideo': true } });

    };

    //executes if other side accepted my offer
    var offerAccepted = function(){
        peerConnection.setRemoteDescription(new RTCSessionDescription(otherSDP));
        console.log('it should work now');
    };

    $('#acceptOffer').on('click',function(){
        createAnswer();
    });

    $('#createOffer').on('click',function(){
        sendOffer();
    });
});

Ich auch gelesen, dass der local-media-stream aufgefangen werden muss, bevor Sie ein Angebot senden. Bedeutet das, ich muss hinzufügen, dass es, wenn die PeerConnection erstellt?
I. e. so etwas wie dieses:

//create Connection
var peerConnection = new webkitRTCPeerConnection(
    { 
        "iceServers": [{ "url": "stun:stun.l.google.com:19302" }],
        "mediaStream": stream //attach media stream here?
    }
);

Vielen Dank im Voraus, ich freue mich über jede Hilfe!!!

EDIT2:
ich bin ein Stück weiter jetzt. es scheint, dass das hinzufügen der remote-Eis-Kandidaten (switch-case-setIceCandidate, die im client-code) nicht funktioniert, weil der "Eine ungültige oder illegale string angegeben wurde. ". das json-Format.Daten.Kandidaten-Objekt sieht wie folgt aus:

candidate: "a=candidate:1663431597 2 udp 1845501695 141.84.69.86 57538 typ srflx raddr 10.150.16.92 rport 57538 generation 0
↵"
sdpMLineIndex: 1
sdpMid: "video"

habe ich versucht die Schaffung einer neuen Kandidaten wie diese

 var remoteCandidate = new RTCIceCandidate(json.data.candidate);
 peerConnection.addIceCandidate(remoteCandidate);

aber ich habe immer noch ein syntax-Fehler

Schreibe einen Kommentar