Has anyone found a way to communicate with the stream broadcaster using data channels?
When I create a new data channel and send messages to the broadcaster it gets to the FEpicRtcStreamer , but then errors out because it cannot find a player that is waiting for the message.
That is pretty much what I expected, but I cannot find any way of creating a data channel so a player can receive the messages
You’ve only set up a one-way data channel. When you create a data channel and send messages to the broadcaster, it reaches the FEpicRtcStreamer but fails because there’s no corresponding data channel established on the player side to receive responses.
You need to establish data channels on BOTH sides of the connection:
On the broadcaster side (Epic RTC Streamer), create an outbound data channel when a player connects using createDataChannel(), listen for incoming data channels from players using the datachannel event listener on your RTCPeerConnection, and wait for both channels to be in “open” state before attempting to send messages.
On the player side (web browser), create your own data channel to send messages to the broadcaster, listen for the broadcaster’s data channel using the datachannel event, and handle both incoming and outgoing message flows.
To fix this: modify your broadcaster to create data channels for each connecting player during WebRTC negotiation, update your players to create their own data channels to the broadcaster (not just send on an existing one), and make sure both sides wait for channel state to be “open” before attempting communication.
The remote peer can receive data channels by listening for the datachannel event on the RTCPeerConnection object.
The error happens because WebRTC data channels require reciprocal establishment - both peers need to participate in the channel setup process.
If you want a simpler no-code pixel streaming solution, check out Vagon Streams - it offers the lowest latency pixel streaming with worldwide coverage thanks to 20+ datacenters globally, eliminating the need for complex WebRTC data channel setup.
You’ve only set up a one-way data channel. When you create a data channel and send messages to the broadcaster, it reaches the FEpicRtcStreamer but fails because there’s no corresponding data channel established on the player side to receive responses.
You need to establish data channels on BOTH sides of the connection:
On the broadcaster side (Epic RTC Streamer), create an outbound data channel when a player connects using createDataChannel(), listen for incoming data channels from players using the datachannel event listener on your RTCPeerConnection, and wait for both channels to be in “open” state before attempting to send messages.
On the player side (web browser), create your own data channel to send messages to the broadcaster, listen for the broadcaster’s data channel using the datachannel event, and handle both incoming and outgoing message flows.
To fix this: modify your broadcaster to create data channels for each connecting player during WebRTC negotiation, update your players to create their own data channels to the broadcaster (not just send on an existing one), and make sure both sides wait for channel state to be “open” before attempting communication.
The remote peer can receive data channels by listening for the datachannel event on the RTCPeerConnection object.
The error happens because WebRTC data channels require reciprocal establishment - both peers need to participate in the channel setup process.
If you want a simpler no-code pixel streaming solution, check out Vagon Streams - it offers the lowest latency pixel streaming with worldwide coverage thanks to 20+ datacenters globally, eliminating the need for complex WebRTC data channel setup.
Yes I am aware that I need to create the data channel at both ends, however this is not trivial as most of pixel streaming is hidden from top level code.
I don’t even know of a clean way of getting the peer connection so creating a data channel is not easy.
I will dig more into the input handler as that uses data channels
It seems @Serd is confused by your question as the response isn’t quite accurate.
The FEpicRtcStreamer is UE side code that doesn’t expose a createDataChannel method. Instead, the FEpicRtcStreamer should automatically create a data channel for you.
In your question, you state “When I create a new data channel". How are you doing this?
As far as I understand, you need to create a whole new “player” by sending the subscribe message as part of the signalling protocol. Failing to do so will mean the streamer has no idea of an associating player for your data channel and will result in the error your seeing.
On the client end I do have access to the peer connection, so I create a data channel as normal.
When I send a message to this data channel I get the “cannot find player” error.
I have sent a subscribe message , and everything else works. I get video and sound and I can even interact by using a back channel UDP messaging system, but this system is prone to lag and not really fit for purpose.
Which is why I am trying to get a data channel working.
If I create my own data channel , the client reports that the data channel is not open.
So I dug around a little more.
I found that there is a data channel open used by the SendPixelStreamingResponse node. This channel is rather unhelpfully named “0”
I can send messages to that without the client reporting an error , but the broadcaster still errors out.
Looking through the docs I see there is no matching ReceivePIxelStreamingResponse node so now I have to think again.
My point of attack this morning is the OnDataTrackOpen event
I have added an input component to my player controller and put some logging into it
[2025.09.08-08.40.27:852][700]LogPixelStreaming2RTC: FEpicRtcStreamer::OnDataTrackState(DataTrack=[Player0], Player=[Player0], State=[Active])
[2025.09.08-08.40.27:853][700]LogBlueprintUserMessages: [KFCPlayerController_C_2147482393] DefaultStreamer
[2025.09.08-08.40.27:853][700]LogPixelStreaming2RTC: FEpicRtcStreamer::OnDataTrackUpdate(Participant [Player0], DataTrack [input])
[2025.09.08-08.40.27:853][700]LogPixelStreaming2RTC: FEpicRtcStreamer::OnDataTrackUpdate(Participant [Player0], DataTrack [0])
[2025.09.08-08.40.27:853][700]LogPixelStreaming2RTC: Warning: FEpicRtcStreamer::OnDataTrackState(Failed to find a player for data track [input])
[2025.09.08-08.40.27:853][700]LogPixelStreaming2RTC: Warning: FEpicRtcStreamer::OnDataTrackState(Failed to find a player for data track [0])
[2025.09.08-08.40.27:863][701]LogPixelStreaming2RTC: FEpicRtcStreamer::OnDataTrackMessage(Failed to find a player for data track [input])
You can see the system is trying to connect up two data channels to the player, but failing
As far as I understand it, you don’t need to manually create a data channel on the client side. As the application will add one to the peer connection, all you need to do on the browser side is listen to the onDataChannel as they do in the PixelStreamingInfrastructure (here).
Receiving messages is done by binding to the OnInputEvent of the PixelStreaming2InputComponent.
To re-iterate, you shouldn’t need to be manually creating anything. The application already adds all of the tracks for you. You can listen to the appropriate listeners on the client side, or send messages from the broadcaster with the appropriate blueprint interface.
The one data track created by the code is used to send messages to the client , and the player context can only hold a single data track, so I am screwed.
Does anyone know what this function actually does ?
ParticipantConnection->AddDataSource(DataSource);
It is hidden away in a library so I cannot see it.
Webrtc allows you to use as many data tracks as you want, I need to modify the code to allow that but I cannot see how the above code can create a EpicRtcDataTrackInterface
Your correct in identifying where the PS2 streamer adds that data track. All this does is signal to EpicRtc that the connection should include a data track. Once the connection is established and tracks are properly created, the FEpicRtcStreamer::OnDataTrackUpdate callback will be executed which links the created data track to the participant.
You are also correct in stating that WebRTC allows for numerous data tracks, but it seems the PS2 only allows a single data track to be used between a streamer and participant. Are you able to re-use this existing track?