Urgent.News

What's breaking now, across thousands of outlets.

Tech

Audio works, video is black: debugging a layered WebRTC SFU in Go

Audio connects instantly, the viewer hears everything, and the video tile stays black. The publisher side looks fine. ReplaceTrack returns nil , which the code logs as success. That nil is where most of these debugging sessions go wrong. ReplaceTrack returning nil means one thing: the track was bound to a sender that already existed. It does not mean the negotiated SDP allows that m-line to send,…

The audio connection establishes quickly, but the video tile remains black. The publisher appears to function normally. In debugging these issues, the ReplaceTrack returning nil error proves to be a common point of failure. This specific error indicates that the track was already bound to a sender. It does not signify that the SDP negotiation permits the transmission of that media line, nor does it ensure that both parties agreed upon a codec, nor does it imply that a single video RTP packet reached the downstream leg.

These are three distinct failures that produce the same visual outcome. In order to distinguish these issues, follow them systematically, starting with the least resource-intensive checks first. The key point to remember is that audio and video travel along the same connection but not necessarily the same negotiated path. Thus, a functional audio leg does not guarantee the visual success of the video leg.

To begin, examine the negotiated direction, not merely the code Direction in the SDP. The negotiated direction is the final outcome reached by both sides and dictates the RTP path. The sending leg's video m-section must be set to sendonly or sendrecv, while the receiving leg must be configured as recvonly or sendrecv. ReplaceTrack does not renegotiate direction; it simply adds a track to an existing sender, which can result in a nil return value.

When adding a track to a sender that the remote endpoint has accepted as inactive, a nil return value is a normal outcome. Ensure that the video m-line includes a usable a=ssrc from the sender and that the remote direction is set to recvonly or sendrecv. If the video m-line lacks a functional a=ssrc or the remote direction is inactive, there is a negotiation fault, and no buffering or asynchronous handling can resolve it.

Furthermore, both sides must agree on the codec. Although forwarding H.264 between two legs that negotiated different profiles or transmitting VP8 packets into a sender that negotiated H.264 may produce an active track object, the codec compatibility is not guaranteed. The mime type may appear similar, but codec compatibility cannot be assumed solely based on the mime type.

The RTP packets must be consistent with the negotiated codec on both ends. Before proceeding to the forwarding loop, verify that RTP packets reached the sender. Log the packets that never arrived versus those that arrived but were not utilized. After negotiation, before initiating the forwarding loop, iterate through the videoRTPTransceiver's Sender to retrieve the parameters.

Log the SSRC and payload type of each encoding. In the main forwarding loop, attempt to write the local track's RTP packet. If an error occurs, log the error. On the receiving side, after the OnTrack callback, examine pc.GetStats() to determine if the inbound RTP stream has received any packets. If the downstream leg does not receive the initial video packet, the issue lies in negotiation or sending.

If RTP packets reach the downstream leg, but the decoder fails to produce frames, the problem lies in codec compatibility or keyframes. These are two separate issues that require distinct solutions. In the forwarding loop, ensure that the code handles errors properly. A single failed binding should not be mistaken for a successful fan-out, and an error in the read operation should not silently terminate the goroutine.

The symptom of a dead forwarding goroutine is precisely the same as audio working while video disappears on the affected leg. Lastly, be aware of the potential for a black video tile due to a keyframe problem. Even if packets are continuously arriving, the viewer may remain black if the first decodable frame has not been received.

To address this, send a PLI on the inbound video receiver and monitor the framesReceived and framesDecoded statistics. If framesReceived increases but framesDecoded remains flat, the issue lies in codec parameters or the absence of a keyframe. Separate this check from the previous one to accurately diagnose the problem. A more effective approach to avoid the complexities of renegotiation is to create the video transceiver with a placeholder TrackLocalStaticRTP before the initial offer/answer exchange.

Negotiate the transceiver as sendrecv, and only afterward, replace it with the real upstream track once the initial negotiation is stable. This method eliminates the risk of encountering the "sender exists but direction does not allow media" failure. By creating a separate binding for each downstream leg and meticulously checking each write operation, you can prevent the misinterpretation of a failed binding as a successful fan-out.

Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.

Read the original at dev.to →

More in Tech

Passkeys Explained Without the Jargon

You’ve probably seen a website ask, “Would you like to create a passkey?” It sounds like another password to manage. It actually works quite differently. What happens when you create one?

  • Passkeys use cryptographic keys, not passwords, for authentication.
  • Passkeys are tied to specific services, preventing phishing.
  • Loss of phone affects passkey recovery depending on storage method.

OrderSift turns messy customer messages into orders you can actually act on.

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle What I Built OrderSift turns messy customer messages into orders you can actually act on.

  • AI-powered tool transforms customer messages into structured orders
  • Extracts key information like quantities, customizations, and pickup dates
  • Helps small food and craft businesses save time and reduce errors

More from Tuesday 13 October →