来自WebRTC远程对等视频元素的音频未被播放

时间:2018-05-11 13:43:04

标签: javascript node.js socket.io webrtc

我正在创建一个使用WebRTC在用户之间建立对等连接的应用程序。当用户加入应用程序时。它们将被放入一个Socket.io房间,只有2个用户可以进入并仅被提示输入音频。当第二个用户连接到同一个URL时。我向服务器发送一个事件,将它们作为第一个用户放在同一个Socket.io房间,并运行所有WebRTC代码,如创建RTCPeerConnection,RTCInceCandidates和RTCSessionDescription实例,具体取决于从服务器向另一个广播的事件。连接同伴,但由于某种原因,我没有让远程用户的音频播放到我能听到的地方,他们可以听到我的声音。

p2p.js文件(负责设置连接的所有代码)

// roomURL.addEventListener('click', function (e) {
//     document.execCommand('copy')
// });

// roomURL.addEventListener('copy', function (e) {
//     e.preventDefault();
//     if (e.clipboardData) {
//         e.clipboardData.setData('text/plain', roomURL.textContent);
//     }
// });

let isInitializer = false;
let isChannelReady = false;
let isStarted = false;
let pc;
let localStream;
let remoteStream;

/**
 * - Create new RTCPeerConnection
 * - Listen for events on newly created RTCPeerConnection (onicecandidate, onaddstream, onremovestream)
 */

const pcConfig = {
    iceServers: [{
        urls: 'stun:stun.l.google.com:19302'
    }]
};

const room = 'foo';

const socket = io();

if (room !== '') {
    socket.emit('create or join', room);
    console.log('Attempted to create or join room ' + room);
}

socket.on('created', function (room) {
    isInitializer = true;
    console.log('Created room ' + room);
});

socket.on('full', function (room) {
    console.log('Room ' + room + ' is full');
});

socket.on('join', function (room) {
    console.log('Another peer made a request to join room ' + room);
    console.log('This peer is the initiator of room ' + room + '!');
    isChannelReady = true;
});

socket.on('joined', function (room) {
    console.log('joined: ' + room);
    isChannelReady = true;
});

function sendMessage(message) {
    socket.emit('message', message);
}

//////////////////////////////////////////////////////////////////////////////////

socket.on('message', function (message) {
    if (message === 'got user media') {
        start();
        console.log('Got user media');
    } else if (message.type === 'offer') {
        if (!isInitializer && !isStarted) {
            start();
        }
        pc.setRemoteDescription(new RTCSessionDescription(message));
        answer();
        console.log('Offer')
    } else if (message.type === 'answer' && isStarted) {
        pc.setRemoteDescription(new RTCSessionDescription(message));
        console.log('Answer');
    } else if (message.type === 'candidate' && isStarted) {
        const candidate = new RTCIceCandidate({
            sdpMLineIndex: message.label,
            candidate: message.candidate
        });
        pc.addIceCandidate(candidate);
        console.log('Candidate');
    }
});

/////////////////////////////////////////////////////////////////////////////////

var localVideo = document.querySelector('#localVideo');
var remoteVideo = document.querySelector('#remoteVideo');

navigator.mediaDevices.getUserMedia({
    audio: true, video: false
}).then((stream) => {
    localStream = stream;
    console.log('My Stream', stream);
    localVideo.srcObject = stream;
    sendMessage('got user media');
    if (isInitializer) {
        start();
    }
});

//////////////////////////////////////////////////////////////////////////////////

function start() {
    if (!isStarted && typeof localStream !== 'undefined' && isChannelReady) {
        createPeerConnection();
        const tracks = localStream.getTracks();
        for (const track of tracks) {
            pc.addTrack(track);
        }
        isStarted = true;
        if (isInitializer) {
            call();
        }
    }
}

function createPeerConnection() {
    pc = new RTCPeerConnection(null);
    pc.onicecandidate = function (e) {
        if (e.candidate) {
            sendMessage({
                type: 'candidate',
                label: e.candidate.sdpMLineIndex,
                id: e.candidate.sdpMid,
                candidate: e.candidate.candidate
            });
        }
    }
    pc.ontrack = function (e) {
        console.log('Remote track added', e);
        remoteStream = e.streams[0];
        remoteVideo.srcObject = remoteStream;
    }
}

//////////////////////////////////////////////////////////////////////////////////

function call() {
    pc.createOffer(null).then((sessionDescription) => {
        pc.setLocalDescription(sessionDescription);
        sendMessage(sessionDescription);
    }).catch(e => console.log(e));
}

function answer() {
    pc.createAnswer(null).then((sessionDescription) => {
        pc.setLocalDescription(sessionDescription);
        sendMessage(sessionDescription);
    });
}

index.js(用于侦听Socket.io事件的Express服务器)

const express = require('express');
const path = require('path');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
const os = require('os');

app.use(express.static(path.resolve(__dirname, '../public')));

app.get('*', (req, res) => {
    res.sendFile(path.resolve(__dirname, '../public/index.html'));
});

const port = process.env.PORT || 3000;
server.listen(port, () => {
    console.log(('Server listening on port ' + port));
});

io.on('connection', (socket) => {
    socket.on('create or join', (room) => {
        const clientsRoom = (io.sockets.adapter.rooms[room]);
        const roomSize = (clientsRoom ? clientsRoom.length : 0);

        if (roomSize === 0) {
            console.log('Joined room with no one');
            socket.join(room);
            console.log(('Room ' + room + ' now has ' + roomSize + ' connected client(s)'));
            socket.emit('created', room, socket.id);
        } else if (roomSize === 1) {
            console.log(('Client ID ' + socket.id + ' created room ' + room));
            io.sockets.in(room).emit('join', room);
            socket.join(room);
            console.log(('Room ' + room + ' now has ' + roomSize + ' connected client(s) and is full'));
            socket.emit('joined', room, socket.id);
            io.sockets.in(room).emit('ready');
        } else {
            console.log(('Room ' + room + ' is full'));
            socket.emit('full', room);
        }
    });

    socket.on('message', (message) => {
        socket.broadcast.emit('message', message);
    });
});

1 个答案:

答案 0 :(得分:0)

remoteVideo.play();之后添加remoteVideo.srcObject = remoteStream;

如果仍然不起作用,请尝试:

try {

    remoteVideo.srcObject = remoteStream;

} catch(error) {

    remoteVideo.src = URL.createObjectURL(remoteStream);
};

remoteVideo.play();