Coder Social home page Coder Social logo

kroo / wyzecam Goto Github PK

View Code? Open in Web Editor NEW
163.0 7.0 14.0 822 KB

Python package for streaming video from wyze cameras over the local network

Home Page: https://kroo.github.io/wyzecam/

License: MIT License

Makefile 3.04% Python 96.96%
wyzecam wyze-cameras video

wyzecam's People

Contributors

dependabot[bot] avatar kroo avatar krystiancharubin avatar mrlt8 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

wyzecam's Issues

Wyze Video Doorbell Support

πŸ› Bug Report

πŸ”¬ How To Reproduce

Steps to reproduce the behavior:

  1. Run sample code
python3 wyze.py 
AV Client Start: chan_id=0 expected_chan=0 pn_serv_type=16
Sending response: <K10002ConnectAuth code=10002 resp_code=10003>
^CTraceback (most recent call last):
  File "wyze.py", line 51, in <module>
    main()
  File "wyze.py", line 27, in main
    with wyze_iotc.connect_and_auth(account, cam) as sess:
  File "/home/kcharubin/.local/lib/python3.8/site-packages/wyzecam/iotc.py", line 322, in __enter__
    self._auth()
  File "/home/kcharubin/.local/lib/python3.8/site-packages/wyzecam/iotc.py", line 295, in _auth
    mux.waitfor(resolving)
  File "/home/kcharubin/.local/lib/python3.8/site-packages/wyzecam/tutk/tutk_ioctl_mux.py", line 250, in waitfor
    time.sleep(0.1)
KeyboardInterrupt

Code sample

Environment

  • OS: [e.g. Linux / Windows / macOS] Linux
  • Python version, get it with: Python 3.8.5
python --version

Screenshots

πŸ“ˆ Expected behavior

Expect to see the video stream just like with v2 camera

πŸ“Ž Additional context

WiseNet and Samsung BabyView cameras (aka SEW-3057WP)

πŸš€ Feature Request

The Samsung baby cameras seems to somehow reuse the same WyzeCam protocol (at least, I found the same libAVAPIs.so and libIOTCAPIs.so libraries on the device itself). The camera though is not using any cloud, and is only able to connect when in the same WiFi network. The only known application which is able to connect to theese devices is the BabyView application (https://play.google.com/store/apps/details?id=tw.com.surveillance.babyview2&hl=ru&gl=US).

πŸ”ˆ Motivation

There is no way to access these cameras data except by the help of the BabyView app, which, let's be honest, is buggy like hell. This could be another way to do it.

πŸ›° Alternatives

Except using the BabyView official app, none.

πŸ“Ž Additional context

The cameras aren't using any "tokens", but instead are using a some kind of a static "password". It may be converted into the same "token" by some algorythm (because the password itself is supposed to be only 8-15 characters long, so deriving it to a hex 32 characters seems to be doable). Also, the port on which the "AVAPIs_Server" is listening - is the port 9090/tcp and ports 37507/udp, 32761/udp. Apparently the actual used viewing username is "admin".

No Audio

Description of the project is to stream both Audio and Video with full support for v3.....but the code is only for Video stream.

Detailed Linux (Debian) install notes

Okay, not really a question, just leaving some notes for really green Linux users.

# clone repo
git clone https://github.com/kroo/wyzecam.git && cd wyzecam

# Install python, pip and virtual environment
sudo apt-get install python3 python3-pip python3-venv -y

# create venv
python3 -m venv wyzetest
source wyzetest/bin/activate

# Install dependencies
pip install .
pip install requests
pip install opencv-python
pip install av

# Download, compile and install TUTK_IOTC
wget https://github.com/nblavoie/wyzecam-api/raw/master/wyzecam-sdk/TUTK_IOTC_Platform_14W42P1.zip
unzip TUTK_IOTC_Platform_14W42P1.zip
cd Lib/Linux/x64/
g++ -fpic -shared -Wl,--whole-archive libAVAPIs.a libIOTCAPIs.a -Wl,--no-whole-archive -o libIOTCAPIs_ALL.so
sudo cp libIOTCAPIs_ALL.so /usr/local/lib/
cd ../../..

# Set Wyze creds
export [email protected]
export WYZE_PASSWORD=mypassword

# Set your camera name on line 20 of example:
nano examples/streaming_video.py

# run example
python examples/streaming_video.py

Solve DTLS in new wyze FW

πŸš€ Feature Request

The below code suggested by merlt8 to overcome DTLS feature in new wyze FW, where current code cannot access RTSP with new FW with DTLS

def getAuthKey(mac, enr): key = enr + mac.upper() hash = hashlib.sha256(key.encode()) print(hash.digest()) bArr = bytearray(hash.digest())[0:6] print(bArr) authKey = base64.standard_b64encode(bArr).decode().replace('+', 'Z').replace('/', '9').replace('=', 'A').encode() return authKey

av_account: admin
av_password:Β camera.enr

πŸ”ˆ Motivation

This will help keep the code compatible with new wyze FW updates (latest one compatabile was in August wyze FW release).
Wyze official RTSP will stay beta, and they will not maintain it, as they mentioned explicitly (they dont have enough resources to maintain 2 branches of FW).
And always, non RTSP wyze FW maintained and updated well....hut this DTLS is now showstopper.

πŸ›° Alternatives

Dont update wyze FW anymore.

πŸ“Ž Additional context

Is basicInfo wifidb actually link quality?

Checklist

  • I've searched the project's issues.

❓ Question

I had assumed that basicInfo.wifidb represented rssi, but it seems to more related to link quality..?
Any additional info would be appreciated!

πŸ“Ž Additional context

with wyzecam.WyzeIOTC() as wyze_iotc:
  with wyze_iotc.connect_and_auth(account, camera) as sess:
    print(sess.camera.camera_info['basicInfo']['wifidb'])

Native Windows support

πŸš€ Feature Request

Add native Windows support. (without using WSL and Xming.)

The library can support windows natively if the DLL's are specified in the code instead of using a merged .so/.dylib file. Windows does not support merging DLL's.

πŸ”ˆ Motivation

Selfishly, I want to be able to view the camera stream using the efficient cv2.imshow().

I have not tried running it via WSL but I assume running it natively is faster.

πŸ›° Alternatives

Running it via WSL and Xming like proposed in the install instructions.

πŸ“Ž Additional context

I got it to run on Windows by changing the code to specify if tutk_platform_lib needed AVAPIs or IOTCAPIs.
Now, I can't make a PR because it no longer supports Linux or MacOS. I don't know enough about g++ etc. to see why a merged library file is needed instead of just importing the two separate files. If Linux and MacOS can handle 2 separate files it could be cleaned up and merged, and support all 3 platforms.

I attach 2 patch files with the changes I made to get it to work. It's not a proper Git patch but it shows that the changes needed for Windows functionality are quite few.

wyzecam_on_windows

wyzecam/iotc.py:

62c62,63
<         tutk_platform_lib: Optional[Union[str, CDLL]] = None,
---
>         tutk_platform_lib_iotc: Optional[Union[str, CDLL]] = None,
>         tutk_platform_lib_av: Optional[Union[str, CDLL]] = None,
78,82c79,89
<         if tutk_platform_lib is None:
<             tutk_platform_lib = tutk.load_library()
<         if isinstance(tutk_platform_lib, str):
<             path = pathlib.Path(tutk_platform_lib)
<             tutk_platform_lib = tutk.load_library(str(path.absolute()))
---
>         if tutk_platform_lib_av is None:
>             tutk_platform_lib_av = tutk.load_library("C:\\Users\\[Redacted]\\PycharmProjects\\wyzestream\\tutk_lib\\Lib\\Windows\\x64\\AVAPIs.dll")
>         if isinstance(tutk_platform_lib_av, str):
>             path = pathlib.Path(tutk_platform_lib_av)
>             tutk_platform_lib_av = tutk.load_library(str(path.absolute()))
>             
>         if tutk_platform_lib_iotc is None:
>             tutk_platform_lib_iotc = tutk.load_library("C:\\Users\\[Redacted]\\PycharmProjects\\wyzestream\\tutk_lib\\Lib\\Windows\\x64\\IOTCAPIs.dll")
>         if isinstance(tutk_platform_lib_iotc, str):
>             path = pathlib.Path(tutk_platform_lib_iotc)
>             tutk_platform_lib_iotc = tutk.load_library(str(path.absolute()))
84c91,92
<         self.tutk_platform_lib: CDLL = tutk_platform_lib
---
>         self.tutk_platform_lib_av: CDLL = tutk_platform_lib_av
>         self.tutk_platform_lib_iotc: CDLL = tutk_platform_lib_iotc
108c116
<             self.tutk_platform_lib, udp_port=self.udp_port or 0
---
>             self.tutk_platform_lib_iotc, udp_port=self.udp_port or 0
114c122
<             self.tutk_platform_lib, max_num_channels=self.max_num_av_channels
---
>             self.tutk_platform_lib_av, max_num_channels=self.max_num_av_channels
126,127c134,135
<         tutk.av_deinitialize(self.tutk_platform_lib)
<         tutk.iotc_deinitialize(self.tutk_platform_lib)
---
>         tutk.av_deinitialize(self.tutk_platform_lib_av)
>         tutk.iotc_deinitialize(self.tutk_platform_lib_iotc)
132c140
<         return tutk.iotc_get_version(self.tutk_platform_lib)
---
>         return tutk.iotc_get_version(self.tutk_platform_lib_iotc)
161c169
<         return WyzeIOTCSession(self.tutk_platform_lib, account, camera)
---
>         return WyzeIOTCSession(self.tutk_platform_lib_av, self.tutk_platform_lib_iotc, account, camera)
233c241,242
<         tutk_platform_lib: CDLL,
---
>         tutk_platform_lib_av: CDLL,
>         tutk_platform_lib_iotc: CDLL,
252c261,262
<         self.tutk_platform_lib: CDLL = tutk_platform_lib
---
>         self.tutk_platform_lib_av: CDLL = tutk_platform_lib_av
>         self.tutk_platform_lib_iotc: CDLL = tutk_platform_lib_iotc
275c285
<             self.tutk_platform_lib, self.session_id
---
>             self.tutk_platform_lib_iotc, self.session_id
301c311
<         return TutkIOCtrlMux(self.tutk_platform_lib, self.av_chan_id)
---
>         return TutkIOCtrlMux(self.tutk_platform_lib_iotc, self.tutk_platform_lib_av, self.av_chan_id)
357c367
<                 self.tutk_platform_lib, self.av_chan_id
---
>                 self.tutk_platform_lib_av, self.av_chan_id
626c636
<             session_id = tutk.iotc_get_session_id(self.tutk_platform_lib)
---
>             session_id = tutk.iotc_get_session_id(self.tutk_platform_lib_iotc)
632c642
<                 self.tutk_platform_lib, self.camera.p2p_id, self.session_id
---
>                 self.tutk_platform_lib_iotc, self.camera.p2p_id, self.session_id
642c652
<                 self.tutk_platform_lib,
---
>                 self.tutk_platform_lib_av,
667c677
<         tutk.av_client_set_max_buf_size(self.tutk_platform_lib, max_buf_size)
---
>         tutk.av_client_set_max_buf_size(self.tutk_platform_lib_av, max_buf_size)
724c734
<             tutk.av_client_stop(self.tutk_platform_lib, self.av_chan_id)
---
>             tutk.av_client_stop(self.tutk_platform_lib_av, self.av_chan_id)
727c737
<             tutk.iotc_session_close(self.tutk_platform_lib, self.session_id)
---
>             tutk.iotc_session_close(self.tutk_platform_lib_iotc, self.session_id)

wyzecam/tutk/tutk_ioctl_mux.py

109c109
<     def __init__(self, tutk_platform_lib: CDLL, av_chan_id: c_int) -> None:
---
>     def __init__(self, tutk_platform_lib_iotc: CDLL, tutk_platform_lib_av: CDLL, av_chan_id: c_int) -> None:
116c116,117
<         self.tutk_platform_lib = tutk_platform_lib
---
>         self.tutk_platform_lib_iotc = tutk_platform_lib_iotc
>         self.tutk_platform_lib_av = tutk_platform_lib_av
122c123
<             tutk_platform_lib, av_chan_id, self.queues
---
>             tutk_platform_lib_av, av_chan_id, self.queues # original iotc
189c190
<             self.tutk_platform_lib, self.av_chan_id, ctrl_type, encoded_msg
---
>             self.tutk_platform_lib_av, self.av_chan_id, ctrl_type, encoded_msg

Feed Wyze stream into RTMP server

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

WyzeIOTCSession - IOTC_ER_NOT_INITIALIZED

πŸ› Bug Report

Hello, I'm trying to adjust the bitrate/frame size via WyzeIOTCSession as listed in the documentation, however, I keep getting IOTC_ER_NOT_INITIALIZED whenever I try to use WyzeIOTCSession.

πŸ”¬ How To Reproduce

Steps to reproduce the behavior:

import os
import wyzecam

auth_info = wyzecam.login(os.environ["WYZE_EMAIL"], os.environ["WYZE_PASSWORD"])
account = wyzecam.get_user_info(auth_info)
camera = wyzecam.get_camera_list(auth_info)[0]

with wyzecam.iotc.WyzeIOTCSession(wyzecam.tutk.tutk.load_library(),account,camera) as w:
	print(w.state)

Environment

  • OS: macOS 11.4
  • Python version: 3.8.9

πŸ“ˆ Expected behavior

WyzeIOTCSessionState.AUTHENTICATION_SUCCEEDED

Stopped working after updating firmware

πŸ› Bug Report

Was working great until I updated the firmware.

Now I get:
wyzecam.tutk.tutk.TutkError: IOTC_ER_CAN_NOT_FIND_DEVICE

πŸ”¬ How To Reproduce

Steps to reproduce the behavior:

Update camera firmware in app

Code sample

Environment

  • OS: Linux
  • Python version, get it with: Python 3.9.5
python --version

Screenshots

πŸ“ˆ Expected behavior

πŸ“Ž Additional context

Shared Library Issues on Linux

πŸ› Bug Report

Code seems to always look for the .dylib (mac) version of the shared library even on Linux.

shared_lib_path: str = "/usr/local/lib/libIOTCAPIs_ALL.dylib",

πŸ”¬ How To Reproduce

Steps to reproduce the behavior:

  1. Run any of the sample code in Linux
python3 wyze.py
Traceback (most recent call last):
  File "wyze.py", line 10, in <module>
    with wyzecam.WyzeIOTC() as wyze_iotc:
  File "/home/kcharubin/.local/lib/python3.8/site-packages/wyzecam/iotc.py", line 74, in __init__
    tutk_platform_lib = tutk.load_library()
  File "/home/kcharubin/.local/lib/python3.8/site-packages/wyzecam/tutk/tutk.py", line 515, in load_library
    return cdll.LoadLibrary(shared_lib_path)
  File "/usr/lib/python3.8/ctypes/__init__.py", line 451, in LoadLibrary
    return self._dlltype(name)
  File "/usr/lib/python3.8/ctypes/__init__.py", line 373, in __init__
    self._handle = _dlopen(self._name, mode)
OSError: /usr/local/lib/libIOTCAPIs_ALL.dylib: cannot open shared object file: No such file or directory

Code sample

Environment

  • OS: [e.g. Linux / Windows / macOS] Linux
  • Python version, get it with: Python 3.8.5
python --version

Screenshots

πŸ“ˆ Expected behavior

πŸ“Ž Additional context

Wyze cam outdoor support?

Checklist

  • I've searched the project's issues.

❓ Question

Has anyone managed to get the outdoor cam working?

From what I can tell, I believe the camera needs a wake command in K10000ConnectRequest..?

{"cameraInfo": {"mac": mac, "encFlag": 0, "wakeupFlag": 1}}

I don't have an outdoor cam so can't test it out.

Doorbell + Chime Integration

Checklist

  • '[x]' I've searched the project's issues.

❓ Question

Is it possible to use this with the Wyze Doorbell + Chime? Will it also integrate with Home Assistant?

Using this API to interface with Blue Iris or Shinobi ?

Hi,
I am wondering if this would be a better solution for streaming wyze v3 video/audio to blue iris, instead of using the NFS wyzehack and js script solution.
If using your API, it is possible to feed the stream to BI, could you provide an example ? This could be a very popular solution to overcome Wyze's lack of RTSP support for the v3 cam.
Thanks

Local AI with YOLOv5

Not really a feature request, but a quick example to get local AI on the wyze stream with yolov5 using 14 lines of code!

yolov5 requirements: pip install -r https://raw.githubusercontent.com/ultralytics/yolov5/master/requirements.txt

import os
import cv2
import wyzecam
import torch

model = torch.hub.load('ultralytics/yolov5', 'yolov5s')
auth_info = wyzecam.login(os.environ["WYZE_EMAIL"], os.environ["WYZE_PASSWORD"])
account = wyzecam.get_user_info(auth_info)
camera = wyzecam.get_camera_list(auth_info)[0]

with wyzecam.WyzeIOTC() as wyze_iotc:
    with wyze_iotc.connect_and_auth(account, camera) as sess:
        for (frame, frame_info) in sess.recv_video_frame_ndarray():
            results = model(frame)
            cv2.imshow("Video Feed", results.render()[0].copy())
            cv2.waitKey(1)

Adding audio stream

πŸš€ Feature Request

Is it possible to add audio, either to recv_video_data or maybe add another method?

πŸ”ˆ Motivation

Potentially lots of reasons e.g. baby monitor, child watching

πŸ›° Alternatives

πŸ“Ž Additional context

Login access_token and refresh_token

The response from the Wyzecam login API returns
'access_token': None, 'refresh_token': None
even though login appears to be successful.

Here's a minimum working example:

payload = {"email": email, "password": triplemd5(password)}                                                                                                                       
                                                                                                                                                                                  
resp = requests.post(                                                                                                                                                             
    "https://auth-prod.api.wyze.com/user/login",                                                                                                                                  
    json=payload,                                                                                                                                                                 
    headers=get_headers(phone_id)                                                                                                                                                 
)                                                                                                                                                                                 
                                                                                                                                                                                  
print(resp.json())   

{'access_token': None, 'refresh_token': None, 'user_id': 'fea576c0cXXXXXXXX978ddc792b50187', 'mfa_options': ['PrimaryPhone'], 'mfa_details': {'phone_numbers': {'primary_phone': {'country_code': '+1', 'number': 'XXXXXXXXXX'}, 'backup_phone': None}, 'totp_apps': []}, 'sms_session_id': 'XXXXXXXX-f07f-4314-9f56-488be33f302d'}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.