Produce multiple tracks by a single request

I’m trying to publish (produce) two media tracks in a single request. This is useful when you need to handle audio and video tracks of a stream in the consumer side at the same time. However this is hard with current API that uses callback for producing. Consider the following sample code:

const audioProducer = await transport.produce({ track: audioTrack });
const videoProducer = await transport.produce({ track: videoTrack });
transport.on('produce', (data, callback) => {
  // no way to handle producers at the same time
  const id = await sendRequestToServer(data);
  callback({ id });
});

But I wish I had some thing like this instead (Promise approach):

const audioProducerData = await transport.produce({ track: audioTrack });
const videoProducerData = await transport.produce({ track: videoTrack });
// single request for both producers
const { audioProducerId, videoProducerId } = await sendRequestToServer([audioProducerData, videoProducerData]);
audioProducerData.callback({ id: audioProducerId });
videoProducerData.callback({ id: videoProducerId });

Any thought?

What’s the problem? You can wait for both “produce” events and send a single request to the server. This is just cosmetic and we won’t change the API just for that.

How to wait for both when I get them separately inside the callback function? Are you talking about kind of queue?

How about a new API, transport.produceSync() for instance?

We won’t create a new API for this. It’s just cosmetic and you can get the desired behaviour in your app code. Anyway nothing wrong happens for sending two requests to your server instead of one. And still you can wait and collect both “produce” events and send a single request to your server with both (yes, it would require some JS magic).

There is no real issue here.

BTW you say “no way to handle both producers at the same time”. Of course there is a way to do that:

transport.on('produce', async (data, callback) => {
  const id = await sendRequestToServer(data);
  callback({ id });
});

const audioProducer = await transport.produce({ track: audioTrack });
const videoProducer = await transport.produce({ track: videoTrack });

// Here you have your both Producers ready.

Well, I should not do this but anyway:

let audioProducerData;
let audioProducerCallback;
let videoProducerData;
let videoProducerCallback;

transport.on('produce', async (data, callback) => {
	if (data.kind === 'audio') {
		audioProducerData = data;
		audioProducerCallback = callback;
	} else if (data.kind === 'video') {
		videoProducerData = data;
		videoProducerCallback = callback;
	}

	if (audioProducerData && videoProducerData) {
		// Send a single request to the server for both producers because
		// otherwise the humanity will die. 
		const { audioProducerId, videoProducerId } = await sendRequestToServer(
			{ 
				audioProducerData, 
				videoProducerData
			});

		audioProducerCallback({ id: audioProducerId });
		videoProducerCallback({ id: videoProducerId });
	}
});

const audioProducer = await transport.produce({ track: audioTrack });
const videoProducer = await transport.produce({ track: videoTrack });
2 Likes

I said I need to handle them together in the consumer side, so I have to produce them at the same time in the server, so have to send in one request or I have to handle the two requests in the server.

I personally prefer Promise over Callback as much as possible which leads to easier code structure and logic.

Never mind I’ll find a way for that, just a sympathy. Thank you.

Me too, and that’s what we try to achieve in mediasoup and mediasoup-client when possible.

1 Like