keshavdv / unifi-cam-proxy

Enable non-Ubiquiti cameras to work with Unifi NVR
MIT License
1.65k stars 230 forks source link

Reolink jpg Still Image URL #109

Closed craggyh closed 2 years ago

craggyh commented 2 years ago

Can this proxy be modified so that it connects to the camera jpg URL for still image instead of using ffmpeg? The reason I ask is because I have 8x Reolink cameras and each copy of unifi-cam-proxy spawns an ffmpeg process (presumably for the preview snapshot) and each one consumes around 40% of a Xeon E3 2670 V2 CPU core. With 8x cameras running that's 2-3 cores of my server being consumed.

Am I correct in presuming that ffmpeg is only used for the preview image? The actual h264 stream is just passed on to Unifi Protect without any decoding/transcoding? Or does Unifi Protect actually pull the stream directly from the camera? This would make more sense if it was possible.

m3resourcesllc commented 2 years ago

Can this proxy be modified so that it connects to the camera jpg URL for still image instead of using ffmpeg? The reason I ask is because I have 8x Reolink cameras and each copy of unifi-cam-proxy spawns an ffmpeg process (presumably for the preview snapshot) and each one consumes around 40% of a Xeon E3 2670 V2 CPU core. With 8x cameras running that's 2-3 cores of my server being consumed.

Am I correct in presuming that ffmpeg is only used for the preview image? The actual h264 stream is just passed on to Unifi Protect without any decoding/transcoding? Or does Unifi Protect actually pull the stream directly from the camera? This would make more sense if it was possible.

Sorry to hijack but would you mind sharing your working config? I'm trying to get reolink cameras working but so far haven't been able to get any output, just black screen...

m3resourcesllc commented 2 years ago

Can this proxy be modified so that it connects to the camera jpg URL for still image instead of using ffmpeg? The reason I ask is because I have 8x Reolink cameras and each copy of unifi-cam-proxy spawns an ffmpeg process (presumably for the preview snapshot) and each one consumes around 40% of a Xeon E3 2670 V2 CPU core. With 8x cameras running that's 2-3 cores of my server being consumed.

Am I correct in presuming that ffmpeg is only used for the preview image? The actual h264 stream is just passed on to Unifi Protect without any decoding/transcoding? Or does Unifi Protect actually pull the stream directly from the camera? This would make more sense if it was possible.

Disclaimer, I'm not developer! More of a McGyver so please forgive this crude solution. Maybe this will serve as motivation for me to put more thought into it and learn how to submit the changes.

First off, when using this software I don't think Unifi pulls the video direct from the camera, I believe it's proxied as another set of ffmpeg streams.

But for the snapshots, take a look at rtsp.py. Lines 25 & 26 start a stream using ffmpeg in order to pull snapshots, but only if a snapshot_url isn't defined.

My quick hack: manually define it .. I added the following as a new line immediately after line 15 like this:

self.args = args (existing line 15) self.args.snapshot_url = "http://(camera-ip)/cgi-bin/api.cgi?cmd=Snap&channel=0&rs=(random-string)&user=(camera-username)&password=(testing)"

Ultimately I think a new camera definition file needs to be created (reolink.py) incorporating the snapshot URL and any other brand specific stuff that there may be. Also need to add the camera username and password as arguments elsewhere in the code so they, along with the camera IP can be used to build the URL dynamically rather than manually.

Anyway, at least with my quick edit, it did prevent an ffmpeg stream just for the snapshots... The others remain for the live video although I'm not sure why we need three of them unless it's a requirement on the Unifi side. I don't know enough about how all of this works but it seems strange to me to create three streams, all with identical ffmpeg settings and sending them all to the same IP/port. They each have a unique name so maybe Unifi can split them out but unless it's a Unifi requirement, not sure what the point of sending three identical streams is....

GhostlyCrowd commented 2 years ago

I had mentioned this as well it never got a response and stale bot closed it so i stopped trying :/ but i agree with you. If i were capable id add the proper reolink support my self but alas im not.

GhostlyCrowd commented 2 years ago

https://github.com/keshavdv/unifi-cam-proxy/issues/91#issuecomment-925902421

check out my previous dig into this.

GhostlyCrowd commented 2 years ago

Can this proxy be modified so that it connects to the camera jpg URL for still image instead of using ffmpeg? The reason I ask is because I have 8x Reolink cameras and each copy of unifi-cam-proxy spawns an ffmpeg process (presumably for the preview snapshot) and each one consumes around 40% of a Xeon E3 2670 V2 CPU core. With 8x cameras running that's 2-3 cores of my server being consumed. Am I correct in presuming that ffmpeg is only used for the preview image? The actual h264 stream is just passed on to Unifi Protect without any decoding/transcoding? Or does Unifi Protect actually pull the stream directly from the camera? This would make more sense if it was possible.

Disclaimer, I'm not developer! More of a McGyver so please forgive this crude solution. Maybe this will serve as motivation for me to put more thought into it and learn how to submit the changes.

First off, when using this software I don't think Unifi pulls the video direct from the camera, I believe it's proxied as another set of ffmpeg streams.

But for the snapshots, take a look at rtsp.py. Lines 25 & 26 start a stream using ffmpeg in order to pull snapshots, but only if a snapshot_url isn't defined.

My quick hack: manually define it .. I added the following as a new line immediately after line 15 like this:

self.args = args (existing line 15) self.args.snapshot_url = "http://(camera-ip)/cgi-bin/api.cgi?cmd=Snap&channel=0&rs=(random-string)&user=(camera-username)&password=(testing)"

Ultimately I think a new camera definition file needs to be created (reolink.py) incorporating the snapshot URL and any other brand specific stuff that there may be. Also need to add the camera username and password as arguments elsewhere in the code so they, along with the camera IP can be used to build the URL dynamically rather than manually.

Anyway, at least with my quick edit, it did prevent an ffmpeg stream just for the snapshots... The others remain for the live video although I'm not sure why we need three of them unless it's a requirement on the Unifi side. I don't know enough about how all of this works but it seems strange to me to create three streams, all with identical ffmpeg settings and sending them all to the same IP/port. They each have a unique name so maybe Unifi can split them out but unless it's a Unifi requirement, not sure what the point of sending three identical streams is....

i actually made reolink.py today and its working but im no python pro. its only spawning 2 ffmpeg streams now video 1 and video 3

If we could get closer to how the hikvision cams work and we get the proper main video stream and the low-quality sub stream for previews parsing properly, this would be beneficial for load on the proxy.

the wall im hitting is i cannot seem to be able to send the ffmpeg arguments in my camera command as it says "ffmpeg expects one argument only" so its doubling up somehow. so the only thing i have working is recording live viewing doesn't work anywhere.

appcoders commented 2 years ago

You do not need to change the source code at all.

Just use after rtsp -s rtsp://... -i http://snapshoturl

-i is a shortcut for snapshot_url

GhostlyCrowd commented 2 years ago

You do not need to change the source code at all.

Just use after rtsp -s rtsp://... -i http://snapshoturl

-i is a shortcut for snapshot_url

There is more to the reolink cameras then just using the snapshot url as well, for example hooking into the api for motion detection, and main/sub stream usage that people would like to use.

m3resourcesllc commented 2 years ago

You do not need to change the source code at all.

Just use after rtsp -s rtsp://... -i http://snapshoturl

-i is a shortcut for snapshot_url

Thanks for that, digging through the code I missed it and don't think I saw it documented.

m3resourcesllc commented 2 years ago

You do not need to change the source code at all. Just use after rtsp -s rtsp://... -i http://snapshoturl -i is a shortcut for snapshot_url

There is more to the reolink cameras then just using the snapshot url as well, for example hooking into the api for motion detection, and main/sub stream usage that people would like to use.

All of that would be fantastic. Unfortunately I still don't have a single working camera. I do get the snapshots (whether by ffmpeg or snapshot URL) but no video. I can't even get the Big Buck Bunny video to work. Would you mind sharing your details to see if I can match up to at least get video? proxy version, ffmepg settings, etc?

WaaromZoMoeilijk commented 2 years ago

Same here on Reolink cameras, only a still image and endless loading. The error messages do not reveal anything fixable at this time.

I've setup a systemd service for each camera on an LXC Ubuntu container running unifi-cam-proxy.

If i uncover more i'll come back.

Edit: Tried it with both reolinknvr at channel 0, also works, but only a stale image, does refresh every few seconds though.

Edit 2 It also seems that it keeps switching between the main and sub stream very fast every few seconds, and then becomes unavailable for a few milliseconds

root@UnifiCamProxy:~# unifi-cam-proxy -H 192.168.X.X --mac 'AA:BB:LO:LO:LO:LO' -i 192.168.X.X -c client.pem -t TOKEN reolink_nvr -u admin -p password -c 0

root@UnifiCamProxy:~# cat /etc/systemd/system/*cam.service

[Unit]
Description=FrontCamProxy
After=network.target

[Service]
User=root
ExecStart=/usr/local/bin/unifi-cam-proxy --mac '00:00:13:37:00:00' -H 192.168.X.X -i 192.168.X.X -t TOKEN -c client.pem rtsp -s rtsp://admin:password@192.168.X.X:554/h264Preview_01_main --ffmpeg-args '-c:v copy -vbsf "h264_metadata=tick_rate=60000/1001:fixed_frame_rate_flag=1" -ar 32000 -ac 2 -codec:a aac -b:a 32k'
WorkingDirectory=/root
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=FrontCamProxy
Restart=always

[Install]
WantedBy=multi-user.target
[Unit]
Description=FrontCamProxy
After=network.target

[Service]
User=root
ExecStart=/usr/local/bin/unifi-cam-proxy --mac '00:00:73:31:00:00' -H 192.168.X.X -i 192.168.X.X -t TOKEN -c client.pem rtsp -s rtsp://admin:password@192.168.X.X:554/h264Preview_01_main --ffmpeg-args '-c:v copy -vbsf "h264_metadata=tick_rate=60000/1001:fixed_frame_rate_flag=1" -ar 32000 -ac 2 -codec:a aac -b:a 32k'
WorkingDirectory=/root
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=FrontCamProxy
Restart=always

[Install]
WantedBy=multi-user.target

DeepinScreenshot_select-area_20211112003725

m3resourcesllc commented 2 years ago

You do not need to change the source code at all.

Just use after rtsp -s rtsp://... -i http://snapshoturl

-i is a shortcut for snapshot_url

Agreed,

I did a quick check to see if it was an argument that could be passed and missed it...

m3resourcesllc commented 2 years ago

Same here on Reolink cameras, only a still image and endless loading. The error messages do not reveal anything fixable at this time.

I've setup a systemd service for each camera on an LXC Ubuntu container running unifi-cam-proxy.

If i uncover more i'll come back.

Edit: Tried it with both reolinknvr at channel 0, also works, but only a stale image, does refresh every few seconds though.

Edit 2 It also seems that it keeps switching between the main and sub stream very fast every few seconds, and then becomes unavailable for a few milliseconds

root@UnifiCamProxy:~# unifi-cam-proxy -H 192.168.X.X --mac 'AA:BB:LO:LO:LO:LO' -i 192.168.X.X -c client.pem -t TOKEN reolink_nvr -u admin -p password -c 0

root@UnifiCamProxy:~# cat /etc/systemd/system/*cam.service

[Unit]
Description=FrontCamProxy
After=network.target

[Service]
User=root
ExecStart=/usr/local/bin/unifi-cam-proxy --mac '00:00:13:37:00:00' -H 192.168.X.X -i 192.168.X.X -t TOKEN -c client.pem rtsp -s rtsp://admin:password@192.168.X.X:554/h264Preview_01_main --ffmpeg-args '-c:v copy -vbsf "h264_metadata=tick_rate=60000/1001:fixed_frame_rate_flag=1" -ar 32000 -ac 2 -codec:a aac -b:a 32k'
WorkingDirectory=/root
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=FrontCamProxy
Restart=always

[Install]
WantedBy=multi-user.target
[Unit]
Description=FrontCamProxy
After=network.target

[Service]
User=root
ExecStart=/usr/local/bin/unifi-cam-proxy --mac '00:00:73:31:00:00' -H 192.168.X.X -i 192.168.X.X -t TOKEN -c client.pem rtsp -s rtsp://admin:password@192.168.X.X:554/h264Preview_01_main --ffmpeg-args '-c:v copy -vbsf "h264_metadata=tick_rate=60000/1001:fixed_frame_rate_flag=1" -ar 32000 -ac 2 -codec:a aac -b:a 32k'
WorkingDirectory=/root
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=FrontCamProxy
Restart=always

[Install]
WantedBy=multi-user.target

DeepinScreenshot_select-area_20211112003725

I'm still trying to get everything working but I've made progress... I think I had multiple issues going on.

First, be careful about the characters used in the camera password. I had a "$" in mine and it doesn't get escaped properly.

So far I've been trying with docker. I didn't want to dig out another piece of hardware to test with so I gave it a go from Linux on my Chromebook... Installed python, ffmpeg, netcat, git cloned the proxy. It still didn't work, no video. I kept messing with it and it started working. How/why? I'm not entirely sure but I did create another user on the camera besides "admin" and it could be coincidence but after updating with the new user/pass it is now working from my Chromebook. Long shot but maybe there is something funky using the admin user?

Anyway, I can now consistently get video when running from my Chromebook but toggling back over to docker, even with the same command line settings doesn't work. I also switched from bridge to host networking without success. I did that wondering if ports need to be exposed but it's not obvious to me that it's needed.

I'm pulling the image right from GitHub, I may try creating my own to follow the same steps I did on the Chromebook to create an image

WaaromZoMoeilijk commented 2 years ago

Thanks for the feedback.

I'm running natively via pip.

Also tried another user on the CAMs (non admin user) but still the same unfortunately.

this is the output when i run the command by hand: https://hastebin.waaromzomoeilijk.nl/kawecofewu.rb Nothing in there that raises any bells.

I've made sure everything is reachable firewall wise and also tested

when running: ffmpeg -nostdin -y -stimeout 15000000 -rtsp_transport tcp -i "rtsp://user:password@10.0.10.11:554/h264Preview_01_main" -c:v copy -vbsf "h264_metadata=tick_rate=60000/1001:fixed_frame_rate_flag=10" -ar 32000 -ac 2 -codec:a aac -b:a 32k -metadata streamname=VmhOadfasdfasdfP -f flv - | /usr/bin/python3 -m unifi.clock_sync | nc 10.0.10.1 7550 I do get the live stream parameters like FPS and bitrate that keep changing as would a live stream. Just doesn't reflect in the webui.

It also seems that the command : ffmpeg -nostdin -y -re -rtsp_transport tcp -i "rtsp://user:password@10.0.10.11:554/h264Preview_01_main" -vf fps=1 -update 1 /tmp/tmpaasdfanr/screen.jpg keeps overwriting the file and subsequently refreshes in the UI (as per parameters fps 1 and update every second, i guess)

I'll keep digging, would love to tackle this problem.

stale[bot] commented 2 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.