RTSP get video from IP Camera with Erlang

Trying to find any examples of how to get video from IP Camera via RTSP and record it on disk with Erlang. Is there any examples or manuals? Where to start to develop this functionality? For me isn’t clear the global mechanism of interacting with camera.

The things that found by is:

When trying to connect via Telnet:

PLAY rtsp://192.168.*.*:554/live/main RTSP/1.0
Authorization: Basic *************=

RTSP/1.0 200 OK
CSeq: 0
Range: npt=0.000-
Session: 00000000
RTP-Info:

But video stream not appearing. What is missing by me?

The Erlang ode for connecting to IP Camera looks like:

get_rtsp() ->
	{ok,Socket} = gen_tcp:connect("192.168.*.*",554,[binary, {packet, line}]),
	ok = gen_tcp:send(Socket, "OPTIONS rtsp://192.168.*.*:554 RTSP/1.0\r\n\r\n"),
	rtsp_data(Socket, []).
rtsp_data(Socket, SoFar) ->
	receive
		{tcp,Socket,Bin} ->
			erlang:display(is_binary(Bin)),
			erlang:display("Bin"),
			erlang:display(Bin),
			<<"RTSP/1.0 200 OK\r\n">> = Bin,
			rtsp_data(Socket, [Bin|SoFar]);
		{tcp_closed,Socket} ->
			erlang:display("SoFar"),
			erlang:display(SoFar)
	end.

The DESCRIBE of IP Camera looks like:

DESCRIBE rtsp://192.168.*.*:554 RTSP/1.0
Authorization: Basic *************=

RTSP/1.0 200 OK
CSeq: 0
Content-Type: application/sdp
Content-Length: 390

v=0
o=- 1693921639435130 1 IN IP4 0
s=brovtech
t=0 0
a=control:*
a=range:npt=0-
a=recvonly
m=video 0 RTP/AVP 96
c=IN IP4 0.0.0.0
b=AS:5000
a=control:track1
a=rtpmap:96 H264/90000
a=fmtp:96 packetization-mode=1;profile-level-id=4d002a;sprop-parameter-sets=Z00AKpWoHgCJ+WbgICAgQA==,aO48gA==
m=audio 0 RTP/AVP 8
c=IN IP4 0.0.0.0
b=AS:50
a=rtpmap:8 PCMA/8000
a=control:track2

When trying to use SETUP command - just closing connection without any reason:

SETUP rtsp://192.168.*.*:554 RTSP/1.0
Authorization: Basic *************=

Connection closed by foreign host.

OPTIONS command reply looks like:

OPTIONS rtsp://192.168.*.*:554/live/main RTSP/1.0

RTSP/1.0 200 OK
CSeq: 0
Public: OPTIONS, DESCRIBE, SETUP, TEARDOWN, PLAY, SET_PARAMETER

Almost every camera vendor has their own bugs in RTSP implementation (so does erlyvideo code las modified 12 years ago).
The best I can suggest is connecting to that camera with other client (e.g. ffmpeg) and modifying rtsp.erl to make the same requests on handshake.
Also you may try switching the transport (udp/tcp), it may help with some cameras.

Oh-yea-a-a!!! Especially from cheap-China-vendors …
We decided to proceed with FFMPEG implementation of RTSP. Developing erlang application that is using FFMPEG. So far so good …

2 Likes

can you give a start point / reference for using ffmpeg with Erlang? cheers

It depends on what and how you going to do in context of your own resources.

  1. Running FFMPEG from Erlang node by using ErlExec (GitHub - saleyn/erlexec: Execute and control OS processes from Erlang/OTP). There are total dependancy on what could be done with ffmpeg command in shell. Sometimes it’s not Ok for what you need. But if you don’t need something unique - it could be used. In some cases it could be up to 2000-3000 symbols. To write it manually almost impossible. There should be adjustable FFMPEG-command-generator.

  2. If you need something special in FFMPEG functionality (means developing own FFMPEG library based application) or want to mix FFMPEG and OpenCV you need to write your own C/C++ application and make a connection between Erlang node and your application itself. How to organise interraction - up to you and your own level of abilities. It might be plain socket, it might be ErlExec, it might be Erlang Port. This mix will not be simple in development.

Beside all of it there are might be HUGE troubles with cameras. Chinas cheap camera vendors do what they want and how they want. The result of their activities totally unpredictable. It will be matter of how you organise process of camera testing and determinations of cause of the problem. It might be very tricky.

Beside all of it in reality super-mega-poor documentation of FFMPEG itself, there are only some simple examples. But if you need adjust something special - only experiments and experience. If you developing cluster with huge amount of cameras you need to start thinking of how to mix Erlang and FFMPEG/RTSP with security and DevOps in case of planing scalability from begin. For me handling +600 cameras per server (there are 10 servers for begin planned by me only for receiving RTSP streams and more for keeping archived data) within automation were additional amount of DevOps activities. The amount of DevOps development almost equal to server itself. Especially if you need to pass any kind of security certification.

Another one trouble is how you going to organise storage for recorded video. It’s HUGE!!! Handling this amount of archived data really not trivial. You will have very painful process of balancing what you want with you budget and what you really can to develop by level of your knowledge. If you you need restream it on-line - you will face performance issues and how to mix archived data with realtime streaming. The solution will depend on level of knowledge of developers who is creating client side.

And many other things …

1 Like

My advise based on my own experience:

  • Take care of test lab that will allow you to do without any risk to kill project in production. It will allow you to recognise camera special differences. Especially if there OnVif.
  • If you have no enough of experience in playing around FFMPEG library written with C and have no imagination of how FFMPEG working itself start with ErlExec and command line. It’s MUCH simpler.
  • If you just starting your project from scratch and have no experience with mixing FFMPEG and Erlang try to hire someone with proven experience (ONLY with proven experience!!! Do not make my boss mistakes of hiring only by word) it will reduce time and cost in result dramatically even you hire someone like mentor or part time consultant.
1 Like

About RTSP protocol itself - we decided not develop own RTSP handler with Erlang or any other languages. Using FFMPEG only.

1 Like

Hi there, I’m a maintainer of Membrane, an Elixir framework for media streaming. It supports RTSP and many other protocols. There’s also ex_nvr that uses Membrane’s RTSP extensively. For some time I’ve been thinking about making Membrane usable from Erlang. Even though I don’t have much experience in Erlang, I believe it shouldn’t be that hard, and the experience for the Erlang users should be fairly seamless. Would you find it useful? Would anyone be willing to help with this?

5 Likes

Pretty sure I’d find a lot of uses for an Erlang Membrane, I’ve looked enviously at it several times. Very little elixir knowledge here but would be extremely happy to help test an Erlang version.

2 Likes

Great, I’ll try to come up with some POC :wink:

1 Like