3

So, I have an adaptation of https://github.com/Dirvann/mediasoup-sfu-webrtc-video-rooms working in vanilla JS that I am attempting to adapt to use React. Instead of every user being a broadcaster, in my version, only the room creator is the broadcaster.

I've hit an issue. In the React version, when a viewer navigates to the room, they are not receiving the stream! I have no idea why since they use the same RoomClient class: https://github.com/Dirvann/mediasoup-sfu-webrtc-video-rooms/blob/master/public/RoomClient.js

This line const consumer = await this.consumerTransport.consume({ id, producerId, kind, rtpParameters, codecOptions, }); seems to be causing the problem, since the log following it doesn't get printed. Inside the consume function, my log that says 'hi' is executed, but 'blah' is not. Here is a screenshot of the client console: enter image description here

The most important functions are found below. For the entire class, please click the github link above.

  async consume(producer_id) {
    //let info = await roomInfo()
    console.log('consume ', producer_id);
    console.log('dddddddddddd', await this.getConsumeStream(producer_id));
    this.getConsumeStream(producer_id).then(
      function ({ consumer, stream, kind }) {
        console.log('blah');
        this.consumers.set(consumer.id, consumer);

        let elem;
        console.log('clg kind === ', kind);
        if (kind === 'video') {
          console.log('cons vid');
          elem = document.createElement('video');
          elem.srcObject = stream;
          elem.id = consumer.id;
          elem.playsinline = false;
          elem.autoplay = true;
          elem.className = 'vid';
          this.remoteVideoEl.appendChild(elem);
        } else {
          elem = document.createElement('audio');
          elem.srcObject = stream;
          elem.id = consumer.id;
          elem.playsinline = false;
          elem.autoplay = true;
          this.remoteAudioEl.appendChild(elem);
        }

        consumer.on(
          'trackended',
          function () {
            this.removeConsumer(consumer.id);
          }.bind(this)
        );
        consumer.on(
          'transportclose',
          function () {
            this.removeConsumer(consumer.id);
          }.bind(this)
        );
      }.bind(this)
    );
  }

  async getConsumeStream(producerId) {
    const { rtpCapabilities } = this.device;
    console.log('rtpcaps ', rtpCapabilities);
    const data = await this.socketRequest('consume', {
      rtpCapabilities,
      consumerTransportId: this.consumerTransport.id, // might be
      producerId,
    }).then((data) => {
      console.log('daaatttaaa', data);
      return data;
    });
    const { id, kind, rtpParameters } = data;

    console.log('data === ', data);

    let codecOptions = {};
    console.log('aaaaaaaaaaaaaa', this.consumerTransport.consume);
    const consumer = await this.consumerTransport
      .consume({
        id,
        producerId,
        kind,
        rtpParameters,
        codecOptions,
      })
      .then((result) => {
        console.log('bbbbbbb', result);
        return result;
      });
    console.log('consumer === ', consumer);

    const stream = new MediaStream();
    console.log('stream === ', stream);
    stream.addTrack(consumer.track);
    console.log('kind ', kind);
    return {
      consumer,
      stream,
      kind,
    };
  }

Many thanks for your time

---update---

This line never resolves: const consumer = await this.consumerTransport.consume({ id, producerId, kind, rtpParameters, codecOptions, }) It ends up executing some complex-looking functions from packages. In fact, It seems to get stuck in an infinite loop in the package called sdp-transform, after executing a few lines in mediasoup-client.

I don't even understand how chrome debugger's working. Because if I put a breakpoint on that line where ...consume(... is called, and click 'step', it parses this line: let answer = await this._pc.createAnswer() ... Which is part of a function called receive, which wasn't called by the breakpoint line... Please, somebody help.

harry young
  • 600
  • 1
  • 8
  • 24

1 Answers1

0

You said something interesting there. 'hi' gets logged and 'blah' not. There isn't much code in between them. This should make us wonder how it is even possible.

Maybe create the same just without any distractions around.

Promise.resolve()
    .then(console.log('hi'))
    .then(function() {
        console.log('blah');
    })

What would that do? and why?

.then is a function that expects to be given a function (to be called when the promise resolves...)

What does console.log('hi') return? And when is it executed?

You did not want to execute the log when creating the promise chain and you also want to maybe return the result again since you want to work with the value.

So my guess would be. Changing it to:

.then(result => {
    console.log('hi')
    return result
})

brings you at least a step closer.

ian
  • 1,112
  • 1
  • 5
  • 15
  • 1
    Thanks, I'm no good with promise chaining, so I learned something there. Anyhow it wasn't joining the room before I added the .then(... console.log('hi')). Your comment is helpful, but not the solution. – harry young Mar 11 '21 at 00:05