Code Monkey home page Code Monkey logo

rtcpeerconnection-shim's Introduction

RTCPeerConnection shim

This repository contains an implementation of the W3C RTCPeerConnection API as a shim ontop of the ORTC API provided by Microsoft Edge.

It was added to adapter.js in late 2015 but in 2017 was being split out for easier maintenance.

Q&A

This is crazy, ORTC is the better API!

Yes. This is internally known as the wicked shim of the west.

the wicked witch of the west, namesake for this (courtesy of wіkipedia)

rtcpeerconnection-shim's People

Contributors

davies147 avatar fippo avatar syerrapragada avatar tgabi333 avatar zzxx53 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

rtcpeerconnection-shim's Issues

createOffer should ignore rejected datachannel transceivers

  it.only('...', () => {
    const sdp = SDP_BOILERPLATE +
        'm=application 9 DTLS/SCTP 5000\r\n' +
        'c=IN IP4 0.0.0.0\r\n' +
        'a=ice-ufrag:' + ICEUFRAG + '\r\n' +
        'a=ice-pwd:' + ICEPWD + '\r\n' +
        'a=fingerprint:sha-256 ' + FINGERPRINT_SHA256 + '\r\n' +
        'a=setup:actpass\r\n' +
        'a=mid:data\r\n' +
        'a=sctpmap:5000 webrtc-datachannel 1024\r\n';
    const pc = new RTCPeerConnection();
    pc.setRemoteDescription({type: 'offer', sdp})
      .then(() => pc.createAnswer())
      .then((answer) => pc.setLocalDescription(answer))
      .then(() => pc.createOffer())
      .then((offer) => console.log(offer.sdp))
  });

throws

(node:31948) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'getLocalParameters' of undefined
    at module.exports (/home/fippo/webrtc/wicked/writemediasection.js:21:31)

createOffer should skip over rejected datachannel m-lines the same way createAnswer does.

Disabled media in offer causes nullptr exception

How to reproduce:

  1. Call setRemoteDescription with OFFER which contains enabled audio media and disabled video media.
  2. Call setLocalDescription with generated ANSWER.
  3. Transceiver for video was not created and than you get nullptr exception here:
      var isIceLite = SDPUtils.matchPrefix(sessionpart,
          'a=ice-lite').length > 0;
      sections.forEach(function(mediaSection, sdpMLineIndex) {
        var transceiver = pc.transceivers[sdpMLineIndex];
        var iceGatherer = transceiver.iceGatherer;
  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

My solution now is:

      var isIceLite = SDPUtils.matchPrefix(sessionpart,
          'a=ice-lite').length > 0;
      sections.forEach(function(mediaSection, sdpMLineIndex) {
        var transceiver = pc.transceivers[sdpMLineIndex];
        if (!transceiver)
              return;
        var iceGatherer = transceiver.iceGatherer;

Though of course I don't know all the details but this can give you some ideas on how to properly fix this case.

Could not complete the operation due to error c004e008

Here's an incoming SDP which I feed inside setRemoteDescription.
This was originally taken from Chrome and slightly modified inside my gateway.

v=0
o=WebRTC 328414035 281589450 IN IP4 192.168.1.47
s=3CXWebRTC audio call
c=IN IP4 192.168.1.47
t=0 0
m=audio 9356 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 110 112 113 126
c=IN IP4 192.168.1.47
a=rtpmap:111 opus/48000
a=fmtp:111 minptime=10;useinbandfec=1
a=rtpmap:103 ISAC/16000
a=rtpmap:104 ISAC/32000
a=rtpmap:9 G722/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:106 CN/32000
a=rtpmap:105 CN/16000
a=rtpmap:13 CN/8000
a=rtpmap:110 telephone-event/48000
a=rtpmap:112 telephone-event/32000
a=rtpmap:113 telephone-event/16000
a=rtpmap:126 telephone-event/8000
a=ptime:20
a=sendrecv
a=candidate:1234 1 udp 572662306 192.168.1.47 9356 typ host generation 0
a=end-of-candidates
a=ice-ufrag:ISEhISEhISIiISIh
a=ice-pwd:IiIiIiIhIiIiISIhISIhISIi
a=fingerprint:sha-256 12:5C:71:5B:A7:AB:AC:E9:70:22:86:2E:1D:D0:EF:E7:81:47:05:D8:15:B3:A4:D2:DC:11:B1:3A:16:C9:3C:D2
a=rtcp:9356 IN 192.168.1.47
a=rtcp-mux
a=setup:actpass

transceiver.rtpReceiver.receive(params) gives me upper error: Could not complete the operation due to error c004e008

It starts to work once I remove opus rtp.
Do you have any ideas why?

onaddstream/ontrack fires async

should be sync before SRD is resolving. There is a test for this even
triggers ontrack and track event before resolving
but it does not do what it says.

signalingstatechange is emitted even if there are no updates

    it('does stuff', () => {
      const sdp = SDP_BOILERPLATE +
          MINIMAL_AUDIO_MLINE;
      pc.onsignalingstatechange = () => console.log('here');
      return pc.setRemoteDescription({type: 'offer', sdp})
      .then(() => pc.setRemoteDescription({type: 'offer', sdp}));
    });

logs 'here' twice. It should not since the spec says

10. If connection's signaling state changed above, fire a simple event named
 signalingstatechange at connection.

https://w3c.github.io/webrtc-pc/#set-the-rtcsessiondescription

wrong treatment of video-audio offers

reported by @dagingaa.
If you call addTrack(audioTrack), addTrack(videoTrack) and then set an offer containing a video mline followed by an audio mline the answer will be wrong. This happens with offers from safari, other browsers
Fiddle with repro data:
https://jsfiddle.net/mu6kcxrw/1/

There is a test for a similar issue here ('keeps the order from the remote offer') but it did not catch this behaviour, possibly due to the assertion being too weak.

Event target is set to DocumentFragment instead of peer connection itself

We started to use adapter in our calls and faced an issue with Edge where we would get a DocumentFragment as a target for onNegotiationNeeded event. After digging into adapter's logic we discovered that rtcpeerconnection-shim does this explicitly https://github.com/otalk/rtcpeerconnection-shim/blob/master/rtcpeerconnection.js#L41.
We were wondering if there are reasons for such a thing?
P.S. we use peer connection from event to check the current state (signalingState, iceConnectionState) and then create an offer.
Thanks!

Asymmetic media negotiation fails

     console.log('pc1 adds an video track');
      const stream1 = await navigator.mediaDevices.getUserMedia({video: true, fake: true});
      const [localVideoTrack] = stream1.getVideoTracks();
      pc1.addTrack(localVideoTrack, stream1);

      console.log('pc2 adds an audio track');
      const stream2 = await navigator.mediaDevices.getUserMedia({audio: true, fake: true});
      const [localAudioTrack1] = stream2.getAudioTracks();
      pc2.addTrack(localAudioTrack1, stream2);

      console.log('pc1 and pc2 negotiate');
      offer = await pc1.createOffer();
      await Promise.all([pc1.setLocalDescription(offer), pc2.setRemoteDescription(offer)]);
      answer = await pc2.createAnswer();
      await Promise.all([await pc2.setLocalDescription(answer), await pc1.setRemoteDescription(answer)]);

Above example fails to negotiate.

shim WebRTC 1.0 name changes compared to ORTC

Name changes (ondtlsstatechange -> onstatechange, onicestatechange -> onstatechange, getNominatedCandidatePair -> getSelectedCandidatePair, RTCDtmfSender -> RTCDTMFSender)
Object model incongruities:
RTCIceTransport.getLocalCandidates (shimmed from RTCIceGatherer.getLocalCandidates)
RTCIceTransport attributes (visible from adapter.js but not native WebRTC 1.0 API in Edge)

via @aboba

Edge remote dtls parameters seems to have a hardcoded role of client.

Hello,

We are using rtcpeerconnection-shim for RTCPeerConnections with Edge. Here's what we have as an offer/answer scenario:

1) Edge sending a SDP offer with `a=setup:actpass`
2) Edge getting a SDP answer with `a=setup:passive`
3) This results in both peers staying passive so no DTLS handshake is initiated.

It all boils down to this line and it seems that remote dtls parameters role is hardcoded to client while it should be read from the sdp a=setup:... lines ?
https://github.com/otalk/rtcpeerconnection-shim/blob/master/rtcpeerconnection.js#L870

Please advice if this is an issue or an intended behaviour ?

error thrown in createOffer for a rejected datachannel

    describe('rejects a legacy datachannel offer', () => {
...
      it.only('in setRemoteDescription with a local track', () => {
        // test that we don't forget about the track.
        return navigator.mediaDevices.getUserMedia({audio: true})
          .then((stream) => {
            pc.addTrack(stream.getTracks()[0], stream);
            return pc.setRemoteDescription({type: 'offer', sdp: sdp});
          })
          .then(() => pc.createAnswer())
          .then((answer) => pc.setLocalDescription(answer))
          .then(() => pc.createOffer())
          .then((offer) => {
            const sections = SDPUtils.getMediaSections(offer.sdp);
            expect(sections).to.have.length(2);
            expect(SDPUtils.isRejected(sections[0])).to.equal(true);
            expect(SDPUtils.kind(sections[1])).to.equal('audio');
          });
      });

This does weird stuff in createOffer, creating an ice gatherer for the rejected m-line and then failing.

Failed ice connection between Edge and Safari with empty MediaStream

Steps to reproduce:

  1. Create new MediaStream() in Safari.
  2. Add this stream to connection.
  3. Gather ice candidates.
  4. Send offer with ice candidates to Edge.
  5. Add ice candidates to connection.
  6. Gather ice candidates on Edge side.
  7. Send answer with ice candidates to Safari.
  8. Add ice candidates to connection.

Actual result:
iceConnectionState became 'checking'.
After few seconds iceConnectionState became 'failed'.

Also I tried to create media stream with video and audio. In that case iceConnectionState became connected, but I'd got an error "OperationError (DOM Exception 34): Failed to set local sdp: Session error code: ERROR_CONTENT. Session error description: Failed to set local audio description recv parameters.."

This problem occurred only for Edge - Safari connection.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.