Before I purchased a hardware based NVR, I was using some enterprise NVR software and an older MJPEG camera as well as a 720p USB webcam. MJPEG = Motion JPEG. MJPEG was pretty common on older cameras / cloud cameras / consumer items. My Hik NVR only supports RTSP streams though - so these cameras aren't compatible (out of the box at least).
Transcoding (realtime conversion from one video format to another) was the only way I saw around this. I spent a good portion of the weekend researching potential options. What I found is that my use case is probably a little unique, generally speaking.
I was looking for software do do three basic things:
It was pretty clear that I was probably looking at one piece of software to transcode and a separate software solution to serve the streams to clients. FFMPEG is very popular for transcoding, supports all major formats, and is actually the backend used by several NVR software vendors (including some enterprise NVR sw). I was also able to find a basic RTSP media server (opensource perl script).
I went with:
FFMPEG is relatively easy to get going - download the latest zip file, extract, and ffmpeg.exe can be found in the bin folder. If you are using Linux, you can do the same (or just install ffmpeg with whatever pacakge management app your OS uses).
RTSP-Server is linux only. I was not able to find anything suitable (or free) for the Windows platform. RTSP server is super easy to build and required zero configuration - literally install it and run the script. Script can be launched as a bg process with the usual & at the end of the command. I wrote my own init script so that it spawns the RTSP-Server (media server) at startup.
I used a general purpose linux machine to host the RTSP-Server (media server) and I used a Windows VM (w/usb camera attached) for FFMPEG (transcoding). RTSP-Server listens for media (from the transcoder) on port 5545 and listens for clients (NVR, etc) on the standard RTSP port (554).
Commandline for transcoding MJPEG (url) to RTSP:
Commandline for transcoding directshow (USB device/webcam) to RTSP:
Thinking a little more broadly, it seems that you could likely use similar methods to have FFMPEG transcode video from a video capture device, TV tuner, etc. It's probably worth noting that VLC can also be used to transcode to rtsp. I am not transcoding audio from the webcam - but it could be done with a few additional commandline options.
The USB camera transcoding process uses ~10% of CPU and transcoding MJPEG uses around 5%. Combined total is less than half the CPU usage I saw when using NVR software to do the work. A fair amount of tweaking was required with FFMPEG commands to optimize the stream for the NVR. Initially I was seeing huge delays (1-2m) when the cameras were pulled up on the live view and they wouldn't stream through hik-connect at all.
I also ran into an issue with the MJPEG camera. Apparently it doesn't completely adhere to MJPEG standards. Probably not an issue with all cameras, but the result was that FFMPEG would randomly die due to "invalid stream data". I ended up creating a batch file loop to respawn the transcoder automatically.
Example of batch file loop:
On the NVR side (hikvision), I setup a custom protocol for each camera - pointing to proper url/ports/etc. The RTSP-Server is UDP only, so I specified that when setting up the protocol. Outside of this, one camera had the url "/livingroom" and the other had the url "/garage". As an example, in VLC the full URL would be rtsp:/rtsp_server_address/livingroom. Once the protocols were added I added each camera, set the proper protocol, and entered the address of my RTSP server.
Everything has been working smoothly for the last 24-48 hours. I'm doing continuous recording on these two channels since it's just an RTSP stream (no ONVIF event support, for motion etc). If I have some free time (before I end up replacing these two cams), I'll probably start looking into ONVIF emulation options.
This project looks pretty interesting, maybe a good starting point:
How to Turn an USB Camera With Raspberry Pi Into an Onvif IP Camera?
Transcoding (realtime conversion from one video format to another) was the only way I saw around this. I spent a good portion of the weekend researching potential options. What I found is that my use case is probably a little unique, generally speaking.
I was looking for software do do three basic things:
- Pull the MJPEG stream (or directshow device video)
- Transcode it to RTSP/h264
- Serve it to the network/NVR
It was pretty clear that I was probably looking at one piece of software to transcode and a separate software solution to serve the streams to clients. FFMPEG is very popular for transcoding, supports all major formats, and is actually the backend used by several NVR software vendors (including some enterprise NVR sw). I was also able to find a basic RTSP media server (opensource perl script).
I went with:
- FFMPEG - pull video streams (url or local), transcode to proper format, push to media server
FFmpeg
- RTSP-Server - receive data from FFMPEG and serve the content to clients on the network
revmischa/rtsp-server
FFMPEG is relatively easy to get going - download the latest zip file, extract, and ffmpeg.exe can be found in the bin folder. If you are using Linux, you can do the same (or just install ffmpeg with whatever pacakge management app your OS uses).
RTSP-Server is linux only. I was not able to find anything suitable (or free) for the Windows platform. RTSP server is super easy to build and required zero configuration - literally install it and run the script. Script can be launched as a bg process with the usual & at the end of the command. I wrote my own init script so that it spawns the RTSP-Server (media server) at startup.
I used a general purpose linux machine to host the RTSP-Server (media server) and I used a Windows VM (w/usb camera attached) for FFMPEG (transcoding). RTSP-Server listens for media (from the transcoder) on port 5545 and listens for clients (NVR, etc) on the standard RTSP port (554).
Commandline for transcoding MJPEG (url) to RTSP:
Code:
ffmpeg -i http://admin:admin@camera_ip_address/goform/video -pix_fmt yuv420p -vcodec libx264 -maxrate 1M -bufsize 2M -tune zerolatency -preset faster -r 5 -f rtsp rtsp:/rtsp_server_address:5545/garage
Commandline for transcoding directshow (USB device/webcam) to RTSP:
Code:
ffmpeg -f dshow -framerate 5 -video_size 1280x720 -i video="B525 HD Webcam" -pix_fmt yuv420p -vcodec libx264 -maxrate 1M -bufsize 3M -tune zerolatency -preset faster -f rtsp rtsp:/rtsp_server_address:5545/livingroom
Thinking a little more broadly, it seems that you could likely use similar methods to have FFMPEG transcode video from a video capture device, TV tuner, etc. It's probably worth noting that VLC can also be used to transcode to rtsp. I am not transcoding audio from the webcam - but it could be done with a few additional commandline options.
The USB camera transcoding process uses ~10% of CPU and transcoding MJPEG uses around 5%. Combined total is less than half the CPU usage I saw when using NVR software to do the work. A fair amount of tweaking was required with FFMPEG commands to optimize the stream for the NVR. Initially I was seeing huge delays (1-2m) when the cameras were pulled up on the live view and they wouldn't stream through hik-connect at all.
I also ran into an issue with the MJPEG camera. Apparently it doesn't completely adhere to MJPEG standards. Probably not an issue with all cameras, but the result was that FFMPEG would randomly die due to "invalid stream data". I ended up creating a batch file loop to respawn the transcoder automatically.
Example of batch file loop:
Code:
@echo off
:loop
ffmpeg -i http://admin:admin@camera_ip_address/goform/video -pix_fmt yuv420p -vcodec libx264 -maxrate 1M -bufsize 2M -tune zerolatency -preset faster -r 5 -f rtsp rtsp:/rtsp_server_address:5545/garage
goto loop
pause
On the NVR side (hikvision), I setup a custom protocol for each camera - pointing to proper url/ports/etc. The RTSP-Server is UDP only, so I specified that when setting up the protocol. Outside of this, one camera had the url "/livingroom" and the other had the url "/garage". As an example, in VLC the full URL would be rtsp:/rtsp_server_address/livingroom. Once the protocols were added I added each camera, set the proper protocol, and entered the address of my RTSP server.
Everything has been working smoothly for the last 24-48 hours. I'm doing continuous recording on these two channels since it's just an RTSP stream (no ONVIF event support, for motion etc). If I have some free time (before I end up replacing these two cams), I'll probably start looking into ONVIF emulation options.
This project looks pretty interesting, maybe a good starting point:
How to Turn an USB Camera With Raspberry Pi Into an Onvif IP Camera?