【问题标题】:The audio from the WebRTC remote peer video element isn't being played未播放来自 WebRTC 远程对等视频元素的音频
【发布时间】:2018-05-11 13:43:03
【问题描述】:

我正在制作一个使用 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);
    });
});

【问题讨论】:

    标签: javascript node.js socket.io webrtc


    【解决方案1】:

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

    如果还是不行,试试这个:

    try {
    
        remoteVideo.srcObject = remoteStream;
    
    } catch(error) {
    
        remoteVideo.src = URL.createObjectURL(remoteStream);
    };
    
    remoteVideo.play();
    

    【讨论】:

    • 感谢您的回复。我会在我的代码库中尝试一下,并告诉你它是否有任何改变。不过 ATM 很忙。
    猜你喜欢
    • 2020-09-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    • 2021-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    相关资源
    最近更新 更多