WebRTC WebSocket Messaging Reference
This documentation is for developers who need to implement signaling between Ant Media Server and clients for publishing & playing streams.
Let's understand it step by step:
Publish WebRTC Stream
-
To connect to the Ant Media Server, client can use WebSocket with a URL in the format:
wss://SERVER_NAME:5443/live/websocket
-
wssindicates that it's a secure WebSocket connection using SSL/TLS. -
/live/websocketspecifies the endpoint for the WebSocket connection in Ant Media Server.
-
To publish a stream, clients first send the
publishcommand to the server to start the stream.{
command : "publish",
streamId : "stream1",
streamName : "streamName",
token : "token",
mainTrack : "mainTrack",
metaData : "metaData",
subscriberCode : "subscriberCode",
subscriberId : "subscriberId",
enablevideo : "true",
enableaudio : "true",
}
-
token: Thetokenfield is required if any stream security (token control) is enabled.If the user has enabled stream-security, they need to fill in the
tokenfield with the correct token. -
subscriberIdandsubscriberCode: These are the values for the Time-based One-time Password (TOTP). If the user is using the TOTP mechanism, they need to pass thesubscriberIdandsubscriberCode. -
streamName: Zombie streams are streams that don’t have entries in the AMS database. Therefore, users can give these "on the fly" streams astreamName. -
mainTrack:mainTrackis related to multitrack streaming and is required if the user wants to start the stream as asubtrackfor thismainTrack. For multitrack conferences,mainTrackis set as the room ID. -
metaData: ThemetaDatais free text information for the stream to server. -
enableVideoandenableAudio: These parameters define whether to enable video and audio for the stream.
If enableVideo is true, then the video will be sent to the server. If enableAudio is true, then audio will be sent to the server.
If enableVideo is false and enbleAudio is true, then it means it's an audio-only stream.
- Only
commandandstreamIdare mandatory. Audio and video are enabled by default. When the server receives thepublishcommands, it checks whether the license is active vs suspended and whether the server has enough resources, and retrieves the token if necessary.
- If the Server accepts the stream, it replies with the
startcommand
{
command : "start",
streamId : "stream1",
subscriberId : "",
}
- The client initiates peer connections, creates offer SDP, and sends the SDP configuration to the server with
takeConfigurationcommand
{
command : "takeConfiguration",
streamId : "stream1",
type : "offer",
sdp : "${SDP_PARAMETER}"
}
- The server creates answers SDP and sends the SDP configuration to the client with
takeConfigurationcommand
{
command : "takeConfiguration",
streamId : "stream1",
type : "answer",
sdp : "${SDP_PARAMETER}"
}
- Client and Server get ice candidates several times and send them to each other with
takeCandidatecommand
{
command : "takeCandidate",
streamId : "stream1",
label : "${CANDIDATE.SDP_MLINE_INDEX}",
id : "${CANDIDATE.SDP_MID}",
candidate : "${CANDIDATE.CANDIDATE}"
}
- After a stream has started, the server sends a
publish_startedcommand
{
command : "notification",
definition : "publish_started",
streamId : "stream1",
}
- Clients send stop JSON command to stop publishing
{
command : "stop",
streamId: "stream1",
}
- The server responds with a publish_finished message to indicate that the stream has stopped
{
command : "notification",
definition : "publish_finished",
streamId : "stream1",
subscriberId : "subscriberId",
}
Play WebRTC Stream
-
To connect to the Ant Media Server, client can use WebSocket with a URL in the format:
wss://SERVER_NAME:5443/live/websocket
-
wssindicates that it's a secure WebSocket connection using SSL/TLS. -
/live/websocketspecifies the endpoint for the WebSocket connection in Ant Media Server.
- Client sends play
commandto the server withstreamIdparameter.
{
command : "play",
streamId : "stream1",
token : "token",
subscriberCode : "subscriberCode",
subscriberId : "subscriberId",
trackList : [enabledtracksarray],
viewerInfo : "viwerInfo",
}
-
Only
commandandstreamIdis mandatory, rest are situational, such assubscriberId,subscriberCode,tokenandenabled tracks. -
If a stream has sub-tracks,
trackListis enabled by default. If there are 2 tracks on the stream, the user can specify both and both tracks will be played. To get all tracks in a stream you can take a look ingetTrackListcommand that is in the miscellaneous part. -
viewerInfois a kind ofmetaDataused to collect informations.
- If the Server accepts the stream, it replies with the offer command.
{
command : "takeConfiguration",
streamId : "stream1",
type : "offer",
sdp : "${SDP_PARAMETER}"
}
- The client creates an answer SDP and sends the SDP configuration to the server with
takeConfigurationcommand.
{
command : "takeConfiguration",
streamId : "stream1",
type : "answer",
sdp : "${SDP_PARAMETER}"
}
- Client and Server get ice candidates several times and send them to each other with
takeCandidatecommand.
{
command : "takeCandidate",
streamId : "stream1",
label : "${CANDIDATE.SDP_MLINE_INDEX}",
id : "${CANDIDATE.SDP_MID}",
candidate : "${CANDIDATE.CANDIDATE}"
}
- Server notifies with
play_startedonce the stream starts to play.
{
command : "notification",
definition : "play_started",
streamId : "stream1",
subscriberId : "subscriberId",
}
- Client sends toggle video to stop/start incoming video packets from a video track ( streamId = trackId for single track use ) Enabled is
trueas default.trackIdandstreamIdis mandatory.
{
command : "toggleVideo",
streamId: "stream1",
trackId: "track1",
enabled: boolean
}
- Client sends toggle audio to stop/start incoming audio packets from an audio track ( streamId = trackId for single track use ) Enabled is
trueas default.trackIdandstreamIdis mandatory.
{
command : "toggleAudio",
streamId: "stream1",
trackId: "track1",
enabled: boolean
}
- If there are multiple sub-tracks, the user can enable/disable any track using
toggleso that the server does not send audio/video packets for that track.
- Clients sends
stopJSON command to stop playing.
{
command : "stop",
streamId: "stream1",
}
- Server notifies with
play_finishedto notify that play has stopped.
{
command : "notification",
definition : "play_finished",
streamId : "stream1",
subscriberId : "subscriberId",
}
Conference WebRTC Stream
Think of Conference room as this way , we will publish our video streams and we will play the videos of the remote participants, so essentially we will be using same publish and play functions , we normally use for publishing and plying streams.
-
Participants connect to the Ant Media Server through WebSocket.
wss://SERVER_NAME:5443/live/websocket -
The client publishes his stream with the
publishcommand as we discussed in the publishing section above and these will be the same. mainTrack is the room name that client is publishing his stream to.
{
command : "publish",
streamId : "streamId",
streamName : "streamName",
mainTrack : "room1",
metaData : "metaData",
subscriberCode : "subscriberCode",
subscriberId : "subscriberId",
video : "true",
audio : "true",
}
- The client sends the
playcommand to the server withstreamIdas theroomId
{
command : "play",
room : "room1",
streamId : "room1",
token : "token",
subscriberCode : "subscriberCode",
subscriberId : "subscriberId",
trackList : [enabledtracksarray],
viewerInfo : "viwerInfo",
}
-
We only play the
roomIdas thismainTrackhas all thesubTracksin the room and therefore it is not required to play eachstreamIdseparately. -
all the remote video tracks will be received in "newTrackAvailable" callback in WebRTCAdapter callback.Once the tracks are received they can then be played by application logic.
- When a client wants to leave the room they send the
stopcommand to the server for both publish and play.
stop publish our stream
{
command : "stop",
streamId : "stream1",
}
stop playing from room.
{
command : "stop",
streamId : "room1",
}
- The server responds with a
play_finishedorpublish_finishedmessage.
{
command : "notification",
definition : "publish_finished",
}
{
command : "notification",
definition : "play_finished",
}
-
The JavaScript SDK/SDKs handle the background processing of multitrack streaming for conferences on their own. If you are implementing your code using WebSocket references, you will likely need to listen for
onTrackEventswithin theinitPeerConnectionsfunction. When a new track, stream, or subTrack is dynamically added to the room during runtime, theonTrack(event, streamId)function is triggered. This function notifies the application that a new track is available, allowing the application to handle and play the newly added track as needed. -
When a new
streamIdis added to or removed from the room, the server and client initiate a renegotiation process. During this process, the server sends a new Session Description Protocol (SDP) to the client, suggesting a change in the configuration. This change prompts the addition or removal of a new track to or from the room in real time.
Peer-to-Peer WebRTC Stream
-
Peers connect to the Ant Media Server through WebSocket.
wss://SERVER_NAME:5443/live/websocket -
The client sends a join JSON command to the server with the
streamIdparameter. If only want toplay,modecan be set toplay, if the user wants to publish and play at the same time,bothcan be set. As default,modeis set toboth. OnlycommandandstreamIdare mandatory.
{
command : "join",
streamId : "stream1",
mode: "play or both"
}
- Server notifies with
joined.
{
command : "notification",
definition : "joined"
streamId : "stream1",
}
-
If there is only one peer in stream1, the server waits for the other peer to join the room.
-
When the second peer joins the stream, the server sends the
startJSON command to the first peer.
{
command : "start",
streamId : "stream1",
}
- First peer creates an offer SDP and sends it to the server with the
takeConfigurationcommand.
{
command : "takeConfiguration",
streamId : "stream1",
type : "offer",
sdp : "${SDP_PARAMETER}"
}
- Server relays the offer SDP to the second peer
- The second peer creates the answer SDP and sends it to the server with the
takeConfigurationcommand.
{
command : "takeConfiguration",
streamId : "stream1",
type : "answer",
sdp : "${SDP_PARAMETER}"
}
- Server relays the answer SDP to the first peer
- Each peer gets ice candidates several times and sends them to each other with the
takeCandidatecommand through the server.
{
command : "takeCandidate",
streamId : "stream1",
label : "${CANDIDATE.SDP_MLINE_INDEX}",
id : "${CANDIDATE.SDP_MID}",
candidate : "${CANDIDATE.CANDIDATE}"
}
- Clients send leave JSON command to leave the room.
{
command : "leave",
streamId: "stream1"
}
- Server notifies with
leaved
{
command : "notification",
definition : "leaved",
}
- When the second peer stops the stream or the stream is ended, the server sends a
stopJSON command to the first peer.
{
command : "stop",
streamId : "stream1",
}
WebSocket Error Callbacks
-
noStreamNameSpecified: it is sent when the stream id is not specified in the message.{
command : "error",
definition : "noStreamNameSpecified",
} -
not_allowed_unregistered_streams: Thenot_allowed_unregistered_streamserror message is returned to the user when they try to send a stream with an unregisteredstreamId, and the server is configured not to accept undefined streams.For conference, if it is not set then the room is created automatically and is removed once it finishes.
{
command : "error",
definition : "not_allowed_unregistered_streams",
streamId : "stream1",
} -
no_room_specified: This is sent back to the user when there is no room specified in joining the video conference.{
command : "error",
definition : "no_room_specified",
} -
unauthorized_access: When stream security is enabled but the token is either incorrect or not validated, or the subscriberId and/or subscriberCode are incorrect.{
command : "error",
definition : "unauthorized_access",
streamId: "stream1",
} -
no_encoder_settings: This is sent back to the user when there are no encoder settings available in publishing the stream.{
command : "error",
definition : "no_encoder_settings",
} -
no_peer_associated_before: This is peer to peer connection error definition. It is sent back to the user when there is no peer associated with the stream.{
command : "error",
definition : "no_peer_associated_before",
} -
notSetRemoteDescription: This is sent if there is a mismatch between the encoder and the decoders between the Ant Media Server and the client.{
command : "error",
definition : "notSetRemoteDescriptio",
} -
notSetLocalDescription: It is sent when the local description is not set successfully.{
command : "error",
definition : "notSetLocalDescription",
} -
highResourceUsage: It is sent when the server is overloaded. Server overload means over CPU usage or RAM usage.Over CPU usage means CPU load is more than the
server.cpu_limitvalue inconf/red5.properties. Its default value is %75. Over RAM usage means available memory in the system is less thanserver.min_free_ramvalue in conf/red5.properties. Its unit is MB and the default value is 10.{
command : "error",
definition : "highResourceUsage",
} -
streamIdInUse: This error message is returned by the server when a user tries to publish a stream with astreamIdthat is already in use by an active stream in either the preparing or publishing state. This error can occur if a user attempts to re-publish a stream with the samestreamIdwithout first closing the previous WebRTC connection.{
command : "error",
definition : "streamIdInUse",
streamId : "stream1",
} -
publishTimeoutError: The server sends thepublishTimeoutErrormessage when WebRTC publishing fails to start within a specified time period.This may occur due to network issues, such as the lack of an established ICE connection or the failure to send video and audio streams to the server. The timeout value can be customized using the
settings.webrtc.client.start.timeoutMsproperty in the App-Configuration, with a default value of 5000 milliseconds.Using a TURN-server helps mitigate these network-related issues.
{
command : "error",
definition : "publishTimeoutError",
streamId : "stream1",
} -
invalidStreamName: it is sent when the stream name contains special characters.{
command : "error",
definition : "invalidStreamName",
} -
data_store_not_available: It's sent when the data store is not available. It's not available if it's not initialized or closed.{
command : "error",
definition : "data_store_not_available"
} -
license_suspended_please_renew_license: It's sent when the license is suspended.{
command : "error",
definition : "license_suspended_please_renew_license"
} -
already_playing: This is sent back to the user when a new play message is received while it is playing or it is about to play.{
command : "error",
definition : "already_playing",
streamId: "stream1"
} -
already_publishing: This message is sent when a new publish message is received while the server is either publishing or about to publish. The message indicates that publishing is already in progress.{
command : "error",
definition : "already_publishing",
streamId: "stream1",
} -
encoderNotOpened: If the encoder fails to open, the server sends this error message to the client indicating that the encoder could not be opened.{
command : "error",
definition : "encoderNotOpened",
streamId : "stream1",
} -
encoderBlocked: The server sends this error message if the encoder is blocked for some reason or not performing efficiently.{
command : "error",
definition : "encoderBlocked",
streamId : "stream1",
} -
no_codec_enabled_in_the_server: This is sent back to the user when there is no codec enabled in the server and someone try to make a publish{
command : "error",
definition : "no_codec_enabled_in_the_server",
streamId: "stream1"
}
-
stream_not_active_or_expired: The messagestream_not_active_or_expiredis returned to the user when theplannedStartDateandplannedEndDateof a stream are either not in the specified interval or have expired.{
command : "error",
definition : "stream_not_active_or_expired",
streamId : "stream1",
}
-
viewerLimitReached: This is sent when the viewer limit is reached. When a user is trying to watch a broadcast that already hit the limit, this error is sent to the client.{
command : "error",
definition : "viewerLimitReached",
} -
no_room_specified: if roomId is not specified for a conference, the server returns with ano_room_speficifiederror message.{
command : "error",
definition : "no_room_specified",
}
Miscellaneous WebSocket Methods
-
ping&pong: Some load balancers may start to close connections after a certain amount of time to prevent idle connections from consuming resources.To prevent this from happening, the client sends
pingmessages to the server, and the server returns with apongresponse. This keeps the connection active and prevents it from being closed by the load balancer.{
command : "ping",
}Pong Response from Server
{
command : "pong",
} -
getStreamInfo: Get Stream Information from Server. You may use this method to learn more about stream status and bitrates. The client should send the following message.{
command: "getStreamInfo",
streamId: "stream_id_that_you_want_to_get_info",
}Server returns in two ways. It may return stream information as follows:
{
command: "streamInformation",
streamId: "stream_id_of_the_stream_information",
streamInfo: [{
streamWidth: "resolution_width",
streamHeight: "resolution_height",
videoBitrate: "video_bitrate",
audioBitrate: "audio_bitrate",
videoCodec: "codec_of_the_video",
},
...
]
}If the stream is not active, it will return
no_stream_exist.{
command : "error",
definition : "no_stream_exist",
streamId: "id_of_the_stream",
} -
getRoomInfo: The functiongetRoomInfois called when a new participant or track is added to the room to retrieve information about the current state of the room, including the active streams. The client should send the following message to get the response from the server.{
command: "getRoomInfo",
room: "room_id_that_you_want_to_get_info",
streamId: "server_returns_while_you_join_the_room",
}The server responds in the following format with the list of streams available in the room.
{
command: "roomInformation",
room: "room_id_that_this_information_belongs_to",
streams: [ stream_id_1, stream_id_2, ...]
} -
bitrateMeasurement: Server periodically sends this information to the WebRTC viewers. It lets show a message to the user if it's internet bandwidth is not good enough.If the
targetBitrateis bigger than the sum ofvideoBitrateandaudioBitrate, it means the internet bandwidth is good enough to play the video. If thetargetBitrateis less than the sum ofvideoBitrateandaudioBitrate, it means some playback issues(pixelating, packet drop, etc.) may happen and disturb the user experience.{
command : "notification",
definition : "bitrateMeasurement",
streamId: "unique_stream_id_returned_by_the_server"
targetBitrate: "measured_bandwidth_of_the_client",
videoBitrate: "video_bitrate_of_the_current_playing_video",
audioBitrate: "audio_bitrate_of_the_current_playing_audio",
} -
forceStreamQuality: If there are adaptive-bitrates(multi-bitrate) for that stream, you can get bitrates with thegetStreamInfomethod and then you can make the Ant Media Server force to send you a specific resolution. If you want to switch back to auto stream quality, you can give0forstreamHeightand send the message below.{
command: "forceStreamQuality",
streamId: "write_the_stream_id",
streamHeight: "write_the_height_of_the_resolution_you_want_to_force",
} -
server_will_stop: When the server is about to stop and it receives a command from a service or the command line to initiate the shutdown process, it notifies the user withserver_will_stop.{
command : "notification",
definition : "server_will_stop",
} -
leavedFromRoom: It's sent after the stop command is received or if the client sends theleaveFromRoomcommand.{
command : "notification",
definition : "leavedFromRoom",
ATTR_ROOM_NAME: "roomName",
} -
getTrackList: Sends a request to the server to get a tracklist in a specified stream. The token is not mandatory. If the stream has a token, the token needs to be used, otherwise not needed.{
command : "getTrackList",
streamId: "stream1",
token: "token",
} -
trackList: The server returns the tracklist of the specified stream after receiving thegetTrackListcommand.{
command : "trackList",
streamId: "stream1",
trackList: "tracks",
} -
enableTrack: Player can enable or disable the tracks in the broadcast.{
command : "enableTrack",
streamId: "stream1",
trackId: "id of track",
enabled: "boolean",
} -
streaming_Session_Restored: when a WebRTC publish stream is interrupted due to network issues but is restored within the timeout duration, the server sends this message to indicate that the streaming session has been restored.The viewer's connection remains active and is not dropped during the timeout duration. The timeout duration,
webRTCClientStartTimeoutis configurable and has a default value of 10 seconds.{
command : "notification",
description: "streaming_session_Restored",
}
WSS-Messaging Ready 🔔
You’ve now explored how WebSocket signaling works in AMS: connected via wss://…/live/websocket, sent the **publish** command, included metadata, managed TOTP or token fields if required, and understood the optional vs mandatory fields.
Your signaling layer is fully setup — smooth, secure, and ready to handle stream control messages and status notifications. Your WebRTC stack is talking properly now! 📡