wyzecam icon indicating copy to clipboard operation
wyzecam copied to clipboard

Feed Wyze stream into RTMP server

Open noelhibbard opened this issue 3 years ago • 37 comments

I was trying to find a way to serv frames as an RTMP stream in pure Python but didn't have any luck. So I decided to fire up my own RTMP server and then leverage ffmpeg to stream to this server.

So using this guide I spun up an RTMP server using Nginx and the RTMP module: https://obsproject.com/forum/resources/how-to-set-up-your-own-private-rtmp-server-using-nginx.50/

Then I wrote a program to pipe the raw Wyze frames into ffmpeg which then streams to my RTMP server. I'm not a Python developer so I'm open to suggestions on making it more robust but it's working and seems to survive connection loss or a power cycle of the camera. I made a systemd service to run it as a service on my Debian server and it's working well. I was then able to feed it into Frigate.

from wyzecam import get_camera_list, get_user_info, login
from wyzecam.iotc import WyzeIOTC
import getopt, sys, signal, subprocess
from time import sleep

def main():

    def handler(signum, frame):
        sys.exit()

    signal.signal(signal.SIGINT, handler)

    try:
        opts, args = getopt.getopt(sys.argv[1:], "", ["user=", "password=", "cameraname=", "url="])
    except getopt.GetoptError as err:
        print("--user=<wyzeuser> --password=<wyzepassword> --cameraname=<cameraname> --url=<rtmpServerUrl>")
        sys.exit(2)

    user = None
    password = None
    cameraname = None
    rtmpurl = None

    for opt, arg in opts:
        if opt == "--user":
            user = arg
        if opt == "--password":
            password = arg
        if opt == "--cameraname":
            cameraname = arg
        if opt == "--url":
            rtmpurl = arg
    if user == None or password == None or cameraname == None or rtmpurl == None:
        print("--user=<wyzeuser> --password=<wyzepassword> --cameraname=<cameraname> --url=<rtmpServerUrl>")
        sys.exit(2)
        
    auth_info = login(user, password)
    account = get_user_info(auth_info)
    cameras = get_camera_list(auth_info)

    cam = [camera for camera in cameras if camera.nickname == cameraname][0]

    ffmpeg = subprocess.Popen(['ffmpeg',
        '-f', 'h264',
        '-i', '-',
        '-vcodec', 'copy', 
        '-f','flv', rtmpurl], stdin=subprocess.PIPE)

    while True:
        with WyzeIOTC() as wyze_iotc:
            try:
                with wyze_iotc.connect_and_auth(account, cam) as sess:
                    session_info = sess.session_check()
                    for (frame, frame_info) in sess.recv_video_data():
                        ffmpeg.stdin.write(frame)
            except:
                print("Reconnect")
        sleep(1)

if __name__ == "__main__":
    main()

Example command line:

python rtmp.py --user [email protected] --password blablabla --cameraname "Front Porch" --url rtmp://127.0.0.1/live/frountporch

Then playback using a URL like this: rtmp://myserver.example.com/live/frountporch

noelhibbard avatar Jun 21 '21 20:06 noelhibbard

I haven't tried yet but it looks like you can configure Nginx to create an HLS stream from an RTMP feed. So if you have an NVR that doesn't handle RTMP but does handle HLS then this should be doable too.

noelhibbard avatar Jun 21 '21 20:06 noelhibbard

Look, no lag at all on the stream in Frigate: https://i.imgur.com/B8TnLCm.jpg

noelhibbard avatar Jun 22 '21 01:06 noelhibbard

Here are some streamlined instructions:

Install Python 3

sudo apt-get install python3.8 python3.8-pip python3.8-venv -y

Create venv

python3.8 -m venv ~/wyze-to-rtmp
cd ~/wyze-to-rtmp
source bin/activate

Install dependencies

pip install wyzecam
pip install requests

Download wyze-to-rtmp.py

wget https://gist.github.com/noelhibbard/02870a26dda8d120f0a5b6f646677280/raw/c782883d05b268b4cc94d905b627fb441470570f/wyze-to-rtmp.py

Run wyze-to-rtmp.py

python wyze-to-rtmp.py --user [email protected] --password blablabla --cameraname "Front Porch" --url rtmp://127.0.0.1/live/frontporch

If you aren't currently in the venv (for example you closed your shell) you can execute it this way to run it in the venv:

~/wyze-to-rtmp/bin/python ~/wyze-to-rtmp/wyze-to-rtmp.py --user [email protected] --password blablabla --cameraname "Front Porch" --url rtmp://127.0.0.1/live/frontporch

Example systemd service file if you want it to run as a service. Adjust paths accordingly.

[Unit]
Description=FrontPorch
After=network.target
Wants=network-online.target

[Service]
ExecStart=/root/wyze-to-rtmp/bin/python /root/wyze-to-rtmp/wyze-to-rtmp.py --user [email protected] --password blablabla --cameraname "Front Porch" --url rtmp://127.0.0.1/live/frontporch
Restart=always
KillMode=process
Type=idle

[Install]
WantedBy=multi-user.target

Install systemd service file which you created above

systemctl enable /full/path/to/wyze-to-rtmp.service
systemctl start wyze-to-rtmp

noelhibbard avatar Jun 24 '21 06:06 noelhibbard

I created a gist here with details on running it as a systemd service using config files so you can easily create multiple services for multiple cameras.

https://gist.github.com/noelhibbard/03703f551298c6460f2fd0bfdbc328bd#file-readme-md

noelhibbard avatar Jun 24 '21 15:06 noelhibbard

@noelhibbard you didn't have to do anything else to get no latency? I set it up as above (thanks!) but I get ~6s of latency best case. I'm seeing the latency with ffplay/vlc/totem/zoneminder.

pygmymarmoset avatar Jun 25 '21 04:06 pygmymarmoset

Made it here! nginx is running Downloaded wyze-to-rtmp, created venv, installed dependencies and executed from command line and got this:

wyzetest) ron@ToshibaWin7-Ubuntu:~/wyze-to-rtmp$ /home/ron/wyze-to-rtmp/bin/python /home/ron/wyze-to-rtmp/wyze-to-rtmp.py --user [my username] --password [my password] --cameraname "WyzeCam301" --url rtmp://127.0.0.1/live/wyzecam301 ffmpeg version 4.2.4-1ubuntu0.1 Copyright (c) 2000-2020 the FFmpeg developers built with gcc 9 (Ubuntu 9.3.0-10ubuntu2) configuration: --prefix=/usr --extra-version=1ubuntu0.1 --toolchain=hardened --libdir=/usr/lib/x86_64-linux-gnu --incdir=/usr/include/x86_64-linux-gnu --arch=amd64 --enable-gpl --disable-stripping --enable-avresample --disable-filter=resample --enable-avisynth --enable-gnutls --enable-ladspa --enable-libaom --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libcdio --enable-libcodec2 --enable-libflite --enable-libfontconfig --enable-libfreetype --enable-libfribidi --enable-libgme --enable-libgsm --enable-libjack --enable-libmp3lame --enable-libmysofa --enable-libopenjpeg --enable-libopenmpt --enable-libopus --enable-libpulse --enable-librsvg --enable-librubberband --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libspeex --enable-libssh --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx265 --enable-libxml2 --enable-libxvid --enable-libzmq --enable-libzvbi --enable-lv2 --enable-omx --enable-openal --enable-opencl --enable-opengl --enable-sdl2 --enable-libdc1394 --enable-libdrm --enable-libiec61883 --enable-nvenc --enable-chromaprint --enable-frei0r --enable-libx264 --enable-shared libavutil 56. 31.100 / 56. 31.100 libavcodec 58. 54.100 / 58. 54.100 libavformat 58. 29.100 / 58. 29.100 libavdevice 58. 8.100 / 58. 8.100 libavfilter 7. 57.100 / 7. 57.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 5.100 / 5. 5.100 libswresample 3. 5.100 / 3. 5.100 libpostproc 55. 5.100 / 55. 5.100 Input #0, h264, from 'pipe:': Duration: N/A, bitrate: N/A Stream #0:0: Video: h264 (Main), yuv420p(tv, bt709, progressive), 1920x1080, 20 fps, 20 tbr, 1200k tbn, 40 tbc rtmp://127.0.0.1/live/wyzecam301: Input/output error

nginix is running as far as I can see.

root 12160 0.0 0.0 15772 872 ? Ss 19:47 0:00 nginx: master process ./nginx nobody 12161 0.0 0.0 16404 3364 ? S 19:47 0:00 nginx: worker process nobody 12162 0.0 0.0 16404 3780 ? S 19:47 0:00 nginx: worker process nobody 12163 0.0 0.0 16188 3436 ? S 19:47 0:00 nginx: cache manager process

Any config I need to do on nginix side?

SomebodySysop avatar Jun 25 '21 05:06 SomebodySysop

OK, finally got it to work.

My url would be rtmp://127.0.0.1/show/wyzecam301 (according to my nginx configuration file)

Thus, my http output is: http://localhost:8080/hls/wyzecam301.m3u8

Now, to get this thing to run as a service -- and figure out how to output an rtsp stream! That would be an nginx issue.

Thanks much for ALL the help!

SomebodySysop avatar Jun 25 '21 06:06 SomebodySysop

@noelhibbard you didn't have to do anything else to get no latency? I set it up as above (thanks!) but I get ~6s of latency best case. I'm seeing the latency with ffplay/vlc/totem/zoneminder.

I have about 6s when playing in VLC simply because it creates a big buffer. I had lag in homebridge at first but not in Frigate so I studied the ffmpeg options that Frigate was using and noticed this one "-fflags nobuffer". So I added that to my homebridge-camera-ffmpeg plugin and it did the trick.

Speaking of latency. I've been really impressed with Frigate. It sends MQTT event messages so I wrote a nodejs app that subscribes to the events and then sends a Telegram message to a group which includes some basic details along with a thumbnail of the motion. I can sit in my drive way and my phone will ding the second a car enters my peripheral vision. It's literally instant. It amazes me that there are so many layers to this and still no lag.

Wyze Cam V3>kroo/wyzecam>Nginx>frigate>motion detector>mqtt>telegram>iPhone

noelhibbard avatar Jun 25 '21 10:06 noelhibbard

OK, finally got it to work.

My url would be rtmp://127.0.0.1/show/wyzecam301 (according to my nginx configuration file)

Thus, my http output is: http://localhost:8080/hls/wyzecam301.m3u8

Now, to get this thing to run as a service -- and figure out how to output an rtsp stream! That would be an nginx issue.

Thanks much for ALL the help!

If you're looking to create a service out of the kroo/wyzecam side of things then follow the directions in my gist here: https://gist.github.com/noelhibbard/03703f551298c6460f2fd0bfdbc328bd#file-readme-md

Not sure how familiar you are with systemd services but the instructions in my gist should give you some hints into also getting Nginx setup as a systemd service.

The most common mistake I make with systemd when trying to enable a new service file I've created is not using a full path.

For example this wouldn't work:

systemctl enable ./blblbla.service

But this would:

systemctl enable /full/path/to/blblbla.service

Just a little hint because you will probably find an example Nginx service file with Google and not know how to use it.

noelhibbard avatar Jun 25 '21 10:06 noelhibbard

thanks for posting a working script to use on non-hacked firmware!! I use the FiveLeavesLeft/WyzeCameraLiveStream which isn't the best method however since the output can be piped into cvlc ( command line vlc ) using one command I don't need to build another restreamer... cvlc -vvv http://[camera IP]:12345 --sout ‘#rtp{sdp=rtsp://:8554/}’ --demux h264 ... I tried using python scripts w gstreamer but was unsuccessful . with the rtsp stream from cvlc I have both Synology Surveillance station and Home Assistant pulling the stream in ... my only issue and question here... does this [ WyzeIOTC() as wyze_iotc ] contain any audio streams from the WyzeCams??

rickgitdone avatar Jun 25 '21 12:06 rickgitdone

Hi was wondering if someone could point me in the right direction.

Trying to run the last command but get the following error:

Input #0, h264, from 'pipe:': Duration: N/A, bitrate: N/A Stream #0:0: Video: h264 (Main), yuv420p(tv, bt709, progressive), 1920x1080, 20 fps, 20 tbr, 1200k tbn, 40 tbc [tcp @ 0x55d37055cc00] Connection to tcp://127.0.0.1:1935 failed: Connection refused [rtmp @ 0x55d37066c540] Cannot open connection tcp://127.0.0.1:1935 rtmp://127.0.0.1/driveway: Connection refused Reconnect Reconnect

Also tried changing to the local ip address but not luck.

Thanks

musseilm avatar Jun 25 '21 16:06 musseilm

thanks for posting a working script to use on non-hacked firmware!! I use the FiveLeavesLeft/WyzeCameraLiveStream which isn't the best method however since the output can be piped into cvlc ( command line vlc ) using one command I don't need to build another restreamer... cvlc -vvv http://[camera IP]:12345 --sout ‘#rtp{sdp=rtsp://:8554/}’ --demux h264 ... I tried using python scripts w gstreamer but was unsuccessful . with the rtsp stream from cvlc I have both Synology Surveillance station and Home Assistant pulling the stream in ... my only issue and question here... does this [ WyzeIOTC() as wyze_iotc ] contain any audio streams from the WyzeCams??

No sound unfortunately. Looking at the TUTK library it looks like sound is possible I just don't think it was implemented in kroo/wyzecam.

noelhibbard avatar Jun 25 '21 16:06 noelhibbard

Hi was wondering if someone could point me in the right direction.

Trying to run the last command but get the following error:

Input #0, h264, from 'pipe:': Duration: N/A, bitrate: N/A Stream #0:0: Video: h264 (Main), yuv420p(tv, bt709, progressive), 1920x1080, 20 fps, 20 tbr, 1200k tbn, 40 tbc [tcp @ 0x55d37055cc00] Connection to tcp://127.0.0.1:1935 failed: Connection refused [rtmp @ 0x55d37066c540] Cannot open connection tcp://127.0.0.1:1935 rtmp://127.0.0.1/driveway: Connection refused Reconnect Reconnect

Also tried changing to the local ip address but not luck.

Thanks

That URL just needs to point to your RTMP server. Do you have one running? By the output I'm assuming not.

noelhibbard avatar Jun 25 '21 16:06 noelhibbard

OK, finally got it to work.

My url would be rtmp://127.0.0.1/show/wyzecam301 (according to my nginx configuration file)

Thus, my http output is: http://localhost:8080/hls/wyzecam301.m3u8

Now, to get this thing to run as a service -- and figure out how to output an rtsp stream! That would be an nginx issue.

Thanks much for ALL the help!

You should enable RTMP output on your Nginx server. HLS is great for playback in a browser but I'm not sure how well it would work in NVRs. I could be wrong but I think it would add some lag compared to RTMP. I have my server setup to do HLS and RTMP but I feed the RTMP feed into my NVR and just use the HLS stream for easy access in a browser or on my iPhone.

noelhibbard avatar Jun 25 '21 17:06 noelhibbard

Hi was wondering if someone could point me in the right direction. Trying to run the last command but get the following error: Input #0, h264, from 'pipe:': Duration: N/A, bitrate: N/A Stream #0:0: Video: h264 (Main), yuv420p(tv, bt709, progressive), 1920x1080, 20 fps, 20 tbr, 1200k tbn, 40 tbc [tcp @ 0x55d37055cc00] Connection to tcp://127.0.0.1:1935 failed: Connection refused [rtmp @ 0x55d37066c540] Cannot open connection tcp://127.0.0.1:1935 rtmp://127.0.0.1/driveway: Connection refused Reconnect Reconnect Also tried changing to the local ip address but not luck. Thanks

That URL just needs to point to your RTMP server. Do you have one running? By the output I'm assuming not.

Thanks! Got it working much appreciated.

musseilm avatar Jun 25 '21 17:06 musseilm

You should enable RTMP output on your Nginx server. HLS is great for playback in a browser but I'm not sure how well it would work in NVRs. I could be wrong but I think it would add some lag compared to RTMP. I have my server setup to do HLS and RTMP but I feed the RTMP feed into my NVR and just use the HLS stream for easy access in a browser or on my iPhone.

How do I do that?

Also, you wouldn't happen to know how to enable RTSP output from nginx?

SomebodySysop avatar Jun 25 '21 18:06 SomebodySysop

@SomebodySysop RTMP playback is enabled by default but if I had to guess you used the same install instructions I did which has a line that blocks playback.

This is the line in the application section: deny play all

The Nginx RTMP module doesn't support RTSP but I haven't come across anything that supports RTSP that doesn't also support RTMP.

noelhibbard avatar Jun 25 '21 18:06 noelhibbard

The Nginx RTMP module doesn't support RTSP but I haven't come across anything that supports RTSP that doesn't also support RTMP.

OK, thanks. I removed the "deny play all" line.

I've been using ContaCam which is basically freeware, but if this works I could go back to iSpy for which I still have a license.

What url format to I connect to rtmp output stream? What url format do you use?

SomebodySysop avatar Jun 25 '21 18:06 SomebodySysop

The Nginx RTMP module doesn't support RTSP but I haven't come across anything that supports RTSP that doesn't also support RTMP.

OK, thanks. I removed the "deny play all" line.

I've been using ContaCam which is basically freeware, but if this works I could go back to iSpy for which I still have a license.

What url format to I connect to rtmp output stream? What url format do you use?

The play stream is the same URL which you used to publish.

Above you said your publish URL was rtmp://127.0.0.1/show/wyzecam301. So your play URL would also be rtmp://127.0.0.1/show/wyzecam301. Of course the IP would probably need to be changed to the IP of the server rather than loopback assuming you aren't playing back on the actual server.

noelhibbard avatar Jun 25 '21 20:06 noelhibbard

Above you said your publish URL was rtmp://127.0.0.1/show/wyzecam301. So your play URL would also be rtmp://127.0.0.1/show/wyzecam301. Of course the IP would probably need to be changed to the IP of the server rather than loopback assuming you aren't playing back on the actual server.

Got it. Thanks! Good to go. Just need software that supports rtmp and then we'll see how this thing works! Waiting to hear back from ispy if they support it. Contacam doesn't.

But anyway, you've been a huge help! Thanks so much for this contribution.

SomebodySysop avatar Jun 25 '21 20:06 SomebodySysop

Shinobi and Frigate are options that both support rtmp. They both leverage ffmpeg for input so they will accept just about anything kind of stream. Shinobi is more difficult to set up. I'm using Frigate myself and it's working really well. It's in a docker and easy to deploy. It does object detection and supports the Google Coral EdgeTPU to offload the AI. My old slow 3rd gen i5 runs about 15% with the Coral doing the heavy lifting. I got the USB version which was about $70. Frigate supports multiple Corals if you have lots of cameras. From what I read it can do about 100fps and if you're only feeding 5fps to the detector that would let you handle 20 cameras. That's assuming there is movement on all 20 at the same time. Frigate also has an MQTT interface so it's easy to interface with other software. It's nice to not get random notifications because of a tree blowing. It's still important to mask out trees so that the Coral isn't busy all the time. It also integrates with Home Assistant but has a simple webui if your not running HA.

https://github.com/blakeblackshear/frigate

noelhibbard avatar Jun 26 '21 00:06 noelhibbard

OK, looked briefly at the documentation. corals sound cool, no problem. I'm not running HA. But it says Frigate requires MQTT server, a docker container and a HaasAddon -- none of which I ever even heard of before today. And you say Shinobi is even more difficult?

SomebodySysop avatar Jun 26 '21 00:06 SomebodySysop

OK, looked briefly at the documentation. corals sound cool, no problem. I'm not running HA. But it says Frigate requires MQTT server, a docker container and a HaasAddon -- none of which I ever even heard of before today. And you say Shinobi is even more difficult?

A Docker Container is a way for people to distribute programs in a virtualized container along with all the dependencies. Docker fixes the problem where two programs have the same dependency but two different versions. It's not like the old days where you have to install and configure a gazillion different services just to run a program. You no longer run apt upgrade and then end up with some services broken. Everything in the container is isolated.

Home Assistant (HA) is a home automation platform that has a plugin system.

MQTT (Message Queueing Telemetry Transport) is a server for sending and receiving messages. It's used as a sort of universal way for various services to communicate with each other. It's become extremely popular and the sort of thing every Linux server should have as a bare minimum.

So there are two ways to install Frigate, as an HA addon. or Docker. If you aren't already running HA and don't plan to, then Docker is the way to go and because you aren't running HA then MQTT isn't really needed either because Frigate mostly uses it to talk to HA.

So all you really need to do is create a Frigate config file, create a folder for the Frigate data and then create a docker-compose config file that explains what container to download and how to map the folders in the container to the actual folders on your server. Then you just run this command from the folder where you docker-compose.yml file is: docker-compose up -d So once you have docker and docker compose installed you just create a folder to store your recordings, create a docker-compose.yml file and a frigate config file. The docker-compose.yml file is basically a config file for the container where you tell it how to map ports and folders. After that you just type:

docker-compose up -d

That's it. Now it's running as a service and will survive reboots.

Here is some info on installing Docker: https://docs.docker.com/engine/install/ubuntu/

You also want to be sure you install docker-compose. Once you have the docker repo setup you can install it like this: apt install docker-compose

Once docker and docker-compose are installed, head over here for the Frigate install instructions: https://blakeblackshear.github.io/frigate/installation

If you decide you don't want to run Frigate anymore you just stop and delete the container and then delete the images. It's a learning curve but not bad. Once you know how to use docker you will be able to spin up all sorts of services with zero risk of trashing your system.

noelhibbard avatar Jun 26 '21 07:06 noelhibbard

@noelhibbard couple suggestions after doing this a few times:

for debian buster, python 3.8 packages are available here for amd64 and arm (32 and 64 bit) platforms: https://community.home-assistant.io/t/home-assistant-core-python-3-8-backport-for-debian-buster/234859

edit 2: derp, the same instructions are in the readme.md

~~it's probably worth linking to https://pypi.org/project/wyzecam/ specifically about the instructions for installing libIOTCAPIs_ALL~~

on arm (but not amd64) I've had to do pip install wheel before installing wyzecam, otherwise a wyzecam dependency has a weird break: https://pastebin.com/raw/Wgefds1X

I don't know python well enough to know if that's going to be a problem or performance issue, but pip install wheel fixes it. I imagine it's harmless everywhere.

I prefer to not have the username/password visible with ps, and a simple solution is to

pip install setproctitle

then in the script import setproctitle and then first thing in main:

setproctitle.setproctitle("wyze-to-rtmp")

(or whatever you want to call it)

And then lastly, and this is purely personal preference, but ffmpeg is insanely noisy in the logs (if using systemd, otherwise its just going to stdout/stderr) so I added these in the [Service] section of the unit file:

StandardOutput=null StandardError=null

Thanks again for figuring this out, working great!

edit: oh, and -fflags nobuffer worked in zoneminder options too for zero delay, awesome!

pygmymarmoset avatar Jun 26 '21 07:06 pygmymarmoset

Once docker and docker-compose are installed, head over here for the Frigate install instructions: https://blakeblackshear.github.io/frigate/installation

If you decide you don't want to run Frigate anymore you just stop and delete the container and then delete the images. It's a learning curve but not bad. Once you know how to use docker you will be able to spin up all sorts of services with zero risk of trashing your system.

OK. I'll give it a try tomorrow. Spent the past several hours trying to get stream up on Shinobi. No luck.

I can, however, steam hls and rtmp to vlc, so I'm still hopeful.

SomebodySysop avatar Jun 26 '21 07:06 SomebodySysop

Speaking of docker, I actually made a quick docker-compose for @noelhibbard's script. I uploaded it here if anyone wants it: https://github.com/mrlt8/docker-wyze-bridge

mrlt8 avatar Jun 26 '21 13:06 mrlt8

Speaking of docker, I actually made a quick docker-compose for @noelhibbard's script. I uploaded it here if anyone wants it: https://github.com/mrlt8/docker-wyze-bridge

I like how you're looping through all the cameras and starting a stream for each one. I was considering doing that myself. I was also thinking about making a docker for it but I'd have to learn how that side of docker works first.

noelhibbard avatar Jun 26 '21 13:06 noelhibbard

Muchas gracias @noelhibbard for this solution! From the first day I read it, I began researching the question: How do I convert RTMP stream to RTSP? I am already using a nice little nvr that I like and have been using for years now, and really did not want to change if I didn't have to. However, I could not find any usable references to RTMP -> RTSP (the reverse, yes, there were tons of them). Then, I began researching how to use ffmpeg to open an RTSP stream. I found the command to do it, but it wouldn't work because you need a listener at the port where you wanted to stream RTSP

In trying to troubleshoot that problem I found the RTSP Simple Server: https://github.com/aler9/rtsp-simple-server. You can download it as a pre-compiled binary.

Long story short, with one command:

ffmpeg -re -stream_loop -1 -i rtmp://127.0.0.1:1940/show/wyzecam301 -c copy -f rtsp rtsp://localhost:8554/wyzecam301

I am now able to redirect the RTMP stream I create using wyze-to-rtmp to an RTSP stream using RTMP Simple Server. Using this url:

rtsp://192.168.1.197:8554/wyzecam301

I am able to connect my existing nvr to the stream. In fact, I can now use any nvr that supports rtsp. WyzeCam V3 streaming problem solved!

Furthermore, by launching wyze-to-rtmp on port 1940 (instead of 1935), I can run both RTSP Simple Server and nginx at the same time!

Of course, these solutions aren't simple: they mostly require a dedicated computer. But, you can install Ubuntu on any old computer you have laying around (I have it running on a 11 year old laptop) and have the full power of Linux to do all of this.

Again, thanks to all who have shared this invaluable information!

SomebodySysop avatar Jun 26 '21 20:06 SomebodySysop

So, I got this to work with one camera:

/home/ron/wyze-to-rtmp/bin/python /home/ron/wyze-to-rtmp/wyze-to-rtmp.py --user [my username] --password [my password] --cameraname "WyzeCam301" --url rtmp://127.0.0.1/show/wyzecam301

But what about multiple cameras? I got a startup script that executes the 3 segments I need:

  1. starts rtsp-simple-server
  2. runs wyze-to-rtmp for first camera
  3. ffmpeg rtsp stream for first camera

However, when I add the wyze-to-rtmp script for second camera, I run into issues.

Is there a way to execute wyze-to-rtmp once but create rtmp streams for multiple cameras?

SomebodySysop avatar Jun 27 '21 06:06 SomebodySysop

@SomebodySysop I updated my docker-compose.yml to use rtsp-simple-server, so you could run that to get an RTSP/RTMP/HLS stream for all your cameras.

mrlt8 avatar Jun 27 '21 11:06 mrlt8

It's called simple server but it looks really flexible. I'm going to ditch my whole setup and go with your docker. So clean and simple. Thanks for packaging this up! Its also motivated me to learn more about docker so thanks for that too. 😀

noelhibbard avatar Jun 27 '21 13:06 noelhibbard

@SomebodySysop I updated my docker-compose.yml to use rtsp-simple-server, so you could run that to get an RTSP/RTMP/HLS stream for all your cameras.

OK. I got this thing working without docker, but unable to figure out the multiple cameras. So, bit the bullet and attempted to install docker (so I can use your yml) on Ubuntu 20 "focal" os. Got this far:

root@ToshibaWin7-Ubuntu:/home/ron/docker# apt-get install docker-ce docker-ce-cli containerd.io Reading package lists... Done Building dependency tree
Reading state information... Done Package docker-ce is not available, but is referred to by another package. This may mean that the package is missing, has been obsoleted, or is only available from another source

E: Package 'docker-ce' has no installation candidate E: Unable to locate package docker-ce-cli E: Unable to locate package containerd.io E: Couldn't find any package by glob 'containerd.io' E: Couldn't find any package by regex 'containerd.io'

Any suggestions on what to do next? This is all new to me.

This is what I got back on the command previous to the one above:

root@ToshibaWin7-Ubuntu:/home/ron/docker# echo"deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null bash: echodeb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu focal stable: No such file or directory

SomebodySysop avatar Jun 27 '21 18:06 SomebodySysop

E: Package 'docker-ce' has no installation candidate E: Unable to locate package docker-ce-cli E: Unable to locate package containerd.io E: Couldn't find any package by glob 'containerd.io' E: Couldn't find any package by regex 'containerd.io'

So, I used my Google friend and found a workaround for installing docker on Ubuntu focal. Also located instructions for installing docker-compose.

https://stackoverflow.com/questions/61401626/docker-installation-failed-on-ubuntu-20-04-ltsvmware

sudo apt-get install -y docker.io

root@ToshibaWin7-Ubuntu:/home/ron/docker# docker -v Docker version 20.10.2, build 20.10.2-0ubuntu1~20.04.2

root@ToshibaWin7-Ubuntu:/home/ron/docker# docker-compose -version docker-compose version 1.26.2, build eefe0d31

So, hopefully now it all gets easy!

SomebodySysop avatar Jun 27 '21 19:06 SomebodySysop

This is impressive, I love the simplicity of piping to ffmpeg to set up an rtsp stream. Fwiw, I got rtsp working (mostly, still working out some memory leak issues) with gstreamer and gst-rtsp-server; and the best part is it doesn't need to do any transcoding, as it's an h264/h265 stream already under that crazy protocol. However, the setup is way worse than this solution, which frankly is hard to beat :).

Will publish what I have shortly, just haven't had time to document any of it yet.

(Thanks @noelhibbard!)

kroo avatar Jun 29 '21 07:06 kroo

Here's what I put together, note that this is still very much in an experimental state:

https://github.com/kroo/wyze-rtsp-bridge

This is an rtsp server powered by this python library and gstreamer. My hope is to get it to the point where it's easily useable directly in docker, though I've run into some networking challenges with the tutk library and docker that I still need to work out before that will work...

kroo avatar Jul 13 '21 00:07 kroo

Hey, @kroo I've actually got the tutk library in my docker container working:

https://github.com/mrlt8/docker-wyze-bridge/blob/main/app/dockerfile#L4-L5

mrlt8 avatar Jul 13 '21 00:07 mrlt8

Nice! I was able to get Tutk installed in the docker container (I mounted it rather than building it in just to avoid distributing the library, and to be a little more cross-platform); was just running into networking issues on docker for Mac (it keeps trying to connect via a bridge rather than over the local network, which i imagine is mostly a mac networking problem)

kroo avatar Jul 13 '21 02:07 kroo