# How to add media stream to a producer

**URL:** <https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967>\
**Category:** Integration\
**Created:** [February 17, 2023, 6:51pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967 "2023-02-17T18:51:38Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![indie](https://avatars.discourse-cdn.com/v4/letter/i/b5e925/32.png) [@indie](https://mediasoup.discourse.group/u/indie)\
**Post date:** [February 17, 2023, 6:51pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/1 "2023-02-17T18:51:38Z")

</div>

Hi,

I am using NodeJS with mediasoup v3 for creating a sfu server using mediasoup v3.  
But i don’t understand if what i do is well and how to add the media stream that i get from the front end to the producer.

I would like to know, how to add a media stream to a pipe producer, so every consumer who join the stream can get the media stream and see a livestream or video conference.

Here is my code for creating the pipeProducer on a nodejs back end:

```auto
async createPipeProducer(userStreamerId: string, mediaStream: MediaStream) {
const router = await this.createRouterFromWorker(this.worker);

    const transport = await router.createWebRtcTransport(
        {
            webRtcServer : this.server, // Or ListenIps
            // listenIps : [{ ip: "192.168.0.111", announcedIp: "88.12.10.41" }],
            enableUdp : true,
            enableTcp : true,
            preferUdp : true
        }
    );

    transport.on("icestatechange", (iceState) => {
        console.log(`ICE state changed to ${iceState}`);
    });

    // Get the supported RTP capabilities
    const rtpCapabilities = router.rtpCapabilities;

    // Create the producer
    const pipeProducer = await transport.produce({
        kind: 'video',
        rtpParameters: rtpCapabilities["video"].codecs.find(codec => codec.mimeType.toLowerCase() === "video/vp8"),
        appData: { type: 'pipe' }
    });

    // Set the media stream as the source of the producer
    const track = mediaStream.getVideoTracks()[0];
    track.onended = () => {
        pipeProducer.pause();
    };

    // It's in this part that i am stuck
    const mediaSender = await pipeProducer.getStats();
    const rtpSenders = mediaSender[0].rtpSenders;
    mediaSender.send(track);

    return pipeProducer;
}

```

Am i making everything great ? Expect for add a media stream to the producer, so every consumer can join a specific producer’s stream.  
I can provide more informations if it can help you to help me.  
Thanks for your help.

---

<div class="post-metadata">

**Author:** ![zaidiqbal](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/zaidiqbal/32/1498_2.png) [@zaidiqbal](https://mediasoup.discourse.group/u/zaidiqbal)\
**Post date:** [February 17, 2023, 7:06pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/2 "2023-02-17T19:06:14Z")

</div>

You are mixing server side code with client side code, we do this on server side:

> [@indie](#):
>
> ```auto
> // Create the producer
> const pipeProducer = await transport.produce({
> kind: 'video',
> rtpParameters: rtpCapabilities["video"].codecs.find(codec => codec.mimeType.toLowerCase() === "video/vp8"),
> appData: { type: 'pipe' }
> });
> 
> ```

And this on client side:

> [@indie](#):
>
> ```auto
> const router = await this.createRouterFromWorker(this.worker);
> 
> const transport = await router.createWebRtcTransport(
> {
> webRtcServer : this.server, // Or ListenIps
> // listenIps : [{ ip: "192.168.0.111", announcedIp: "88.12.10.41" }],
> enableUdp : true,
> enableTcp : true,
> preferUdp : true
> }
> );
> 
> ```

I think you have missed many things in the documentation, perhaps a look at the demo code will give you good understanding.

> **[GitHub - versatica/mediasoup-demo: mediasoup official demo application](https://github.com/versatica/mediasoup-demo)**
>
> mediasoup official demo application. Contribute to versatica/mediasoup-demo development by creating an account on GitHub.

Further more you have mentioned about ‘piping’, this is not used normally but only used when we need to share producer between routers within a server on between separate servers.

**Apart from this the basic step to produce are these:**

- Create router, workers etc on server
- Create transport on server, and based upon the result create transport on client as well
- Use transport.produce() method to produce track on the transport you just created. It will give you producer
- After that ‘producer’ event will fire on transport you created, and on that event you will send producer details on your server.
- After that ‘connect’ event will fire on transport you created, and on that event you will send transport details so finally peer connection will be established and track will start flowing to the server.

---

<div class="post-metadata">

**Author:** ![indie](https://avatars.discourse-cdn.com/v4/letter/i/b5e925/32.png) [@indie](https://mediasoup.discourse.group/u/indie)\
**Post date:** [February 24, 2023, 8:33pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/3 "2023-02-24T20:33:52Z")

</div>

and how to add the media stream to a producer then ? In the front end or in the back end ?

---

<div class="post-metadata">

**Author:** ![indie](https://avatars.discourse-cdn.com/v4/letter/i/b5e925/32.png) [@indie](https://mediasoup.discourse.group/u/indie)\
**Post date:** [February 24, 2023, 9:29pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/4 "2023-02-24T21:29:25Z")

</div>

i have asked chatGPT and createWebRtcTransport can be used in both back end and front end.  
Here is his answer:

`createWebRtcTransport` is part of the mediasoup library and can be used in both the front-end and the back-end.

In a server-side application, `createWebRtcTransport` would typically be called on the server to create a WebRTC transport object that can be used to send and receive media streams from clients. In a client-side application, `createWebRtcTransport` would typically be called on the browser to create a WebRTC transport object that can be used to send and receive media streams from the server.

So, `createWebRtcTransport` is not specific to the front-end or the back-end, but rather it is used in both contexts.

---

<div class="post-metadata">

**Author:** ![indie](https://avatars.discourse-cdn.com/v4/letter/i/b5e925/32.png) [@indie](https://mediasoup.discourse.group/u/indie)\
**Post date:** [February 25, 2023, 6:05pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/5 "2023-02-25T18:05:50Z")

</div>

I understand the flow now.  
But i have checked the mediasoup-client library and it seems that the connect() method doesn’t exist.  
why that ?  
Do i still ahve to connect before using produce() method ?  
If yes and if it doesn’t exist anymore, by what should i change that ?

Thanks for your help.

---

<div class="post-metadata">

**Author:** ![snnz](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/snnz/32/693_2.png) [@snnz](https://mediasoup.discourse.group/u/snnz)\
**Post date:** [February 26, 2023, 8:30am UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/6 "2023-02-26T08:30:37Z")

</div>

The first call to `produce` will initiate the connection process internally. You should catch the “connect” event on the transport and manage the signalling.

---

<div class="post-metadata">

**Author:** ![zaidiqbal](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/zaidiqbal/32/1498_2.png) [@zaidiqbal](https://mediasoup.discourse.group/u/zaidiqbal)\
**Post date:** [February 26, 2023, 8:56am UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/7 "2023-02-26T08:56:29Z")

</div>

createWebRtcTransport is used in backend while createSendTransport/ createRecvTransport is used on client side.

Follow the docs brother, I think you are rushing through the docs, take your time and it will all reveal to you.

---

<div class="post-metadata">

**Author:** ![zaidiqbal](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/zaidiqbal/32/1498_2.png) [@zaidiqbal](https://mediasoup.discourse.group/u/zaidiqbal)\
**Post date:** [February 26, 2023, 9:03am UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/8 "2023-02-26T09:03:21Z")

</div>

> [@indie](#):
>
> But i have checked the mediasoup-client library and it seems that the connect() method doesn’t exist.

There is no connect() method in mediasoup-client, on client side we have ‘connect’ event while on server side we have connect() method:

> **[mediasoup :: API](https://mediasoup.org/documentation/v3/mediasoup-client/api/#transport-on-connect)**
>
> Cutting Edge WebRTC Video Conferencing

> **[mediasoup :: API](https://mediasoup.org/documentation/v3/mediasoup/api/#transport-connect)**
>
> Cutting Edge WebRTC Video Conferencing

When you call produce() on client side then it will trigger ‘connect’ event on transport automatically on that event you will signal to your server some parameters and on server side you will call transport.connect() method and then these transports are connected.

---

<div class="post-metadata">

**Author:** ![indie](https://avatars.discourse-cdn.com/v4/letter/i/b5e925/32.png) [@indie](https://mediasoup.discourse.group/u/indie)\
**Post date:** [February 26, 2023, 2:08pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/9 "2023-02-26T14:08:27Z")

</div>

I did that, can you confirm me it is correct in this way ?  
I first create a new instance of Device:

> const device = new Device();

Then i use createSendTransport method from device 🙂

> this.sendTransport = device.createSendTransport(responseStreamCreated.transport.transportOptions);

Then listen the connect event:

> this.sendTransport.on(‘connect’, ({ dtlsParameters }, callback) =\> {  
> // Send dtlsParameters to the backend  
> callback();  
> });

From now it seems to work, but once i try to isten produce event to add the media stream audio and media stream video to make a stream like that:

> this.sendTransport.on(‘produce’, async (parameters, callback, errback) =\> {  
> try {  
> this.localStream.getTracks().forEach(async (track) =\> {  
> const producer = await this.sendTransport.produce({  
> track: this.localStream.getTracks()[0],  
> codecOptions: {  
> opusStereo: true,  
> opusDtx: true,  
> },  
> });  
> callback({ id: producer.id });  
> });  
> } catch (err) {  
> errback(err);  
> }  
> });

Is everything alright ?

---

<div class="post-metadata">

**Author:** ![zaidiqbal](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/zaidiqbal/32/1498_2.png) [@zaidiqbal](https://mediasoup.discourse.group/u/zaidiqbal)\
**Post date:** [February 26, 2023, 2:17pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/10 "2023-02-26T14:17:33Z")

</div>

> [@indie](#):
>
> > this.sendTransport.on(‘produce’, async (parameters, callback, errback) =\> {  
> > try {  
> > this.localStream.getTracks().forEach(async (track) =\> {  
> > const producer = await this.sendTransport.produce({  
> > track: this.localStream.getTracks()[0],  
> > codecOptions: {  
> > opusStereo: true,  
> > opusDtx: true,  
> > },  
> > });  
> > callback({ id: producer.id });  
> > });  
> > } catch (err) {  
> > errback(err);  
> > }  
> > });

This is wrong. You shouldn’t call transport.produce() method inside ‘produce’ event, it should be reverse i.e you should call transport.produce() outside somewhere after creating transport and registering for event, produce() method will automatically call ‘produce’, ‘connect’ events. And on these events you will signal data to your server

---

<div class="post-metadata">

**Author:** ![snnz](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/snnz/32/693_2.png) [@snnz](https://mediasoup.discourse.group/u/snnz)\
**Post date:** [February 26, 2023, 2:18pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/11 "2023-02-26T14:18:54Z")

</div>

Read the [documentation](https://mediasoup.org/documentation/v3/communication-between-client-and-server/#producing-media), it describes what and when has to be done pretty well.

---

<div class="post-metadata">

**Author:** ![indie](https://avatars.discourse-cdn.com/v4/letter/i/b5e925/32.png) [@indie](https://mediasoup.discourse.group/u/indie)\
**Post date:** [February 26, 2023, 2:23pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/12 "2023-02-26T14:23:43Z")

</div>

but the problem is i have an error on this.sendTransport.on, on method doesn’t exist

---

<div class="post-metadata">

**Author:** ![zaidiqbal](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/zaidiqbal/32/1498_2.png) [@zaidiqbal](https://mediasoup.discourse.group/u/zaidiqbal)\
**Post date:** [February 26, 2023, 2:26pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/13 "2023-02-26T14:26:51Z")

</div>

> [@indie](#):
>
> > this.sendTransport = device.createSendTransport(responseStreamCreated.transport.transportOptions);

Then the problem is you are not creating transport correctly. To create transport on client side, which you are creating, you must create transport on server before that. And from the server’s response you should create the transport on client side and then listen to events.

Try logging this.sendTransport and see what it contains.

---

<div class="post-metadata">

**Author:** ![indie](https://avatars.discourse-cdn.com/v4/letter/i/b5e925/32.png) [@indie](https://mediasoup.discourse.group/u/indie)\
**Post date:** [February 26, 2023, 2:36pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/14 "2023-02-26T14:36:05Z")

</div>

yes i created a transport in back end, then get the transport information using websocket, from the response i built the transport like that:

> this.sendTransport = device.createSendTransport(responseStreamCreated.transport.transportOptions);

Here is the console.log response:

```auto
 1. Transport {_events: {…}, _eventsCount: 0, _maxListeners: Infinity, _closed: false, _connectionState: 'new', …}

  1. _appData: {}
  2. _awaitQueue: AwaitQueue {pendingTasks: Map(0), nextTaskId: 0, stopping: false}
  3. _canProduceByKind: {audio: true, video: true}
  4. _closed: false
  5. _connectionState: "new"
  6. _consumerCloseInProgress: false
  7. _consumerCreationInProgress: false
  8. _consumerPauseInProgress: false
  9. _consumerResumeInProgress: false
  10. _consumers: Map(0) {size: 0}
  11. _dataConsumers: Map(0) {size: 0}
  12. _dataProducers: Map(0) {size: 0}
  13. _direction: "send"
  14. _events: {connect: ƒ, produce: ƒ}
  15. _eventsCount: 2
  16. _extendedRtpCapabilities: {codecs: Array(2), headerExtensions: Array(11)}
  17. _handler: Chrome74 {_events: {…}, _eventsCount: 2, _maxListeners: Infinity, _mapMidTransceiver: Map(0), _sendStream: MediaStream, …}
  18. _id: "049f3994-14ea-411b-8f5b-3833839d44c0"
  19. _maxListeners: Infinity
  20. _maxSctpMessageSize: null
  21. _observer: EnhancedEventEmitter {_events: {…}, _eventsCount: 0, _maxListeners: Infinity}
  22. _pendingCloseConsumers: Map(0) {size: 0}
  23. _pendingConsumerTasks: []
  24. _pendingPauseConsumers: Map(0) {size: 0}
  25. _pendingResumeConsumers: Map(0) {size: 0}
  26. _probatorConsumerCreated: false
  27. _producers: Map(0) {size: 0}
  28. appData: (...)
  29. closed: (...)
  30. connectionState: (...)
  31. direction: (...)
  32. handler: (...)
  33. id: (...)
  34. observer: (...)
  35. [[Prototype]]: EnhancedEventEmitter

```

---

<div class="post-metadata">

**Author:** ![indie](https://avatars.discourse-cdn.com/v4/letter/i/b5e925/32.png) [@indie](https://mediasoup.discourse.group/u/indie)\
**Post date:** [February 26, 2023, 2:37pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/15 "2023-02-26T14:37:00Z")

</div>

I have connect and produce event on my object, but it’s maybe not by using .on that it will work ?

---

<div class="post-metadata">

**Author:** ![snnz](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/snnz/32/693_2.png) [@snnz](https://mediasoup.discourse.group/u/snnz)\
**Post date:** [February 26, 2023, 2:41pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/16 "2023-02-26T14:41:07Z")

</div>

Why do you think that `on` method does not exist? It is in the `EnhancedEventEmitter` prototype.

---

<div class="post-metadata">

**Author:** ![indie](https://avatars.discourse-cdn.com/v4/letter/i/b5e925/32.png) [@indie](https://mediasoup.discourse.group/u/indie)\
**Post date:** [February 26, 2023, 2:54pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/17 "2023-02-26T14:54:46Z")

</div>

i just don’t understand why i have an error that sendTransport is undefined then if it exist.  
I have this exact error:

```auto
core.mjs:6412 ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'on')
TypeError: Cannot read properties of undefined (reading 'on')

```

---

<div class="post-metadata">

**Author:** ![indie](https://avatars.discourse-cdn.com/v4/letter/i/b5e925/32.png) [@indie](https://mediasoup.discourse.group/u/indie)\
**Post date:** [February 26, 2023, 2:57pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/18 "2023-02-26T14:57:57Z")

</div>

this is the transportOptions i am passing to this.sendTransport = device.createSendTransport(responseStreamCreated.transport.transportOptions);:

```auto
{id: '48aded87-b36f-42f3-b050-b6cf74aa3264', iceParameters: {…}, iceCandidates: Array(1), dtlsParameters: {…}}
dtlsParameters
: 
{fingerprints: Array(5), role: 'auto'}
iceCandidates
: 
[{…}]
iceParameters
: 
{iceLite: true, password: 'qrohkckjxofhawa0fwlm15h8edwenpbt', usernameFragment: 'oxi7u6mpzmtfoqcexe70znbqwvyclfdf'}
id
: 
"48aded87-b36f-42f3-b050-b6cf74aa3264"
[[Prototype]]
: 
Object

```

---

<div class="post-metadata">

**Author:** ![snnz](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/snnz/32/693_2.png) [@snnz](https://mediasoup.discourse.group/u/snnz)\
**Post date:** [February 26, 2023, 3:10pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/19 "2023-02-26T15:10:31Z")

</div>

You definitely call the `on` method not on what `createSendTransport` returned (and which is logged in the console.log). It is some uninitialized variable: “TypeError: Cannot read properties of _undefined_”.

---

<div class="post-metadata">

**Author:** ![zaidiqbal](https://yyz2.discourse-cdn.com/free1/user_avatar/mediasoup.discourse.group/zaidiqbal/32/1498_2.png) [@zaidiqbal](https://mediasoup.discourse.group/u/zaidiqbal)\
**Post date:** [February 26, 2023, 3:28pm UTC](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967/20 "2023-02-26T15:28:01Z")

</div>

> [@indie](#):
>
> ```auto
> core.mjs:6412 ERROR Error: Uncaught (in promise): TypeError: Cannot read properties of undefined (reading 'on')
> TypeError: Cannot read properties of undefined (reading 'on')
> 
> ```

This error may be coming from somewhere else, make sure where it is coming from, show the exact line from developer tools where this error is occurring.

Also console.log(this.sendTransport); console.log(this.sendTransport.on); together after transport is created and show the result.

[Next page](https://mediasoup.discourse.group/t/how-to-add-media-stream-to-a-producer/4967.md?page=2)
