murat-dogan / node-datachannel

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

How to select the codec to use ? #228

Open oanguenot opened 3 months ago

oanguenot commented 3 months ago

I use node-datachannel 0.5.4 to do an echo-test from the browser.

I succeeded to send and receive my audio/video streams back and forth.

The offer is initiated by the browser to the node-datachannel that sends the answer.

My problem is that whatever I did, my streams always stay in H264 and G711. (Mac M2).

I think I didn't correctly understand how to do the codecs setup.

I did this on server side:

let pc = new nodeDataChannel.PeerConnection(user.id, {iceServers: ['stun:stun.l.google.com:19302']});

let video = new nodeDataChannel.Video('video', 'SendRecv');
video.addVP8Codec(96);
video.setBitrate(90000);

pc.addTrack(video);

And then I use the function sendMessageBinary() to copy the data received back to the browser in the same peer-connection.

As the browser offers VP8/Opus as its preferred codecs, I expected these to be the ones negotiated. But this is H264 and G711 that were negotiated (seen in chrome://webrtc-internals/)

So what do exactly the function addVP8Codec(...) as there is no real codecs managed by the node-datachannel. Is it possible to change the codec used and if yes, how ?

If not, why the H264 and G711 codecs have been selected. Are they the default ones or system codecs accessible from the library ?

Additionally, is it possible to add some API documentation for the media part (ie: Audio, Video, Track and RtcpReceivingSession) ?

Except that, my echo-test works fine :-)

Thanks in advance

paullouisageneau commented 3 months ago

The offer is initiated by the browser to the node-datachannel that sends the answer.

You can't create a new track in an answer, so the addTrack() you do on server side can't have the expected effect. You should instead offer on server side an the browser will conform to the selected codec(s).

oanguenot commented 3 months ago

Thanks @paullouisageneau for your quick answer. I will do that.

oanguenot commented 3 months ago

I did the following (and by doing the offer on server side)

let video = new nodeDataChannel.Video('video', 'SendRecv');
video.addVP8Codec(96);
video.addRTXCodec(97, 96, 90000);

let trackVideo = user.pc.addTrack(video);
let sessionVideo = new nodeDataChannel.RtcpReceivingSession();
trackVideo.setMediaHandler(sessionVideo);

// Echo
trackVideo.onMessage((message) => {
    trackVideo.sendMessageBinary(message);
});

I successfully got a VP8 stream. I saw that the targetBitrate seems to be caped 300000. Why could be the reason and is it a possibility to go above ? Thanks in advance

paullouisageneau commented 3 months ago

I saw that the targetBitrate seems to be caped 300000. Why could be the reason and is it a possibility to go above ? Thanks in advance

Have you set video.setBitrate(bitrate_in_kbps)?

oanguenot commented 3 months ago

I tried with different values (3000, 5000) and without. In all cases, the browser seems to limit its bitrate to 300kbps when sending the video stream to the server. On browser side, I just asked for a 720P video stream and didn't make any changes on the SDP before sending the answer.

Screenshot 2024-03-18 at 13 44 28

Browser and server are launched both locally (same machine).

oanguenot commented 3 months ago

Note: If I don't create a datachannel but only a peerConnection with a media transport, the connection is not established.

I need to call pc.createDataChannel('myChannel') in order to open the connection.