Tutorial: Building and Testing RTSP Stream URLs for IP Cameras

Contents
An IP camera delivers its video over RTSP, and RTSP is standardised. The address that leads to the video is not. Every manufacturer invented a path of its own, and a camera asked on the wrong path answers exactly as it answers a wrong password: with nothing at all.
Such an address has six parts. Four of them look the same on every camera, two have to be looked up per manufacturer. What follows is the order in which the parts are best assembled, and the single command that settles whether the result works – before it disappears into a recorder, where the mistake hides behind six other settings.

The Six Parts of a Stream Address
An RTSP address is built like a web address: scheme, credentials, host, port, path, and on some cameras a query string that carries the stream number.
rtsp://admin:Sommer%402026@192.168.1.64:554/Streaming/Channels/102
rtsp://admin:Sommer%402026@192.168.1.64:554/cam/realmonitor?channel=1&subtype=1
rtsps://192.168.1.1:7441/aBcD1234EfGh?enableSrtp
The scheme is rtsp and the port 554, as long as nobody moved it. Ubiquiti is the exception worth remembering: UniFi Protect answers on rtsps at port 7441, refuses plain RTSP, and hands out an opaque alias instead of a readable path. That alias appears only after RTSP has been switched on for the individual camera in Protect.
Host means the camera, never the recorder. A recorder can re-serve a stream, but then it serves its own address on its own port, and a mistake at that layer looks identical to a broken camera.
Why the Path Differs on Every Camera
The path carries two pieces of information that RTSP itself has no field for: which lens, and which of its streams. Nearly every camera offers at least two – a main stream at full resolution for recording, and a substream at a quarter of it for previews and motion analysis.
| Manufacturer | Main stream | Substream |
|---|---|---|
| Hikvision | /Streaming/Channels/101 | /Streaming/Channels/102 |
| Dahua, Amcrest | /cam/realmonitor?channel=1&subtype=0 | /cam/realmonitor?channel=1&subtype=1 |
| Reolink | /h264Preview_01_main | /h264Preview_01_sub |
| Axis | /axis-media/media.amp | /axis-media/media.amp?resolution=640×360 |
The Hikvision numbering is the one most often mistyped. The three digits are channel and stream glued together: 1 and 01 becomes 101, the second stream of the first channel becomes 102. On a single-lens camera the channel is always 1; on a multi-sensor housing the second lens is 201 and 202.
Guessing stops being necessary as soon as the camera speaks ONVIF. A GetStreamUri call returns the address the camera considers correct, including the path, and that answer beats every table.
Passwords That Break the Address
Credentials sit between the scheme and the host, separated by a colon and closed by an at sign. That is also where the most quietly destructive mistake lives: a password containing an at sign, a colon, a slash or a hash ends the credentials early, and the remainder of the password is read as a host name.
The fix is percent-encoding. An at sign becomes %40, a colon %3A, a slash %2F, a hash %23, a question mark %3F. A password of Sommer@2026 therefore appears as Sommer%402026 in the address and stays untouched in the camera.
Worth knowing about the other end of this: many cameras authenticate over RTSP digest rather than basic auth, so the password never travels in clear text even though it stands in clear text in the address. What does travel in clear text is the address itself – in shell history, in a Compose file, in a log line. Credentials for a camera belong in a separate account with viewing rights only, never in the administrator account.
Testing the Address Before It Goes Anywhere
One command answers the only question that matters at this stage. It opens the stream, reads the first packets, prints what it found and exits.
ffprobe -hide_banner -rtsp_transport tcp \
-i "rtsp://admin:Sommer%402026@192.168.1.64:554/Streaming/Channels/102"
A working address prints a stream line with codec, resolution and frame rate within a second or two. Everything else is a diagnosis, and the four common answers each point somewhere different.
| Answer | What it means |
|---|---|
| 401 Unauthorized | Host and path are right, the credentials are not – or the account has no stream permission |
| 404 Not Found | Credentials accepted, path wrong – a manufacturer or a stream number too far |
| Connection refused | Nothing is listening on 554; RTSP is switched off in the camera, or the port was moved |
| Timeout after the handshake | The session was established, the video packets are not arriving – almost always blocked UDP |
The last of the four explains why -rtsp_transport tcp stands in the command. By default the control channel runs over TCP and the video over UDP on separate ports. Across a VLAN boundary or a firewall, the handshake therefore succeeds and the picture never arrives. Forcing TCP costs a little latency and removes an entire class of faults.
Which Stream Belongs Where
Once the address works, the substream turns out to be the more useful half. Recording needs the main stream, because that is the material an insurer or a court will look at. Motion analysis and object detection need small pictures and get faster with them: a detector fed 4K frames spends its time scaling them down.
Frigate makes that split explicit by assigning roles per stream, and the same idea applies to any recorder that accepts two inputs per camera.
cameras:
driveway:
ffmpeg:
inputs:
- path: rtsp://admin:Sommer%402026@192.168.1.64:554/Streaming/Channels/102
input_args: preset-rtsp-restream
roles: [detect]
- path: rtsp://admin:Sommer%402026@192.168.1.64:554/Streaming/Channels/101
input_args: preset-rtsp-restream
roles: [record]
Two connections to one camera is also the ceiling on many models. Cheap cameras allow four RTSP sessions at once, sometimes only two, and the fifth attempt fails with a message that has nothing to do with the address. A restreamer such as go2rtc solves this by opening one session and handing copies to everyone else.
What Still Breaks Later
An address that worked once can stop working without anything about it changing. Three causes cover almost all of it.
The first is DHCP. A camera addressed by its leased IP moves after a router restart, and the address points at whatever took the number. A reservation in the DHCP server, or a static address inside the camera VLAN, ends this permanently.
The second is a firmware update that resets the RTSP switch or the viewer account. Both are worth checking first after an update, because the symptom – connection refused, then 401 – looks like a network fault.
The third is time. Many cameras drop a session that has been idle without RTCP feedback, and some recorders never send it. What that looks like is a stream that runs for hours and disappears overnight, always at a slightly different time. A restreamer with a reconnect setting removes the symptom; a keepalive interval below the camera’s timeout removes the cause.