проблема с двунаправленной видеоконференцсвязью webrtc - PullRequest
1 голос
/ 26 марта 2020

Заранее спасибо.

Я следую руководству по реализации webrt c с официальной страницы:

https://webrtc.org/

И у меня проблемы с двусторонней связью. На одном устройстве p c у меня есть видеокамера, а на другом только микрофон.

Мне удается получить видеокамеру, но я не могу получить событие .ontrack на устройстве p c, которое отправляет видеокамеру и он должен получать только аудио, когда я добавляю трек на компьютер, который отправляет аудио, но не запускает событие .ontrack на удаленном компьютере.

Соединение установлено правильно, здесь вставьте соединение и код

МОЙ КОД один локальный хост / видео. php другой localhsot / видео. php? cliente = 1

<?php
/**
 * Created by PhpStorm.
 * User: Jesús
 * Date: 16/03/2020
 * Time: 13:16
 */
 ?>

<video id="localVideo" autoplay <?= !isset($_GET['cliente']) ? 'muted' : '' ?> playsinline controls="false" style="width: 600px; height: 320px;"></video>

<?php
if(!isset($_GET['cliente'])) {
?>
<button onclick="makeCallAdmin()">enviar llamada</button>
<?php
}
?>

<script src="../app/js/lib/socket.io.js"></script>

<script>

    let cliente = <?= isset($_GET['cliente']) ? 'true' : 'false' ?>;
    let tipo = cliente ? 'client' : 'admin';

    var ipSocket = 'SCOCKETADDRESS';
    // var ipSocket = 'https://192.168.125.175:3001';
    var idgrupo = '5ed44424c2df0470d689.4f6370fbe1ac319e5dc1d7417822d28a';

    var socket = io(ipSocket, {
        query: "grupo=" + idgrupo + "&tipo=" + tipo
    });


    const iceConfiguration = {
        iceServers: [
            {

                urls: 'stun:stun.l.google.com:19302?transport=udp'
            },
            {

                urls: 'turns:turnserver',
                username: 'prueba',
                credential: '123456'
            }
        ],
    }

    const offerOptions = {
        offerToReceiveAudio: 1,
        offerToReceiveVideo: 1
    };

    // let peerConnection, remoteStream, videoElement;
    let peerConnection;
    let fuerzaConectar;



    async function getConnectedDevices(type) {
        const devices = await navigator.mediaDevices.enumerateDevices();
        return await devices.filter(device => device.kind === type)
    }

    // Open camera with at least minWidth and minHeight capabilities
    async function openCamera(cameraId, audioid) {

        let constraints;

        if(!cameraId) {
            constraints = {
                'audio': {'echoCancellation': true}
            }

        }else{
            constraints = {
                'audio': {'echoCancellation': true},
                'video': {
                    'deviceId': cameraId
                }
            }
        }

        // constraints = {'video': true, 'audio': true};

        return await navigator.mediaDevices.getUserMedia(constraints);
    }

    async function playVideoFromCamera(peerConnection, type, fuerza) {
        if(type == null)
            type = 'videoinput';
        if(fuerza == null)
            fuerza = false;

        try {
            const cameras = await getConnectedDevices(type);
            if (cameras && cameras.length > 0) {

                let stream;

                if(fuerza) //si solo ha encontrado el audio enviamos solo audio
                    stream = await openCamera(false, cameras[0].deviceId);
                else //si ha encontrado camara enviamos camara y audio
                    stream = await openCamera(cameras[0].deviceId, false);

                stream.getTracks().forEach(track => {
                    peerConnection.addTrack(track, stream);
                });


            }else{
                if(!fuerza)
                    await playVideoFromCamera(peerConnection, 'audioinput', true);
                else
                    console.log('no hay input');
            }

        } catch(error) {
            console.error('Error opening video camera.', error);
        }
    }


    async function makeCallAdmin() {

        fuerzaConectar = (fuerzaConectar == null | !fuerzaConectar) ? true : false;

        if(typeof peerConnection == 'object') {
            peerConnection.close();
            peerConnection = null;
            const videoElement = document.querySelector('video#localVideo');
            videoElement.srcObject = null;
            if(cliente)
                socket.off('videoconferenciaRecibeCliente');
            else
                socket.off('videoconferenciaRecibeAdmin');
        }

        peerConnection = new RTCPeerConnection(iceConfiguration);

        const remoteStream = new MediaStream();


        // Listen for local ICE candidates on the local RTCPeerConnection
        // peerConnection.removeEventListener('icecandidate', iceCandidate);
        // peerConnection.addEventListener('icecandidate', iceCandidate);
        peerConnection.onicecandidate = e => iceCandidate(e);

        // Listen for connectionstatechange on the local RTCPeerConnection
        // peerConnection.removeEventListener('iceconnectionstatechange', iceconnectionstatechange);
        peerConnection.oniceconnectionstatechange = e => iceconnectionstatechange(e, peerConnection);

        // peerConnection.removeEventListener('track', track);
        // peerConnection.addEventListener('track', trackEv);
        peerConnection.ontrack =  e => trackEv(e, remoteStream);




        socket.on('videoconferenciaRecibeAdmin', data => videoconferenciaRecibeAdmin(data, peerConnection));

        const offer = await peerConnection.createOffer(offerOptions);
        await peerConnection.setLocalDescription(offer);
        socket.emit('videoconferenciaAdmin', {'tipo':'remoteDescription','offer': offer});
    }

    async function makeCallCliente() 
    {

        fuerzaConectar = (fuerzaConectar == null | !fuerzaConectar) ? true : false;

        if(typeof peerConnection == 'object') {
            peerConnection.close();
            peerConnection = null;
            const videoElement = document.querySelector('video#localVideo');
            videoElement.srcObject = null;
            if(cliente)
                socket.off('videoconferenciaRecibeCliente');
            else
                socket.off('videoconferenciaRecibeAdmin');
        }

        peerConnection = await new RTCPeerConnection(iceConfiguration);

        const remoteStream = await new MediaStream();


        // Listen for local ICE candidates on the local RTCPeerConnection
        // peerConnection.removeEventListener('icecandidate', iceCandidate);
        // peerConnection.addEventListener('icecandidate', iceCandidate);
        peerConnection.onicecandidate = e => iceCandidate(e);

        // Listen for connectionstatechange on the local RTCPeerConnection
        // peerConnection.removeEventListener('iceconnectionstatechange', iceconnectionstatechange);
        peerConnection.oniceconnectionstatechange = e => iceconnectionstatechange(e, peerConnection);

        // peerConnection.removeEventListener('track', track);
        // peerConnection.addEventListener('track', trackEv);
        peerConnection.ontrack =  e => trackEv(e, remoteStream);



        socket.on('videoconferenciaRecibeCliente', data => videoconferenciaRecibeCliente(data, peerConnection, ));



    }

    async function videoconferenciaRecibeCliente(data, peerConnection)
    {

        switch(data.tipo) {
            case 'remoteDescription':
                if (data.offer) {
                    console.log(data.offer);
                    await peerConnection.setRemoteDescription(new RTCSessionDescription(data.offer));
                    const answer = await peerConnection.createAnswer(offerOptions);
                    await peerConnection.setLocalDescription(answer);

                    await socket.emit('videoconferenciaCliente', {'tipo':'remoteDescription','answer': answer});
                    console.log('recibida conexion cliente');
                    console.log(peerConnection);
                }
                break;
            case 'icecandidate':
                if (data.icecandidate) {
                    try {
                        await peerConnection.addIceCandidate(data.icecandidate);
                        console.log('creado ice candidate cliente');
                        console.log(data.icecandidate);
                    } catch (e) {
                        console.error('Error adding received ice candidate', e);
                    }
                }
                break;

        }


    }

    async function videoconferenciaRecibeAdmin(data, peerConnection)
    {

        switch(data.tipo) {
            case 'remoteDescription':
                if (data.answer) {
                    console.log(data.answer);
                    const remoteDesc = new RTCSessionDescription(data.answer);
                    await peerConnection.setRemoteDescription(remoteDesc);
                    console.log('recibida conexion admin');
                    console.log(peerConnection);
                }
                break;
            case 'icecandidate':
                if (data.icecandidate) {
                    try {
                        await peerConnection.addIceCandidate(data.icecandidate);
                        console.log('creado ice candidate admin');
                        console.log(data.icecandidate);
                    } catch (e) {
                        console.error('Error adding received ice candidate', e);
                    }
                }
                break;
        }

    }

    async function iceCandidate(event)
    {

        let el_evento = cliente ? 'videoconferenciaCliente' : 'videoconferenciaAdmin';

        if (event.candidate) {
            socket.emit(el_evento, {'tipo':'icecandidate','icecandidate': event.candidate});
        }

    }

    async function iceconnectionstatechange(event, peerConnection)
    {

        console.log(peerConnection.iceConnectionState);

        switch(peerConnection.iceConnectionState) {
            case 'connected':
                console.log('CONECTADO');
                await enviarLLamada(peerConnection);
                switch(true) {
                    case fuerzaConectar && cliente:
                        // makeCallCliente();
                        break;
                    case fuerzaConectar && !cliente:
                        makeCallAdmin();
                        break;
                }
                break;
            case 'disconnected':
                console.log('DESconectado');
                await peerConnection.close();
                peerConnection = null;
                const videoElement = document.querySelector('video#localVideo');
                videoElement.srcObject = null;
                if(cliente)
                    await socket.off('videoconferenciaRecibeCliente');
                else
                    await socket.off('videoconferenciaRecibeAdmin');


                break;
        }

    }

    async function trackEv(event, remoteStream)
    {

        const videoElement = document.querySelector('video#localVideo');
        if(videoElement.srcObject == null)
            videoElement.srcObject = remoteStream;

        console.log('entra a TRACK');
        await remoteStream.addTrack(event.track, remoteStream);
        // videoElement.play();
    }

    async function enviarLLamada(peerConnection)
    {

        await playVideoFromCamera(peerConnection);

    }

    document.addEventListener("DOMContentLoaded", function(event) { 
        if(cliente)
            makeCallCliente();
        // else
        //     makeCallAdmin();

    });





</script>



...