RTMP, SRT or WHIP: Choosing an Ingest Protocol
What dcast accepts, when each protocol is the right answer, the SRT streamid mistake that fails silently, what the SRT latency parameter actually buys, and why your protocol choice does not change the picture your viewers get.
On this page
Before the comparison: the mistake that costs people their first hour is in the SRT URL, and it does not produce an error message. Read the next section even if you skip everything else.
The failure that looks like nothing happening
An SRT ingest URL carries a streamid that looks like this: #!::r=live/sk_srt_…,m=publish. Those characters — #, !, :, , — are exactly the ones a careful person percent-encodes out of habit. Do not. The SRT library does not percent-decode the streamid; it forwards the literal bytes to the server. An encoded streamid therefore arrives as a stream name that begins with %23, the server treats the connection as a playback request rather than a publish, and nothing is reported to you. Your encoder shows a healthy connection. The stream card shows no signal. There is no error anywhere.
Paste the SRT URL exactly as the API returns it. dcast returns it in its literal, publishable form under data.ingest.srt on GET /api/v1/streams/:id, and the same value under data.ingest.srtDisplay, which exists only as an alias for older integrations. Either one goes straight into your encoder with no rewriting.
What dcast accepts
A stream card can be fed by any of these. The choice is yours per card, and it does not change the picture your viewers get.
| Protocol | Where it goes | Best for |
|---|---|---|
| RTMP | rtmp://a.dcast.pro/live/<key> |
The default. Every encoder speaks it. Good networks. |
| SRT | srt://a.dcast.pro:10080?streamid=… |
Unreliable or long-haul networks; remote contribution |
| WHIP | POST SDP offers to the returned HTTPS endpoint |
Browser sources and sub-second contribution paths |
| HTTP pull | You give us an .m3u8 URL and we fetch it |
A stream that already exists somewhere else |
| File | You give us a file URL and we play it out | Scheduled playout of finished material |
The hostname is always a.dcast.pro — the entry point of the routing pool, never an individual server name. That is deliberate: it means the address you configured once keeps working when the stream lands on a different machine.
RTMP: the one that always works
RTMP is old, and that is its entire advantage. Every encoder, every camera with a streaming mode, every phone app and every appliance you might be handed on site can send RTMP without configuration beyond a server and a key. If you are streaming from a stable network and you are not solving a specific problem, RTMP is correct and you should stop reading here.
Its weakness is what happens when the network is not stable. RTMP runs over TCP, and TCP handles loss by retransmitting and waiting. On a good link that is invisible. On a link with real packet loss it is not: the stream develops latency it never gives back, or it stalls, and the recovery behaviour ranges from graceful to a disconnect depending on the encoder.
Split the URL at the last slash if your encoder wants a server and a key separately: server rtmp://a.dcast.pro/live, key sk_rtmp_…. (Stream keys are prefixed by the protocol the card was created for — sk_rtmp_, sk_srt_, sk_webrtc_ — so the key you paste should match the door you are knocking on.)
SRT: the one for bad networks
SRT exists for the case RTMP handles badly — a link with packet loss that you cannot fix, which in practice means mobile networks, public venue Wi-Fi, and anything crossing a long distance.
The idea is a fixed latency budget. Instead of retransmitting until the packet arrives however long that takes, SRT keeps a buffer of a chosen size and re-requests lost packets only while there is still time to place them correctly. Packets that cannot make it in time are dropped rather than allowed to delay everything behind them. The result is a stream with predictable delay and graceful degradation under loss, instead of unpredictable delay and stalls.
That buffer is the latency parameter, expressed in milliseconds. The URLs dcast issues carry 500 ms, and you can raise it as far as 7000. The trade is direct and there is no clever setting: a larger value survives worse loss and adds exactly that much delay. If your stream is losing packets, raise it.
Lowering it below 500 is the one thing that will not work, and it is worth knowing why rather than discovering it. Our ingest declares 500 ms of its own, and an SRT connection settles on the larger of the two ends' figures — so an encoder asking for 80 ms still gets 500. The number is a floor, not just a default.
Two more SRT settings are worth knowing. Mode — dcast issues caller URLs, meaning your encoder initiates the connection outward, which is what works from behind a router with no port forwarding. listener and rendezvous exist for setups that need them. And passphrase — SRT can encrypt the link; if you set one, it must be at least ten characters.
WHIP: the one from the browser
WHIP is how a WebRTC source publishes. Instead of a stream URL you post an SDP offer to an HTTPS endpoint and a peer connection is established. dcast returns that endpoint alongside the others on the stream card.
Use it when your source is a browser — a guest with nothing installed, a web-based control surface, a screen share — or when you need contribution latency below what a segmented path can offer. Encoders that support WHIP expose it as a stream service where you paste the returned URL as-is; there is no separate stream key field, because the key is already in the URL.
Its limitation is that WebRTC is a more demanding thing to run than a TCP push. It is more sensitive to restrictive networks, and it is less universally supported by hardware encoders than RTMP.
Your protocol choice does not change your picture
This is the part that saves people a lot of testing. Whatever protocol delivers your stream, it is normalised into one internal form before anything else happens, and the encoding ladder that runs afterwards is identical. The same rungs, the same bitrate ceilings, the same 2-second keyframe interval, the same 4-second segments with two keyframes each.
Which means: an SRT stream and an RTMP stream carrying the same source at the same bitrate produce the same output. Choosing SRT does not buy you a better picture, and choosing RTMP does not cost you one. Choose on the basis of how your network behaves, which is the only thing the choice actually affects.
The frame rate is likewise decided on our side rather than by the protocol, and identically for all three: at the time of writing the live ladder is encoded at 30 fps whatever you send.
Do not build the ingest URL by hand
Every ingest address dcast gives you is issued by the API for one specific stream card, and each part of it is doing something. GET /api/v1/streams/:id returns them all together under data.ingest, and the correct workflow is to copy from there every time rather than to keep a URL in a document and edit the key in it.
The hostname is the pool entry point rather than a machine name, so it stays valid if your stream is served from somewhere else next week. The key identifies your card. For SRT, the streamid additionally carries the mode — m=publish is what makes the connection a publish rather than a playback — which is precisely why the encoding failure at the top of this article is so quiet: corrupt the streamid and you have not sent a malformed request, you have sent a perfectly valid request to watch a stream that does not exist.
Two habits prevent nearly all of it. Copy the whole URL, including everything after the ?, in one action. And when an encoder insists on separate server and key fields, split at the last slash and paste both halves rather than retyping either.
If you are integrating rather than configuring by hand, request the ingest targets at the point of use instead of caching them, for the same reason: the value you are given is correct now, and it is cheap to ask again.
Encrypting the link
SRT can encrypt the stream between your encoder and us with a passphrase. It is worth turning on whenever the link crosses a network you do not control — a venue's guest Wi-Fi, a hotel, a shared uplink at a conference — because on those networks the contribution feed is the one thing you genuinely cannot re-do if someone interferes with it.
The passphrase must be at least ten characters. Set the same value on both ends; a mismatch fails the handshake rather than degrading, which is the behaviour you want, because a silent downgrade to unencrypted would be worse than a refusal.
Encryption costs a little processing at each end and nothing in picture quality. If you are already using SRT because the network is untrustworthy, the same reasoning usually applies to whether it should be readable.
Choosing, in one paragraph
If your network is a wired connection in a building you control, use RTMP. If you are on a mobile connection, on venue Wi-Fi, or sending across a continent, use SRT and raise the latency until the stream is clean. If your source is a web browser, use WHIP. If the content already exists as a stream somewhere else, use HTTP pull and let us fetch it rather than restreaming it by hand. Those four sentences cover almost every real case.
Testing an ingest before the event
Test with the actual URL from the actual stream card, not a URL you assembled yourself. Most first-time failures are a hand-built address.
Test from the actual venue, on the actual connection, at the actual time of day if the venue is busy. A network that is clean at nine in the morning and saturated at seven in the evening is the normal case, not the exceptional one.
For SRT specifically, watch your encoder's loss and retransmission counters during the test rather than watching the picture. The picture looks fine right up until the latency budget is exhausted, so the counters warn you and the picture does not.
And confirm the stream card shows signal, not just that your encoder shows connected. Those are two different claims, and the SRT streamid failure at the top of this article is precisely the case where the first is true and the second is false.
Frequently Asked Questions
Which is better, RTMP or SRT?
Neither, on picture quality — both feed the identical encoding ladder. SRT is better on networks with packet loss, because it re-requests lost packets within a fixed latency budget instead of retransmitting indefinitely. RTMP is better everywhere else, because every encoder supports it without configuration.
Why does my SRT stream connect but never appear?
Almost always because the streamid was percent-encoded. The SRT library forwards the literal bytes, so an encoded streamid reaches the server as an ordinary stream name and the connection is treated as playback rather than publishing. Paste the URL exactly as the API returns it.
What SRT latency value should I use?
Start with the default of 120 ms. Raise it if your encoder reports packet loss or retransmissions; the added delay is exactly the value you set. dcast accepts 0 to 7000 ms.
Do I need port forwarding for SRT?
Not for the URLs dcast issues. They are caller mode, which means your encoder opens the connection outward — the normal case behind a home or venue router. Listener and rendezvous modes exist for setups that require them.
Can I stream straight from a browser?
Yes, via WHIP. The stream card returns a WHIP endpoint that a WebRTC source posts an SDP offer to. There is no separate stream key to enter, because it is already part of the returned URL.
dcast Team
Professional video streaming experts helping creators succeed.
Related Articles
Start Your Video Business Today
Join thousands of creators monetizing their content with DCAST.
Get Started Free



