Skip to main content

RTSP streaming over dual nat with RTSP Interleaved mode

I have an IP Camera that supports RTSP streaming (most IP cameras seem to support it - Axis, Edimax, etc). This allows you to view mpeg4 or h264 live streams either by using a proprietary ActiveX control (via their web interface) or via a RTSP client.

If you are in the same LAN as the camera, you can easily connect to it by using VLC or even ffmpeg (to save or transcode the stream):

vlc rtsp://192.168.1.10/ipcamera_h264.sdp
ffmpeg -i rtsp://192.168.1.10/ipcamera_h264.sdp test.ts
ffmpeg -i rtsp://192.168.1.10/ipcamera_h264.sdp -f mpegts | vlc -



The problem is if you want to access that camera over the Internet. RTSP usually transports the data over UDP and negotiates the UDP ports over a control session on port 554 TCP. This gets difficult if you use NAT at either end or if you have firewalls you need to get through.

Let's consider this typical scenario:



The packets need to go through 2 NATs to travel between the source and destination. To make this happen, you have 3 possible solutions:

1. Using a session management protocol like ICE, but it needs to be supported by the client and server. Cheap IP cameras don't usually support it
2. Using a Layer 3 or Layer 2 VPN between RouterA and RouterB. With a VPN set in place (and with the appropriate firewall permits), the client can connect via RTSP to the server and it would communicate the same way it does in a LAN environment (no more NAT!). However, your routers need to be configured for site-to-site VPN - which might be challenging (especially if you don't have management access on either router)
3. Using RTSP Interleaved mode - a method I will describe next

According to Wikipedia:
Certain firewall designs and other circumstances may force a server to interleave RTSP methods and stream data. This interleaving should generally be avoided unless necessary since it complicates client and server operation and imposes additional overhead. Interleaved binary data SHOULD only be used if RTSP is carried over TCP.

So, instead of using UDP to transfer data, it uses TCP, and furthermore, it piggybacks the video data on top of the control session that is established on port 554. It may be less efficient in payload size and processing power, but it works with NAT and firewalls - which is what we want.

So, for the example above we have the following prerequisites for this to work:
  1.  The ability to port forward on RouterB
  2.  The IP Camera must have a fixed IP address (in order for port forwarding to work). This can be done either by assigning a static IP manually, or through DHCP.
  3.  Client and server must support RTSP Interleaved mode


Port forwarding setup

Depending on your router's firmware this can be done in different ways. I will not show a specific way to do it, just the concept. On RouterB you need to allow incoming TCP packets from source IP 11.11.11.11 (the NATed IP of the client) to go to your IP camera's IP (192.168.1.10) on the RTSP port (554 by default).

Since this is port forwarding you are actually forwarding a TCP port on your router (e.g. 22.22.22.22:1234) to an internal server in your network (192.168.1.10:554), so you will need to decide which external port you will be using (I used 1234 in my example).

If you have multiple IP Cameras behind RouterB, you can add multiple port forwarding rules - like this:

allow TCP from 11.11.11.11 to 192.168.1.10:554 on external port 1234
allow TCP from 11.11.11.11 to 192.168.1.11:554 on external port 5678
The port forwarding rule does not necessarily have to specify the source address - if it is missing it will allow access from any source address - but this is a security risk, so I advise against it.

RTSP Interleaved mode
Right now, you should be able to connect to the camera from the client computer, but if you try to use RTSP, you will notice that the control session is established, but the data never arrives because the NAT and firewall prevent the communication on the negotiated UDP ports.

You must convince the client software to try connecting in interleaved mode (this is why you came here for, right?).

VLC: Well, according to http://www.wowza.com/forums/content.php?64 you need to do the following configuration in VLC:

  1. Open VLC
  2. Select menu item Tools: Preferences
  3. Select the Input & Codecs section
  4. Select the Live555 stream transport option RTP over RTSP (TCP)
  5. Click Save button
You can now connect to your stream using the command:

vlc rtsp://22.22.22.22:1234/ipcamera_h264.sdp
For other cameras, change the destination port (e.g. 1234 -> 5678) in your command

FFMPEG: Their documentation states that you need to use the rtsp_transport flag:

ffmpeg -rtsp_transport tcp -i rtsp://22.22.22.22:1234/ipcamera_h264.sdp test.ts
ffmpeg -rtsp_transport tcp -i rtsp://22.22.22.22:1234/ipcamera_h264.sdp -f mpegts | vlc -
In case of problems, you should analyse a packet capture and see if Interleaved mode is supported by both end systems (it is negotiated in a RTSP OPTIONS request) - capture example below:


Have fun streaming!

Comments

Deniel nash said…
This comment has been removed by a blog administrator.

Popular posts from this blog

Home Assistant + Android TV = fun

Here's a quick setup guide for controlling your Android TV from within Home Assistant. I've used it to control a genuine Android TV (Philips 7304) and an Odroid N2 running Android TV. For this to work you need ADB access. It can usually be enabled from within Developer Settings. The great part is - you don't need root access! The most important things are described in the androidtv component for Home Assistant: https://www.home-assistant.io/integrations/androidtv/ Make sure you go through the adb setup. My configuration is simple (inside configuration.yaml): media_player:   - platform: androidtv     name: TV Bedroom ATV     host: 192.168.1.61     device_class: androidtv Once Home Assistant restarts, your TV might require you to accept the connection (adb authentication). This happens only once (or until you reset your ATV to factory settings). Once running the integration will show you the current ATV state (on or off) and al...

SmokePing + InfluxDB export + docker + slaves + Grafana = fun

I've been working for a while on this project - with the purpose of getting SmokePing measurements from different hosts (slaves) into InfluxDB so that we can better graph them with Grafana. The slaves run multiple Smokeping instances inside Docker so that they have separate networking (measure through different uplinks, independently). This will not be a comprehensive configuration guide, but a quick "how to" to handle setup and basic troubleshooting. It assumes you already know how to set up and operate a regular Smokeping install with or without slaves and that you are fluent in Smokeping configuration syntax, know your way around Docker and aren't a stranger from InfluxDB and Grafana (sorry, there's a lot of information to take in). 1. Getting Smokeping with InfluxDB support - you can get it either from the official page (most changes have been merged) - https://github.com/oetiker/SmokePing (PR discussion here: https://github.com/oetiker/SmokePing/issues/...

Android: Adding scp/sftp support to dropbear and mounting with sshfs

I have recently received an android smartphone, and one of the first things I did with it was to root it :). This allows power-usres to get the most out of their hardware. The next thing on my list was to set up a SSH server and to be able to transfer files between my Linux system and my phone (by the way, I'm running Android 4.1 and it seems USB mass storage support has been removed. MTP/PTP modes have either horrible transfer speed or are poorly supported in Ubuntu). With the above in mind, the plan was to: Enable tethering on the phone Run a SSH server to support issuing remote commands and file transfer (FTP might have been an alternative, but I'm a SSH adept). Browsing the market I found  SSHDroid which does all that it advertised. Problem is - the free version conflicts with my add-blocking apps and requests that they are disabled to run. For me, this is a big nuisance, so I kept looking. I found Dropbear SSH Server 2 , which is completely free, but doesn'...