kerberos-io / machinery

(DEPRECATED) An open source image processing framework, which uses your USB-, IP- or RPi-camera to recognize events (e.g. motion).
https://www.kerberos.io
490 stars 104 forks source link

RTSP bug: Issue with IP camera Onvif RTSP endpoint #84

Closed cedricve closed 6 years ago

cedricve commented 7 years ago

Looks like the machinery isn't able to connect to an IP camera with ffollowing URI rtsp://192.168.0.101:554/onvif1

Original thread can be found here: kerberos-io/web#71

BinkyWong commented 7 years ago

I have a similar camera, it's the sp009 model and it gives the same error. However - I've managed to work around it by re-encoding the stream like this using the above example:

ffmpeg -i "rtsp://192.168.0.112:554/onvif1" http://localhost:8090/monitoring1.ffm

you then use the alternative streamed URL:

http://yousourceip:8090/monitoring1.ffm

I have verified it working on zoneminder using the following parameters (see screenshots)

image

image

note - you'll need ffserver running in order to stream. The resulting re-stream is really horrible, but it at least shows you can convert between one format and another. Seems like it just does not like the original encoding?

BinkyWong commented 7 years ago

btw, this is the camera used:

https://www.aliexpress.com/item/HD-Mini-Wifi-IP-Camera-Wireless-720P-Smart-P2P-Baby-Monitor-Network-CCTV-Security-Camera-Home/32465427111.html?spm=2114.01010208.3.2.kYbjgB&ws_ab_test=searchweb0_0,searchweb201602_2_10152_10065_10151_10130_10068_436_10136_10157_10137_10060_10138_10155_10062_10156_10154_10056_10055_10054_10059_100031_10099_10103_10102_10096_10147_10052_10053_10050_10107_10142_10051_10084_10083_10119_10080_10082_10081_10110_10111_10112_10113_10114_10179_10037_10181_10183_10182_10185_10033_10184_10032_10078_10079_10077_10073_10070_10123_10120-10033,searchweb201603_16,ppcSwitch_7&btsid=3838c5b0-9cb8-45c7-89e6-bc72139c8994&algo_expid=8ec190e7-5fdd-4979-b469-3ceee7c4d02a-0&algo_pvid=8ec190e7-5fdd-4979-b469-3ceee7c4d02a

BinkyWong commented 7 years ago

codec info here from vlc

image

cedricve commented 7 years ago

@BinkyWong Thanks! Did you tried the workaround with Kerberos.io?

BinkyWong commented 7 years ago

BTW - awesome software, I really can't believe it's not more popular!

Yes I did - initially, the results were really fuzzy and unworkable, but proved a point - that you can re-stream the outputs from these cameras an make them into something more usable for kerberos.io.

I've done some additional tweaking today in my test environment, I've actually managed to get a really nice quality re-stream and kerberos.io was able to view it correctly.

I amended the stream section of ffserver.conf:

<Stream test.mpeg4>
Feed feed.ffm
Format rtp
VideoCodec mpeg4
VideoFrameRate 15
VideoBufferSize 80000
VideoBitRate 100
VideoQMin 1
VideoQMax 5
VideoSize 640x360
PreRoll 0 
Noaudio
</Stream>

I'm running everything in docker, so I re-streamed using:

docker exec -it kerberosio_web_1 ffmpeg -i "rtsp://192.168.0.111:554/onvif1" http://192.168.0.112:8090/feed.ffm

and in the kerberos.io source, I used:

rtsp://192.168.0.112:554/test.mpeg4

I'm running a docker environment on a Dell Laptop with 4GB RAM with a Intel(R) Core(TM) i5 CPU M 520 @ 2.40GHz

With the following running in the background as containers:

and ffmpeg constantly converting and re-streaming the rtsp stream, I get a load average between 0.4 and 0.8 which I guess is not too bad, but probably will shoot up a ton more if I wanted to do more streams.

Not to bad as a workaround - I'm hoping to get rid of ZoneMinder in favor of this once I've got it all setup properly - I'm running Zoneminder in a docker environment too.

BinkyWong commented 7 years ago

@mcgyver83 do you still have your original problem? The above may be a OK workaround for you.

cedricve commented 7 years ago

@BinkyWong nice work a round, however we may need to look for a solution to support onvif out of the box. PS i like your sense for creativity!

BinkyWong commented 7 years ago

@cedricve haha thanks! I like to a good challenge :) yes fully agree, out of the box onvif would be fantastic - also the ability to autodetect cameras would be great too, e.g. https://sourceforge.net/projects/onvifdm/ does a great job of auto detecting cameras on your network.

ffmpeg also sometimes bombs out when streaming and does not auto-recover so I've put the workaround into an endless loop:

while true; do docker exec -it camerafront_web_1 ffmpeg -i "rtsp://192.168.0.123:554/onvif1" http://192.168.0.101:8090/feed1.ffm; done

so it just keeps going. It's now stable enough for me to switch from Zoneminder permanently now :)

cedricve commented 6 years ago

hey @BinkyWong, I'm looking at OpenRTSP to start using it, as it gives better overall IP camera support for RTSP streams. It contains much more fallbacks for hacky RTSP streams.

BinkyWong commented 6 years ago

@cedricve awesome - i'm looking forward to it!!!

mcgyver83 commented 6 years ago

@BinkyWong I paused my ipcam project for the summer, now I'm starting again. I have a lot of things to refresh :(

Btw, this solution require a ffserver, any hints or nice guide to setup it? Seem that at the end this workaround produces bad output video, isn't it?

BinkyWong commented 6 years ago

@mcgyver83 , it's actually not too bad, here's my setup (I'm using Docker to host):

docker run -d -p 554:554 -p 8090:8090 -v /home/binky/kerberos/ffserver.conf:/etc/ffserver.conf vimagick/ffserver

(alter to suit your needs)

where ffserver.conf is:


RTSPPort 554
RTSPBindAddress 0.0.0.0

Port 8090
# bind to all IPs aliased or not
BindAddress 0.0.0.0
# max number of simultaneous clients
MaxClients 1000
# max bandwidth per-client (kb/s)
MaxBandwidth 10000
# Suppress that if you want to launch ffserver as a daemon.
NoDaemon

<Feed feed1.ffm>
File /data/feed1.ffm
FileMaxSize 200M
ACL allow 127.0.0.1
ACL allow 192.168.0.0 192.168.255.255
ACL allow 192.168.1.0 192.168.255.255
</Feed>

<Feed feed2.ffm>
File /data/feed2.ffm
FileMaxSize 200M
ACL allow 127.0.0.1
ACL allow 192.168.0.0 192.168.255.255
ACL allow 192.168.1.0 192.168.255.255
</Feed>

<Stream feed1.mp4>
Feed feed1.ffm
Format rtp
VideoCodec mpeg4
VideoFrameRate 20
VideoBufferSize 80000
VideoBitRate 100
VideoQMin 1
VideoQMax 5
VideoSize 640x360
PreRoll 0
Noaudio
</Stream>

<Stream feed2.mp4>
Feed feed2.ffm
Format rtp
VideoCodec mpeg4
VideoFrameRate 20
VideoBufferSize 80000
VideoBitRate 100
VideoQMin 1
VideoQMax 5
VideoSize 640x360
PreRoll 0
Noaudio
</Stream>

So that is the ffserver setup only, we now need to make the stream compatible, so I run these in screen/tmux sessions:

# Front
while true; do ffmpeg  -rtsp_transport udp  -i "rtsp://192.168.0.105:554/onvif1" http://192.168.0.104:8090/feed1.ffm; done   

# Back
while true; do ffmpeg  -rtsp_transport udp  -i "rtsp://192.168.0.239:554/onvif1" http://192.168.0.104:8090/feed2.ffm; done   

I have to stick these in while/do loops as it can sometimes crash when wifi is lost...messy but works!

I use the following as the source for my instances:


#Front

rtsp://172.17.0.1:554/feed1.mp4

#Back

rtsp://172.17.0.1:554/feed2.mp4

so, the flow is basically this:

The resulting video is actually not too bad now that I've tweaked the ffserver settings a bit. I use it now for both front and back of my house, it runs great!

hope this helps!

mcgyver83 commented 6 years ago

Many thanks! I'm going to try in the week end.

I need to setup an ffserver on my raspberry before doing this.

gianricod commented 6 years ago

Hi I have one of these cameras. It looks like the issue is that opencv forces ffmpeg to use rtsp tcp rtsp transport. That is fine, but the firmware of the ipcam replies with a generic RTSP transport header:

Transport: RTP/AVP;unicast; ....

libavformat of ffmpeg detects it as UDP transport ( libavformat expects RTP/AVP/TCP for TCP),

So in the end libavformat will give an error:

"Nonmatching transport in server reply"

When using ffmpeg from the command line, it defaults to UDP so the issue is not seen.

You can reproduce the issue if you do:

ffmpeg -i "rtsp://192.168.2.8/onvif2" -y test.mp4 -rtsp_transport tcp

I have a patch for ffmpeg but at the moment i am still validating it.

thanks gianrico

cedricve commented 6 years ago

Amazing find @gianricod, I already forked the OpenCV library (for H264 OMX integration). I think we could integrate it in there: github.com/cedricve/opencv.

Let me know what you think @gianricod

cedricve commented 6 years ago

@gianricod I was curious if you had the time to evaluate your patch?

gianricod commented 6 years ago

Hi @cedricve busy at work, sorry.

This is an extremely simple change (one line) to libavformat/rtsp.c . It works fine and more then the patch itself, i was trying to validate whether the behavior introduced was not generating a violation of the RTSP protocol. And that seems ok too because the RFC states that 'interleaved' is for TCP (Page 40 of rfc2326 -- "Interleaved binary data SHOULD only be used if RTSP is carried over TCP.") .

#######

diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index b6da61b95e..2d62278080 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -946,6 +946,8 @@ static void rtsp_parse_transport(AVFormatContext *s,
                                      &th->server_port_max, &p);
                 }
             } else if (!strcmp(parameter, "interleaved")) {
+                   //likely TCP
+                   th->lower_transport = RTSP_LOWER_TRANSPORT_TCP;
                 if (*p == '=') {
                     p++;
                     rtsp_parse_range(&th->interleaved_min,

##########

As you see modification is for ffmpeg(libavformat) and not opencv. If you want a solution from inside opencv, the only one would be to select UDP transport , but that does not seem to be possible at runtime as far as i could read, and one would need to force it at compile time. TCP transport in opencv is set in the file /modules/videoio/src/cap_ffmpeg_impl.hpp:

av_dict_set(&dict, "rtsp_transport", "tcp", 0); And from what i could read, there is no wrapper in opencv for using av_dict_set to set ffmpeg options.

You can add ffmpeg (libs only) as dependency to clone and compile.

thanks gianrico

cedricve commented 6 years ago

Awesome @gianricod, I think we should integrate it into KiOS for the time being. https://github.com/kerberos-io/kios/tree/master/package/ffmpeg

cedricve commented 6 years ago

hey @gianricod, it's been a while. Just wondering if your fix is still "stable" or you change thoughts..

gianricod commented 6 years ago

Hi @cedricve

I have tested the change and had not noticed any bad effects of it. ffmpeg team has not accepted the patch anyway (no feedback from them). I believe you can safely add it to kios. As you see the patch is very simple and the RFC states that interleaved is only for TCP. So the above should be safe.

Which version of ffmpeg are you planning to use in kios?

cedricve commented 6 years ago

Cool, would be great if we can add to this to our next release (I'm planning to release it by the end of this week). At the moment we use ffmpeg 3.3.4 https://github.com/kerberos-io/kios/blob/develop/package/ffmpeg/ffmpeg.mk#L7

We could add your patch in here: https://github.com/kerberos-io/kios/tree/develop/package/ffmpeg

szepnorbee commented 6 years ago

Hi! I have a problem with my chinese IP cam. Kerberos can't connect to them via RTSP. The booth url (hi and lo quality) is working with VLC. URL-s: rtsp://xxxx.duckdns.org:55400/onvif1 rtsp://xxxx.duckdns.org:55400/onvif2 I have no password protection. I tested with & az the end of the url without positive resulth.

My Kerberos LOG:

gianricod commented 6 years ago

Hi

1) Can you start kerberosio from the command line and report the output?

2) https://www.wowza.com/docs/how-to-configure-vlc-media-player-for-rtsp-rtp-playback-rtsp-rtp-interleaved-and-tuning -- following this article please set vlc to use tcp for rtp/rtsp . If you cannot connect to the camera, then this is the same as i explained in previous comments. You need a patched libavformat to fix that.

cedricve commented 6 years ago

hey @gianricod @srgazevedo , gianricod's fix is available in both KiOS and Raspbian .deb files. How did you installed kerberos.io @szepnorbee ?

szepnorbee commented 6 years ago

@cedricve I installed followed this instruction: https://doc.kerberos.io/2.0/installation/Armbian Orange PI PC board with latest Armbian (Armbian_5.38_Orangepipc_Debian_stretch_next_4.14.14) image.

cedricve commented 6 years ago

makes sense, the patch isn't included in that release. It will use the default FFMPEG package shipped by Armbian package manager.

szepnorbee commented 6 years ago

@cedricve It is possible to update the FFMPEG package manual? Iam new in linux.

sgerhager commented 5 years ago

hey, I also have the issue with the stream of the (Chinese) cams not being detected. I'm using the docker version on an old macbook running Arch linux on it. The hack with the FFmpeg restreaming does not work very stable and takes away a lot of resources ...

Do you also have an update (e.g. patched libavformat) for the docker version which fixes the UDP issue above?

ibnbd commented 5 years ago

@cedricve I am also using the docker version, can we have the libavformat patch please.

Thank You