murat-dogan / node-datachannel

WebRTC For Node.js and Electron. libdatachannel node bindings.
Mozilla Public License 2.0
291 stars 55 forks source link

Add an example sending an encoded stream with datachannel #122

Closed Canees closed 2 years ago

Canees commented 2 years ago

Can you create a media sender example to send data packets with libx264 encoders such as ffmpeg

If I succeed in doing this in my own project, I will try to put forward such an example.

Canees commented 2 years ago

I tried it, but localDescription was null, please help me . image

paullouisageneau commented 2 years ago

This is expected as the local description is only present after setLocalDescription() is called, provided a track has been added with addTrack() beforehand.

Note than rather than getting the offer synchronously with localDescription(), you should use the onLocalDescription callback to get it and send it.

murat-dogan commented 2 years ago

Hi, Sorry for late reply. As @paullouisageneau commented it is expected and ok. If you have a working example for this then please create a PR. It will be great. Thanks,

Canees commented 2 years ago

Hi, Sorry for late reply. As @paullouisageneau commented it is expected and ok. If you have a working example for this then please create a PR. It will be great. Thanks,

of course

Canees commented 2 years ago

This is expected as the local description is only present after setLocalDescription() is called, provided a track has been added with addTrack() beforehand.

Note than rather than getting the offer synchronously with localDescription(), you should use the onLocalDescription callback to get it and send it. I may not have made myself clear. Peer1 use datachannel create offer send to peer2(Web),I used the demo of datachannel in WEbRTC: https://github.com/mdn/samples-server/tree/master/s/webrtc-simple-datachannel

Whether it can't send an offer unsolicited: image

paullouisageneau commented 2 years ago

The API is quite simplified and there is no createOffer() method like in the browser WebRTC API. With the browser API it's actually good practice to just call setLocalDescription() without a manual description so the signaling state is handled for you.

Here, just call setLocalDescription() to create and set the offer. You might pass an explicit argument to force an offer but it's not useful.

The code should look like this:

init() {
    this.Peer.onLocalDescription((sdp, type) => {
       this.socket.emit('msg',  { sdp, type });
    });
    this.Peer.onLocalCandidate((candidate, mid) => {
       this.socket.emit('msg', { candidate, mid });
    });
}

msg(data) {
    if (data.type == 'offer' || data.type == 'answer') {
        this.Peer.setRemoteDescription(data.sdp, data.type);
    } else if (data.type == 'candidate') {
        this.Peer.setRemoteCandidate(data.candidate, data.mid);
    } else if (data.type == 'startRTC') {
        // [Add an offered track here with this.Peer.addTrack(media)]
        this.Peer.setLocalDescription();
    }
}
Canees commented 2 years ago

The API is quite simplified and there is no createOffer() method like in the browser WebRTC API. With the browser API it's actually good practice to just call setLocalDescription() without a manual description so the signaling state is handled for you.

Here, just call setLocalDescription() to create and set the offer. You might pass an explicit argument to force an offer but it's not useful.

The code should look like this:

init() {
    this.Peer.onLocalDescription((sdp, type) => {
       this.socket.emit('msg',  { sdp, type });
    });
    this.Peer.onLocalCandidate((candidate, mid) => {
       this.socket.emit('msg', { candidate, mid });
    });
}

msg(data) {
    if (data.type == 'offer' || data.type == 'answer') {
        this.Peer.setRemoteDescription(data.sdp, data.type);
    } else if (data.type == 'candidate') {
        this.Peer.setRemoteCandidate(data.candidate, data.mid);
    } else if (data.type == 'startRTC') {
        // [Add an offered track here with this.Peer.addTrack(media)]
        this.Peer.setLocalDescription();
    }
}

Oh, I looked at your libDatachannel and it's very, very simple and I wonder why WebrTC is so tedious.

Thank you very much, dear Paul. I have achieved it server: image pc: image

kirianguiller commented 9 months ago

I'm sorry to write a message in a closed issue, but this issue is the closest one to the question I currently have, and it might be more relevant to ask it here than to open a new one.

I would like to send a video stream (from a go2rtc server) from a server (but more specifically a node-datachannel client) to another node-datachannel client. However, I don't understand how to send this stream.

In this current issue, we can see that @Canees set the Video track on the server, but I don't understand how this track is reading from another source.

Here is the relevant code snippet from @Canees :

  this.socket.on('msg', data =>{
    // not showing the unrelevant part of the code
    if (data.type === 'startRTC') {
      // test video
      const video = new nodeDataChannel.Video('video', nodeDataChannel.Direction.SendOnly);
      video.addH264Codec(96);
      video.addSSRC(42, 'video-send');
      this.Peer.addTrack(video)
      this.Peer.setLocalDescription()
    }
  })

Is the video.addSSRC method responsible for this ? How does it works ? I don't see this method being tested in the tests files, neither do I see it in one of the 5 examples. Maybe this project could benefit by having an example showing how to use this library to send a video stream with datachannel. I would gladly help adding such an example once I will have figured how to make this works.

Thanks a lot for your help !