Skip to content

Feed Wyze stream into RTMP server #56

Description

@noelhibbard

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 joeblow@example.com --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

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions