IpCamera: New IP Camera Binding

@matt1 Thanks for one of the best bindings for Openhab! It works perfectly for me, except for one thing, the ffmpeg audio alerts stop working after a (temporary) connection issue or when I for example manually restart the camera (to test).
The only way to get it working again is to move the audioThreshold slider one up, that seems to restart the process when looking at the trace logs. I can of course make a rule which increases and decreases the threshold every minute (to restart the stream) but is there a chance you could make it retryable?

These are the last logs when rebooting the camera (Foscam):

2021-11-27 10:34:33.704 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] - size=N/A time=00:19:06.74 bitrate=N/A speed=0.999x    
2021-11-27 10:34:34.319 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] - size=N/A time=00:19:07.36 bitrate=N/A speed=0.999x    
2021-11-27 10:34:34.845 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] - size=N/A time=00:19:07.88 bitrate=N/A speed=0.999x    
2021-11-27 10:34:35.383 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] - size=N/A time=00:19:08.42 bitrate=N/A speed=0.999x    
2021-11-27 10:34:35.949 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] - size=N/A time=00:19:08.98 bitrate=N/A speed=0.999x  

Would expect a connection issue message or something but it seems to just hang…

Btw, I know that Foscam has built-in audio alerts but I’m not satisfied with the (streaming) performance so looking for another cam (Reolink). Unfortunately, most of them don’t have built-in audio alerts so need the ffmpeg variant. I’m assuming this (ffmpeg alerts) works the same for all cams, it’s not a specific Foscam issue, so I will have this issue when buying the Reolink.

Logs after setting the threshold +1:

2021-11-27 10:44:49.875 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] - Stopping ffmpeg RTSP_ALARMS now when keepalive is:8
2021-11-27 10:44:49.884 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] - Starting ffmpeg with this command now:-rtsp_transport tcp -i rtsp://user:********@192.168.2.79:88/audio -af silencedetect=n=-32dB:d=2 -f null -
2021-11-27 10:44:50.194 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] - ffmpeg version 4.1.8-0+deb10u1 Copyright (c) 2000-2021 the FFmpeg developers
2021-11-27 10:44:50.197 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] -   built with gcc 8 (Debian 8.3.0-6)

Thanks for reporting as since I dont use that feature I was not aware it would not restart, but it makes sense…

Correct, same for all cameras if using ffmpeg. If your using Hikvision, Dahua, Amcrest and Instar they will all auto restart the event/alarms methods. Foscams built in should also work automatically. ONVIF cameras that support audio alarms should also restart if the camera goes offline but I have not tested that. Try forcing the foscam to be a ONVIF thing type and check to see if it sends an alarm via the onvif methods.

If the logs say that it had to stop the process when you change the threshold, I don’t think it is an easy fix unless the camera goes offline which will close the process. If you set the gifPreroll to a positive number then it will be polling snapshots and will go offline quickly, that may solve half the issue of knowing when it has stopped, then it would need something added to relaunch the detection. You may be able to restart it with a rule when the camera comes back online.

Hi,

I am trying to use IP Camera Binding, but no luck. I have a Fibaro intercom, that has generic camera, that streams mjpeg. My intercom requires that I provide login:pass within URL. Can this be an issue?
My camera is configured like this:

Thing ipcamera:generic:FibaroCam
[
    ipAddress="192.168.1.229", serverPort=54322,
    gifPreroll=1,
	username="username",
    password="pass",
    snapshotUrl="http://username:pass@192.168.1.229:8080/live/mjpeg",
    mjpegUrl="http://username:pass@192.168.1.229:8080/live/mjpeg",
    ffmpegInputOptions="-f mjpeg",
    ffmpegOutput="/tmp/FibaroCamera/", ffmpegInput="http://username:pass@192.168.1.229:8080/live/mjpeg"
]

I enabled trace, but I don’t see any errors. Camera shows as online.
What I would like to do is to access it using openhabs ip: http://192.168.1.34:54322/ipcamera.mjpeg (in my case)

I use OpenHab 3.1

EDIT:

After playing with it a bit more, now I notice, a line like this in the log:

It looks like ffmpeg can’t somehow access mjpeg stream. Any ideas will be very welcom.

Many Thanks!
Marcin

In the bindings documentation read about the esp32 camera setup. When the only stream available is mjpeg you need to change an option to tell ffmpeg that is the case. The example gives what you will need.

Edit: you have already done that sorry. Delete the snapshot url if you do not have one, by giving it a url for a stream instead of a snapshot that may be the issue.

Thank you for response. I have added a thing definition again through GUI (so I am sure I have default settings correct). The code definition of it is:

UID: ipcamera:generic:b566d3a34d
label: RTSP/HTTP IP Camera
thingTypeUID: ipcamera:generic
configuration:
  ffmpegInputOptions: -f mjpeg
  mjpegOptions: -q:v 5 -r 2 -vf scale=640:-2 -update 1
  ipAddress: 192.168.1.229
  updateImageWhen: "0"
  mjpegUrl: ffmpeg
  gifPreroll: 0
  ffmpegLocation: /usr/bin/ffmpeg
  serverPort: 54321
  ipWhitelist: DISABLE
  mp4OutOptions: -c:v copy -c:a copy
  pollTime: 1000
  password: pass
  port: 80
  snapshotUrl: ffmpeg
  snapshotOptions: -an -vsync vfr -q:v 2 -update 1
  ffmpegInput: http://192.168.1.229:8080/live/mjpeg
  username: username
  hlsOutOptions: -strict -2 -f lavfi -i aevalsrc=0 -acodec aac -vcodec copy
    -hls_flags delete_segments -hls_time 2 -hls_list_size 4
  gifOutOptions: -r 2 -filter_complex
    scale=-2:360:flags=lanczos,setpts=0.5*PTS,split[o1][o2];[o1]palettegen[p];[o2]fifo[o3];[o3][p]paletteuse

Now when I try to open the stream, the log looks like this:

2021-11-28 06:58:31.593 [DEBUG] [pcamera.internal.StreamServerHandler] - Stream Server recieved request 	GET:/ipcamera.mjpeg
2021-11-28 06:58:31.595 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] - Starting ffmpeg with this command now:-f mjpeg -hide_banner -loglevel warning -i http://192.168.1.229:8080/live/mjpeg -q:v 5 -r 2 -vf scale=640:-2 -update 1 http://127.0.0.1:54321/ipcamera.jpg
2021-11-28 06:58:31.820 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] - http://192.168.1.229:8080/live/mjpeg: End of file

I tried setting snapshot url to both ffmpeg and empty, but there is no difference.

Cheers,
Marcin

I would not run it that way, since you have a mjpeg URL this is where you should give the binding the url so that it does not try and create a mjpeg stream transcoded from your already mjpeg URL.

Correct it is the same unless you have a ONVIF camera and it can auto discover the snapshot URL via onvif methods. Since your not setting up as a ONVIF thing type, then you need to supply all the URLs or tell it to use ffmpeg.

I would probably change this to 8080 since your camera is doing everything on that port. Since you have not posted any of the trace logs I am acting blind and I think it would be safer to change this in case it uses port 80 instead of the 8080 you have specified in the other fields.

Its possible these are an issue when trying to create snapshots from a mjpeg input. These will be tested with a h264 input and they may need to be changed when you have a mjpeg stream. Try making this -r 1 -update 1.

Try making this -f mjpeg -r 1 which will limit the binding to only processing 1 frame a second which you wont want snapshots any faster than that. Leaving off the -r 1 meant my arm based cpu could not reach realtime speeds with a 20fps input stream.

These options do not make sense when the input source is already mjpeg. They will waste a lot of CPU. Try -update 1 but if you give the binding the real URL to use as suggested above, then it wont try to re-encode a mjpeg stream which will only waste CPU. But I did run the test here and it is possible to do it if the -f mjpeg -r 1 suggestion above is used.

I did find a number of long standing bugs in the binding for generic cameras when I recently changed the binding over to use the new serving URLs. Since the tests I have just run are with the newer binding, I would recommend you upgrade to the newer version of the binding and then you will not have issues when the breaking change hits in 3.2 Stable which is due to be released next month. The breaking change is explained and also a jar that will work on older 3.x cores can be found in this post if you do not wish to change your core over to a milestone…

IpCamera binding - Breaking changes and new features in 3.2 Milestone 3 and newer - Add-ons / Bindings - openHAB Community

I could not find much on this error but I’ll make a guess that this may be caused by the camera not being able to supply the stream to 2 processes at the same time. What happens if you try to open http://192.168.1.229:8080/live/mjpeg in two new tabs in any browser?
If the camera can only supply 1 single stream at a time then the binding opens it to create snapshots with and this could then be blocking the use of the same URL from being used when you ask for ipcamera.mjpeg

I would not run it that way, since you have a mjpeg URL this is where you should give the binding the url so that it does not try and create a mjpeg stream transcoded from your already mjpeg URL.

I have changed mjpegUrl back to http://192.168.1.229:8080/live/mjpeg, I changed the port to 8080 as well, but, there is no difference.

The only trace I gate in the log is:

2021-11-28 09:06:46.794 [TRACE] [era.internal.handler.IpCameraHandler] - Sending camera: GET: http://192.168.1.229:8080/live/mjpeg

I didn’t think there is anything interesting in it, that’s why I didn’t send it.
It looks like the bidning can’t read the stream for some reason.

If the camera can only supply 1 single stream at a time then the binding opens it to create snapshots with and this could then be blocking the use of the same URL from being used when you ask for ipcamera.mjpeg

I tried that too, opening stream on my phone and in the browser (Edge, I tried chrome, but I read there is no support for embedded login/pass anymore).

I will look for that updated jar file and I will try installing it.

EDIT:

I have installed version 3.2 of the binding but nothing has changed.

My updated thing definition is now:

UID: ipcamera:generic:b566d3a34d
label: RTSP/HTTP IP Camera
thingTypeUID: ipcamera:generic
configuration:
  ipAddress: 192.168.1.229
  updateImageWhen: "0"
  mjpegUrl: http://192.168.1.229:8080/live/mjpeg
  gifPreroll: 0
  ffmpegLocation: /usr/bin/ffmpeg
  serverPort: 54321
  ipWhitelist: DISABLE
  mp4OutOptions: -c:v copy -c:a copy
  pollTime: 1000
  password: pass
  port: 8080
  ffmpegInput: http://192.168.1.229:8080/live/mjpeg
  username: user
  gifOutOptions: -r 2 -filter_complex
    scale=-2:360:flags=lanczos,setpts=0.5*PTS,split[o1][o2];[o1]palettegen[p];[o2]fifo[o3];[o3][p]paletteuse

Many thanks.

So instead of a RTSP cam, I used the ONVIF binding thing and this at least makes the thing go offline when I reboot the camera.

Unfortunately, the process (ffmpeg audio detection) does not restart when the ONVIF camera comes back online so that will indeed be a rule I need to create I guess (changing threshold by just a bit).

When writing this, I also tried to simply disable the thing and re-enable it, I would expect that at least the audio detection should start on Openhab/Thing startup. That also does not happen but that might be pretty simple to fix in the binding right?

In the newer version this does not exist anymore as per the post that explains the breaking change. If the logs show the binding gets the requests at the new URLs then you can just ignore it or delete this line.

Some browsers still do allow it, but will remove the user:pass from the address bar the moment you press enter. If you leave the embedded credentials out, then the browser should pop up a box asking you to enter the user and pass. If that is not happening then its possible there is a bug in the camera or the URL is wrong. You can do a CURL request on the linux command line with the --verbose option and it will show more info as to what is happening.

This thread is interesting as it shows you may have a URL for snapshots that you can use. Also the post that the mjpeg stream does not give a “Content-Length” value would cause an issue for the binding, however I can not comment on if it causes an issue for ffmpeg and if there is a work around for it if that is the case. Recommend you upgrade the firmware in case that helps.

Fibaro Intercom integration authentication issue - Issues - The Home Remote Community

If the camera goes offline then it should be easy enough to change the binding to restart it. Until then a rule that does your work around when the camera comes back online should do the trick. What happens if you keep sending the same threshold value every 10 seconds as a cron rule? Hopefully it does nothing until the camera comes back online, or does it keep restarting the detection every 10 seconds?

When creating the following rule:

when 
    Time cron "0/10 * * * * ?"
then
    ONVIFIPCamera_AudioAlarmThreshold.sendCommand(30)
end

It reboots the stream every 10 seconds.

==> /home/pi/automation/openhab-3/openhab_userdata/logs/events.log <==
2021-11-28 10:08:30.727 [INFO ] [openhab.event.ItemCommandEvent      ] - Item 'ONVIFIPCamera_AudioAlarmThreshold' received command 30
2021-11-28 10:08:30.729 [INFO ] [penhab.event.ItemStatePredictedEvent] - Item 'ONVIFIPCamera_AudioAlarmThreshold' predicted to become 30

==> /home/pi/automation/openhab-3/openhab_userdata/logs/openhab.log <==
2021-11-28 10:08:30.738 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] - Stopping ffmpeg RTSP_ALARMS now when keepalive is:8
2021-11-28 10:08:30.741 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] - Starting ffmpeg with this command now:-rtsp_transport tcp -i rtsp://user:********@192.168.2.79:88/audio -af silencedetect=n=-30dB:d=2 -vn -f null -

OK, I have removed that. I actually tried opening the new URL, but result is exactly the same. A new debug line looks like this:

2021-11-28 10:51:54.274 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] - Starting ffmpeg with this command now:-threads 1 -skip_frame nokey -hide_banner -loglevel warning -i http://192.168.1.229:8080/live/mjpeg  http://127.0.0.1:8080/ipcamera/b566d3a34d/snapshot.jpg
2021-11-28 10:51:54.515 [DEBUG] [hab.binding.ipcamera.internal.Ffmpeg] - http://192.168.1.229:8080/live/mjpeg: End of file

I tried opening that snapshot URL (after changing IP to my openhabian address), but no luck.

I tried again opening camera mjpeg stream in chrome and it works after loging in.

I also checked my firmware and it is the latest one.

I didn’t get this part. The curl --verbose shows:

openhabian@openhabian:/ $ curl http://192.168.1.229:8080/live/mjpeg --verbose
* Expire in 0 ms for 6 (transfer 0x11738b0)
*   Trying 192.168.1.229...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x11738b0)
* Connected to 192.168.1.229 (192.168.1.229) port 8080 (#0)
> GET /live/mjpeg HTTP/1.1
> Host: 192.168.1.229:8080
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 401 Unauthorized
< WWW-Authenticate: Basic realm="live-mjpeg"
* Connection #0 to host 192.168.1.229 left intact

Thank’s so much for your time!

Try curl http://user:pass@192.168.1.229:8080/live/mjpeg --verbose

The respone:

* Expire in 0 ms for 6 (transfer 0x10e28b0)
*   Trying 192.168.1.229...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x10e28b0)
* Connected to 192.168.1.229 (192.168.1.229) port 8080 (#0)
* Server auth using Basic with user ‘user'
> GET /live/mjpeg HTTP/1.1
> Host: 192.168.1.229:8080
> Authorization: Basic XYZ
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-type: multipart/x-mixed-replace; boundary=----AmbarellaBoundaryS0JIa4uHF7yHd8xJ
* no chunk, no close, no size. Assume close to signal end
<
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
* Failed writing body (0 != 5859)
* Closing connection 0

I tried using snapshot URL from fibaro, and it works in the browser, but again it doesn’t work with the bidning. I have set snapshotURL to:

http://192.168.1.229:8080/live/jpeg

but when I request snapshot from the binding, there is nothing showing and the log shows:

2021-11-28 11:14:01.112 [DEBUG] [amera.internal.servlet.CameraServlet] - GET:/ipcamera.jpg, received from 192.168.1.156
2021-11-28 11:14:01.113 [WARN ] [amera.internal.servlet.CameraServlet] - ipcamera.jpg was requested but there was no jpg in ram to send.

Cheers

Posting this line allows people to reverse your password, edit it out if you care.

I am wondering if this can be solved with ffmpegInputOptions: -f mpjpeg -r 1 as it seems ffmpeg has two demuxers and the one with the extra p may be able to ignore the missing content-length header which is what I suspect is the cause.

Does the log show what happens when it asks for the snapshot for the first time? It will do this when first connecting. If the snapshot does not contain the content-length header I’m sure the binding can handle that for snapshots, but wont handle it for the mjpeg stream. This leaves the above as a possible work around by using an older demuxer that may possibly work when a camera does that.

2021-11-28 12:42:36.798 [DEBUG] [amera.internal.servlet.CameraServlet] - GET:/ipcamera.jpg, received from 192.168.1.156
2021-11-28 12:42:36.799 [WARN ] [amera.internal.servlet.CameraServlet] - ipcamera.jpg was requested but there was no jpg in ram to send.

That’s all there is.

I am wondering if this can be solved with ffmpegInputOptions: -f mpjpeg -r

I tried that too, but I can’t see any difference in result or logs.
After all modifications, my thing config looks like this:

UID: ipcamera:generic:b566d3a34d
label: RTSP/HTTP IP Camera
thingTypeUID: ipcamera:generic
configuration:
  ipAddress: 192.168.1.229
  updateImageWhen: "0"
  mjpegUrl: http://192.168.1.229:8080/live/mjpeg
  gifPreroll: 0
  ffmpegLocation: /usr/bin/ffmpeg
  ipWhitelist: DISABLE
  mp4OutOptions: -c:v copy -c:a copy
  pollTime: 1000
  password: pass
  port: 8080
  snapshotUrl: http://192.168.1.229:8080/live/jpeg
  ffmpegInput: http://192.168.1.229:8080/live/mjpeg
  username: user
  gifOutOptions: -r 2 -filter_complex
    scale=-2:360:flags=lanczos,setpts=0.5*PTS,split[o1][o2];[o1]palettegen[p];[o2]fifo[o3];[o3][p]paletteuse
  ffmpegInputOptions: -f mpjpeg -r 1

Now I have spoted something like this in logs:

2021-11-28 12:54:30.405 [DEBUG] [amera.internal.servlet.CameraServlet] - GET:/ipcamera.mjpeg, received from 192.168.1.156
2021-11-28 12:54:30.408 [DEBUG] [amera.internal.servlet.CameraServlet] - Not the first stream requested but the stream from camera was closed
2021-11-28 12:54:30.413 [DEBUG] [amera.internal.servlet.CameraServlet] - Now there are 0 autofps.mjpeg streams open.
2021-11-28 12:54:30.413 [TRACE] [era.internal.handler.IpCameraHandler] - Sending camera: GET: http://192.168.1.229:8080/live/mjpeg
2021-11-28 12:54:30.413 [DEBUG] [amera.internal.servlet.CameraServlet] - All autofps.mjpeg streams have stopped.

can you give the output for the snapshot using curl like before?

Sure


* Expire in 0 ms for 6 (transfer 0x3e08b0)
*   Trying 192.168.1.229...
* TCP_NODELAY set
* Expire in 200 ms for 4 (transfer 0x3e08b0)
* Connected to 192.168.1.229 (192.168.1.229) port 8080 (#0)
* Server auth using Basic with user 'user'
> GET /live/jpeg HTTP/1.1
> Host: 192.168.1.229:8080
> Authorization: Basic AAABBBCCC
> User-Agent: curl/7.64.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-type: image/jpeg
* no chunk, no close, no size. Assume close to signal end
<
Warning: Binary output can mess up your terminal. Use "--output -" to tell
Warning: curl to output it to your terminal anyway, or consider "--output
Warning: <FILE>" to save to a file.
* Failed writing body (0 != 1448)
* Closing connection 0

I really need to see the full trace log of when it trys to send the request for a snapshot for the very first time. For example you may see “Setting up the camera to use Basic Auth and resending last request with correct auth.”
That will tell me which branch the code has taken and I can track it far better than guessing at what has happened. I do not see why the snapshot is not working at this point.

I guess what may be happening is that the snapshot does not give a Content-Length and then also does not close the connection. If it never closes then the binding really has no idea that the full snapshot has been sent.

curl is reporting: no chunk, no close, no size. Assume close to signal end so this may be confirmation that this is what is happening. It really looks like basic http is not being followed by the camera. Have you checked for a firmware update and contacted support?