Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Playing audio through the AudioBridge plugin #51

Closed
Magmanat opened this issue Feb 24, 2025 · 5 comments
Closed

Playing audio through the AudioBridge plugin #51

Magmanat opened this issue Feb 24, 2025 · 5 comments
Labels
enhancement New feature or request

Comments

@Magmanat
Copy link

Magmanat commented Feb 24, 2025

From my firsthand experience with janode, I was able to join AudioBridge room and start an RTP stream using Gstreamer to multicast audio from a web-client using janus-gateway npm package for my application.

However now I am wondering how do I use janode to play audio in the AudioBridge room.

For example a, use case would be playing pre-recorded announcement which could be available as an audio file.

@atoppi
Copy link
Member

atoppi commented Feb 24, 2025

For that the play_file API is needed. Still not supported in the Janode plugin though.

Quoting the Janus API docs:

You can start the playback of an .opus file in an existing room using the play_file request, which has to be formatted as follows:

{
        "request" : "play_file",
        "room" : <unique numeric ID of the room to play the file in>,
        "secret" : "<room password, if configured>",
        "group" : "<group to play in (for forwarding purposes only; optional, mandatory if enabled in the room)>",
        "file_id": "<unique string ID of the announcement; random if not provided>",
        "filename": "<path to the Opus file to play>",
        "loop": <true|false, depending on whether or not the file should be played in a loop forever>
}

Notice that, as explained above, in case you configured an admin_key property and extended it to RTP forwarding as well, you'll need to provide it in the request as well or it will be rejected as unauthorized. By default play_file only requires the room secret, meaning only people authorized to edit the room can start an audio playback.

Also notice that the only supported files are .opus files: no other audio format will be accepted. Besides, the file must be reachable and available on the file system: network addresses (e.g., HTTP URL) are NOT supported.

@atoppi atoppi added the enhancement New feature or request label Feb 24, 2025
@Magmanat
Copy link
Author

Hi atoppi

Thanks for the detailed response! I have a better understanding of how it works now 👍

@Magmanat
Copy link
Author

Hi atoppi,

after reviewing the audiobridge plugin in a little more detail, I notice that there is functionality to join as an RTP participant.

Notice that, while the AudioBridge assumes participants will exchange media via WebRTC, there's a less known feature that allows you to use plain RTP to join an AudioBridge room instead. This functionality may be helpful in case you want, e.g., SIP based endpoints to join an AudioBridge room, by crafting SDPs for the SIP dialogs yourself using the info exchanged with the plugin. In order to do that, you keep on using the API to join as a participant as explained above, but instead of negotiating a PeerConnection as you usually would, you add an rtp object to the join request, which needs to be formatted as follows:

{
        "request" : "join",
        [..]
        "rtp" : {
                "ip" : "<IP address you want media to be sent to>",
                "port" : <port you want media to be sent to>,
                "payload_type" : <payload type to use for RTP packets (optional; only needed in case Opus is used, automatic for G.711)>,
                "audiolevel_ext" : <ID of the audiolevel RTP extension, if used (optional)>,
                "fec" : <true|false, whether FEC from Janus to the user should be enabled for the Opus stream (optional; only needed in case Opus is used)>
        }
}

In that case, the participant will be configured to use plain RTP to exchange media with the room, and the joined event will include an rtp object as well to complete the negotiation:

{
        "audiobridge" : "joined",
        [..]
        "rtp" : {
                "ip" : "<IP address the AudioBridge will expect media to be sent to>",
                "port" : <port the AudioBridge will expect media to be sent to>,
                "payload_type" : <payload type to use for RTP packets (optional; only needed in case Opus is used, automatic for G.711)>
        }
}

I was wondering if this could fit my usecase, and i was testing with the janus web demo from janus-gateway github

const joinResponse = await audiobridge.join({
			room: roomId,
			display: "GStreamer RTP Participant",
			rtp_participant: {
				ip: rtpIp, // my local ip
				port: rtpPort, //50000
				payload_type: 96,
				sampling_rate: 48000,
			},
		});
		console.log("Join response:", JSON.stringify(joinResponse, null, 2));

		// Ensure participant is unmuted and volume is set correctly
		const configureResponse = await audiobridge.configure({
			muted: false,
			volume: 100, // Set to 100% to ensure audio is not silent
		});
		console.log(
			"Configure response:",
			JSON.stringify(configureResponse, null, 2)
		);

		// Spawn the GStreamer process to generate and send the sine wave
		console.log("Starting GStreamer RTP stream...");
		const gstPipeline = `audiotestsrc wave=sine freq=440 ! audioconvert ! audioresample ! opusenc ! rtpopuspay pt=96 ! udpsink host=${rtpIp} port=${rtpPort} ttl-mc=1`;
		const gstProcess = spawn("gst-launch-1.0", gstPipeline.split(" "));

But for some reason I am unable to hear the audio from the frontend client

Image

Is this the correct usecase for the rtp participant? Or am i misunderstanding how it can be used

@Magmanat
Copy link
Author

alright, after reading this pull request

I realised that i had to leave out the ip and port fields

if ip/port are missing, it means this participant will only send media, and will not receive any (e.g., for injecting audio)

Because in my case it is for playing an external audio.

so this playing file capability can be done by using gstreamer to stream the audio over plain rtp

@atoppi
Copy link
Member

atoppi commented Feb 25, 2025

Yes that should fit your use case.
Closing the issue.

@atoppi atoppi closed this as completed Feb 25, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants