Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8999511
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 16, 20262026-06-16T00:11:24+00:00 2026-06-16T00:11:24+00:00

I’ve been trying to get this works, but I don’t know what’s wrong, can

  • 0

I’ve been trying to get this works, but I don’t know what’s wrong, can you guys help me? I tried WebRTC code with modification like this.

  • Both caller and callee enter the web
  • Web will create channel based on their username
  • Caller clicks the call button and sends message to spesific channel to some user’s username. When caller clicks the call button, he then creates peerConnection and adds localStream
  • Callee will receive message, and the process goes on like WebRTC sample code. When callee receives an offer, he then creates peerConnection and adds localStream, then creates and sends answer

My code goes like this

        var my_username = '{{ current_username }}';
        var friend;

        var localVideo;
        var remoteVideo;
        var localStream;
        var remoteStream;
        var channel;
        var channelReady = false;
        var pc;
        var socket;
        var started = false;
        // Set up audio and video regardless of what devices are present.
        var mediaConstraints = {'mandatory': {
                        'OfferToReceiveAudio':true, 
                        'OfferToReceiveVideo':true }};
        var isVideoMuted = false;
        var isAudioMuted = false;


        function choiceFriendInitialize() {
            var choice_visible = false;

            $('ul#friendlist > li').click(function(e) {
                $(this).css('background-color', '#808080');
                friend = $(this).text();
                var choice = $('ul#choice');
                choice_visible = true;
                choice.css('display', 'inline-block');
                choice.css('top', e.pageY);
                choice.css('left', e.pageX);
            });

            // trigger call from here
            $('li#call').click(function() {
                $('ul#friendlist > li').css('background-color', 'transparent');
                $('ul#choice').css('display', 'none');
                choice_visible = false;

                // call
                maybeStart();
                doCall();
            });

            $('li#unfriend').click(function() {
                $('ul#friendlist > li').css('background-color', 'transparent');
                $('ul#choice').css('display', 'none');
                choice_visible = false;
            });

            $("body").mouseup(function(){ 
                if (choice_visible) {
                    $('ul#friendlist > li').css('background-color', 'transparent');
                    $('ul#choice').css('display', 'none');
                    choice_visible = false;
                }
            });
        }

        function initialize() {
            console.log("Initializing..");
            choiceFriendInitialize();

            localVideo = document.getElementById("localVideo");
            remoteVideo = document.getElementById("remoteVideo");
            openChannel();
            doGetUserMedia();
        }

        function openChannel() {
            console.log("Opening channel.");
            var channel = new goog.appengine.Channel('{{ token }}');
            var handler = {
                'onopen': onChannelOpened,
                'onmessage': onChannelMessage,
                'onerror': onChannelError,
                'onclose': onChannelClosed
            };
            socket = channel.open(handler);
        }

        function doGetUserMedia() {
            // Call into getUserMedia via the polyfill (adapter.js).
            var constraints = {"mandatory": {}, "optional": []};
            try {
                getUserMedia({'audio':true, 'video':constraints}, onUserMediaSuccess, onUserMediaError);
                console.log("Requested access to local media with mediaConstraints:\n" + "  \"" + JSON.stringify(constraints) + "\"");
            } catch (e) {
                alert("getUserMedia() failed. Is this a WebRTC capable browser?");
                console.log("getUserMedia failed with exception: " + e.message);
            }
        }

        function createPeerConnection() {
            var pc_config = {"iceServers": [{"url": "stun:stun.l.google.com:19302"}]};
            try {
                // Create an RTCPeerConnection via the polyfill (adapter.js).
                pc = new RTCPeerConnection(pc_config);
                pc.onicecandidate = onIceCandidate;
                console.log("Created RTCPeerConnnection with config:\n" + "  \"" + JSON.stringify(pc_config) + "\".");
            } catch (e) {
                console.log("Failed to create PeerConnection, exception: " + e.message);
                alert("Cannot create RTCPeerConnection object; WebRTC is not supported by this browser.");
                return;
            }
            pc.onconnecting = onSessionConnecting;
            pc.onopen = onSessionOpened;
            pc.onaddstream = onRemoteStreamAdded;
            pc.onremovestream = onRemoteStreamRemoved;
        }

        function maybeStart() {
            if (!started && localStream && channelReady) {
                console.log("Creating PeerConnection.");
                createPeerConnection();
                console.log("Adding local stream.");
                pc.addStream(localStream);
                started = true;
                // Caller initiates offer to peer.
                //if (initiator)
                    //doCall();
            }
        }

        function doCall() {
            console.log("Sending offer to peer.");
            pc.createOffer(setLocalAndSendMessage, null, mediaConstraints);
        }

        function doAnswer() {
            console.log("Sending answer to peer.");
            pc.createAnswer(setLocalAndSendMessage, null, mediaConstraints);
        }

        function setLocalAndSendMessage(sessionDescription) {
            // Set Opus as the preferred codec in SDP if Opus is present.
            sessionDescription.sdp = preferOpus(sessionDescription.sdp);
            pc.setLocalDescription(sessionDescription);
            sendMessage({from: my_username, to: friend}, sessionDescription);
        }

        function sendMessage(client, message) {
            console.log('C->S: ' + JSON.stringify(message));
            var xhr = new XMLHttpRequest();
            xhr.open('POST', '/send', true);
            xhr.setRequestHeader("Content-type","application/json");
            var msgString = {send_info: client, data_message: message};
            xhr.send(JSON.stringify(msgString));
        }

        function processSignalingMessage(message) {
            var msg = JSON.parse(message);
            var data_message = msg.data_message;
            var send_info = msg.send_info;
            if (data_message.type === 'offer') {
                // Callee creates PeerConnection
                if (!started)
                    maybeStart();
                pc.setRemoteDescription(new RTCSessionDescription(data_message));

                friend = send_info.from;
                doAnswer();
            } else if (data_message.type === 'answer' && started) {
                pc.setRemoteDescription(new RTCSessionDescription(data_message));
            } else if (data_message.type === 'candidate' && started) {
                var candidate = new RTCIceCandidate({sdpMLineIndex:data_message.label, candidate:data_message.candidate});
                pc.addIceCandidate(candidate);
            } else if (data_message.type === 'bye' && started) {
                onRemoteHangup();
            }
        }

        function onChannelOpened() {
            console.log('Channel opened.');
            channelReady = true;
        }

        function onChannelMessage(message) {
            console.log('S->C: ' + message.data);
            processSignalingMessage(message.data);
        }

        function onChannelError() {
            console.log('Channel error.');
        }

        function onChannelClosed() {
            console.log('Channel closed.');
        }

        function onUserMediaSuccess(stream) {
            console.log("User has granted access to local media.");
            // Call the polyfill wrapper to attach the media stream to this element.
            attachMediaStream(localVideo, stream);
            localVideo.style.opacity = 1;
            localStream = stream;
            // Caller creates PeerConnection.
            //if (initiator) maybeStart();
        }

        function onUserMediaError(error) {
            console.log("Failed to get access to local media. Error code was " + error.code);
            alert("Failed to get access to local media. Error code was " + error.code + ".");
        }

        function onIceCandidate(event) {
            if (event.candidate) {
                sendMessage({from: my_username, to: friend}, {type: 'candidate',
                    label: event.candidate.sdpMLineIndex,
                    id: event.candidate.sdpMid,
                    candidate: event.candidate.candidate});
            } else {
                console.log("End of candidates.");
            }
        }

        function onSessionConnecting(message) {
            console.log("Session connecting.");
        }

        function onSessionOpened(message) {
            console.log("Session opened.");
        }

        function onRemoteStreamAdded(event) {
            console.log("Remote stream added.");
            attachMediaStream(remoteVideo, event.stream);
            remoteStream = event.stream;
            waitForRemoteVideo();
        }

        function onRemoteStreamRemoved(event) {
            console.log("Remote stream removed.");
        }

        function onHangup() {
            console.log("Hanging up.");
            transitionToDone();
            stop();
            // will trigger BYE from server
            socket.close();
        }

        function onRemoteHangup() {
            console.log('Session terminated.');
            transitionToWaiting();
            stop();
        }

        function stop() {
            started = false;
            isAudioMuted = false;
            isVideoMuted = false;
            pc.close();
            pc = null;
        }

        function waitForRemoteVideo() {
            if (remoteStream.videoTracks.length === 0 || remoteVideo.currentTime > 0) {
                console.log('ada remote stream');
                transitionToActive();
            } else {
                console.log('ga ada remote stream');
                setTimeout(waitForRemoteVideo, 100);
            }
        }

        function transitionToActive() {
            remoteVideo.style.opacity = 1;
        }

        function transitionToWaiting() {
            remoteVideo.style.opacity = 0;
        }

        function transitionToDone() {
            localVideo.style.opacity = 0;
            remoteVideo.style.opacity = 0;
        }

        function toggleVideoMute() {
            if (localStream.videoTracks.length === 0) {
                console.log("No local video available.");
                return;
            }

            if (isVideoMuted) {
                for (i = 0; i < localStream.videoTracks.length; i++) {
                    localStream.videoTracks[i].enabled = true;
                }
                console.log("Video unmuted.");
            } else {
                for (i = 0; i < localStream.videoTracks.length; i++) {
                    localStream.videoTracks[i].enabled = false;
                }
                console.log("Video muted.");
            }
            isVideoMuted = !isVideoMuted;
        }

        function toggleAudioMute() {
            if (localStream.audioTracks.length === 0) {
                console.log("No local audio available.");
                return;
            }

            if (isAudioMuted) {
                for (i = 0; i < localStream.audioTracks.length; i++) {
                    localStream.audioTracks[i].enabled = true;
                }
                console.log("Audio unmuted.");
            } else {
                for (i = 0; i < localStream.audioTracks.length; i++){
                    localStream.audioTracks[i].enabled = false;
                }
                console.log("Audio muted.");
            }

            isAudioMuted = !isAudioMuted;
        }

        setTimeout(initialize, 1);

        // Send BYE on refreshing(or leaving) a demo page
        // to ensure the room is cleaned for next session.
        window.onbeforeunload = function() {
            sendMessage({from: my_username, to: friend}, {type: 'bye'});
            //Delay 100ms to ensure 'bye' arrives first.
            setTimeout(function(){}, 100);
        }

        // Ctrl-D: toggle audio mute; Ctrl-E: toggle video mute.
        // On Mac, Command key is instead of Ctrl.
        // Return false to screen out original Chrome shortcuts.
        document.onkeydown = function() {
            if (navigator.appVersion.indexOf("Mac") != -1) {
                if (event.metaKey && event.keyCode === 68) {
                    toggleAudioMute();
                    return false;
                }
                if (event.metaKey && event.keyCode === 69) {
                    toggleVideoMute();
                    return false;
                }
            } else {
                if (event.ctrlKey && event.keyCode === 68) {
                    toggleAudioMute();
                    return false;
                }
                if (event.ctrlKey && event.keyCode === 69) {
                    toggleVideoMute();
                    return false;
                }
            }
        }

        // Set Opus as the default audio codec if it's present.
        function preferOpus(sdp) {
            var sdpLines = sdp.split('\r\n');
            // Search for m line.
            for (var i = 0; i < sdpLines.length; i++) {
                if (sdpLines[i].search('m=audio') !== -1) {
                    var mLineIndex = i;
                    break;
                }
            }
            if (mLineIndex === null)
                return sdp;
                // If Opus is available, set it as the default in m line.
            for (var i = 0; i < sdpLines.length; i++) {
                if (sdpLines[i].search('opus/48000') !== -1) {
                    var opusPayload = extractSdp(sdpLines[i], /:(\d+) opus\/48000/i);
                    if (opusPayload)
                        sdpLines[mLineIndex] = setDefaultCodec(sdpLines[mLineIndex], opusPayload);
                    break;
                }
            }
            // Remove CN in m line and sdp.
            sdpLines = removeCN(sdpLines, mLineIndex);
            sdp = sdpLines.join('\r\n');
            return sdp;
        }

        function extractSdp(sdpLine, pattern) {
            var result = sdpLine.match(pattern);
            return (result && result.length == 2)? result[1]: null;
        }

        // Set the selected codec to the first in m line.
        function setDefaultCodec(mLine, payload) {
            var elements = mLine.split(' ');
            var newLine = new Array();
            var index = 0;
            for (var i = 0; i < elements.length; i++) {
                if (index === 3) // Format of media starts from the fourth.
                    newLine[index++] = payload; // Put target payload to the first.
                if (elements[i] !== payload)
                    newLine[index++] = elements[i];
            }
            return newLine.join(' ');
        }

        // Strip CN from sdp before CN constraints is ready.
        function removeCN(sdpLines, mLineIndex) {
            var mLineElements = sdpLines[mLineIndex].split(' ');
            // Scan from end for the convenience of removing an item.
            for (var i = sdpLines.length-1; i >= 0; i--) {
                var payload = extractSdp(sdpLines[i], /a=rtpmap:(\d+) CN\/\d+/i);
                if (payload) {
                    var cnPos = mLineElements.indexOf(payload);
                    if (cnPos !== -1) {
                        // Remove CN payload from m line.
                        mLineElements.splice(cnPos, 1);
                    }
                    // Remove CN line in sdp
                    sdpLines.splice(i, 1);
                }
            }
            sdpLines[mLineIndex] = mLineElements.join(' ');
            return sdpLines;
        }

When it comes to waitForRemoteVideo, the function calls the else condition. But the blob url for remoteVideo exists.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-16T00:11:25+00:00Added an answer on June 16, 2026 at 12:11 am

    It’s funny that I’ve been searching for the error and re-writing the code for like three times, and suddenly after posted my question here, I realized my mistake.

    Here in the function processSignallingMessage..

    if (data_message.type === 'offer') {
        // Callee creates PeerConnection
        if (!started)
            maybeStart();
            pc.setRemoteDescription(new RTCSessionDescription(data_message));
    
            friend = send_info.from;
            doAnswer();
        } else ....
    

    Should be like this:

    if (data_message.type === 'offer') {
        friend = send_info.from;
        // Callee creates PeerConnection
        if (!started)
            maybeStart();
            pc.setRemoteDescription(new RTCSessionDescription(data_message));
    
    
            doAnswer();
        } else ....
    

    because callee need variable friend to be filled before sending candidate message.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm trying to convert HTML to plain text. I get many &\#8217; &\#8220; etc.
Does anyone know how can I replace this 2 symbol below from the string
I have a jquery bug and I've been looking for hours now, I can't
This could be a duplicate question, but I have no idea what search terms
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
I know there's a lot of other questions out there that deal with this
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have just tried to save a simple *.rtf file with some websites and
I want to count how many characters a certain string has in PHP, but

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.