Create a local WebRTC, RTSP, RTMP, or HLS/Low-Latency HLS stream for most of your Wyze cameras including the outdoor, doorbell, and 2K cams.
No modifications, third-party, or special firmware required.
It just works!
Streams direct from camera without additional bandwidth or subscriptions.
Please consider ⭐️ starring or ☕️ sponsoring this project if you found it useful, or use the affiliate link when shopping on amazon!
Important
As of May 2024, you will need an API Key and API ID from: Wyze Support Article.
[!WARNING] Please double check your router/firewall and do NOT forward ports or enable DMZ access to the bridge unless you know what you are doing!
See the supported cameras section for additional information.
Install docker and run:
docker run -p 8554:8554 -p 8888:8888 -p 5050:5000 -e WB_AUTH=false idisposablegithub365/wyze-bridgeYou can then use the web interface at http://localhost:5050 where localhost is the hostname or ip of the machine running the bridge.
See basic usage for additional information or visit the wiki page for additional information on using the bridge as a Home Assistant Add-on.
- Revert tutk_protocol change in
K10056SetResolvingBit
- Removed forced leading "/" from RECORD_PATH
- Removed the IP restrictions from the MediaMTX "publisher" role
- Sync up with Elliot Kroo's wyzecam library
- add HL_WCO2 camera support
- K10020CheckCameraParams support
- Fix
authentication_type's type - Add fps to the
K10056SetResolvingBitmessage - Fix time setting to always advance one second (for lag) in
K10092SetCameraTime - Send/recv time and blank (PST flag?) to
K11006GetCurCruisePoint/K11010GetCruisePoints/K11012SetCruisePoints
- Changed the MediaMTX config builder to emit correct config for recording
- Cleanup the warnings in the app code and added
mtx_eventpipe receipt logging - Updated Wyze iOS app version to 3.5.0.8 (for user agent)
- Use
SIGTERMfor more graceful shutdown - More startup logging for the MTX configuration of
RECORD_PATH - Sync up all the ports listed in MediaMTX with the ports exposed in the docker-compose files
- Reverted defaulting of RECORD_PATH option specifying
{cam_name}instead of%path(need to fix that another way) - Changed the MediaMTX config builder to emit correct config for recording.
Changed the documentation and defaults for the RECORD_PATH option to specifyReverted in v3.10.7{cam_name}instead of%pathto eliminate recording errors- Add exception handling to ffmpeg pruning logic to prevent snapshot prunes from killing each other
- Now gathers the list of parents that might be pruned and does that after purging the files
- Fixed python lint message in get_livestream_cmd
- Fix regression for snapshot pruning
- Catch exceptions when pruning snapshots so we don't stop grabbing them if something breaks a prune.
- Allow the ffmpeg error messages to reach the normal runtime
- Bump to MediaMTX 1.12.2 to fix regression on RaspberryPIs
- Bump MediaMTX to 1.12.1
- Added code to protect against the aggressive syntax check in MediaMTX 1.12.0 which
complains about the
recordPathmissing required elements even when recording is not enabled (it really shouldn't validate that setting unless one or more paths request recording...and didn't through 1.11.3). For reference, the pattern is computed from ourRECORD_PATHandRECORD_FILE_NAMEsettings and the combination of them must contain thestrftimeformat specifiers of either a"%s"or all of of "%Y", "%m", "%d", "%H", "%M", "%S" (case-sensitive). If the value is not compliant, to keep MediaMTX from erroring out, we append"_%s"whatever was specified and emit a warning. - Changed the default
RECORD_PATHtov3.10.7"record/%path/%Y/%m/%d/""%path/{cam_name}/%Y/%m/%d" - Changed the default
RECORD_FILE_NAMEto"%Y-%m-%d-%H-%M-%S"
- Add
TOTP_KEYandMQTT_DTOPICto config.yml schema to avoid logged warning noise - Add
MQTT_DTOPICto config.yml options to ensure a usable default - Add
video: trueto all the config.yml variants to ensure hardware encoding can use video card - Upgrade to
python:3.13-slim-bookwormfor docker base image - Cleaned up Dockerfile scripts for testing and multiarch
- Safer docker build by testing the tarballs downloaded for MediaMTX or FFMpeg
- Attempt upgrade of MediaMTX to 1.12.0 (again)
- Fixed schema of RECORD_LENGTH config option (it needs an
sorhsuffix, so must be string) - Added RECORD_KEEP to the config.yml so it can be actually be configured in the add-on
- Better logging of exceptions and pass the MediaMTX messages through to main logs
- Correct building of permissions for MediaMTX
- Documented all the possible points in the docker-compose files.
- Revert MediaMTX to 1.11.3 because 1.12 doesn't work here.
- Fix MediaMTX to pass a user name since 1.12.0 now requires one
- Chore: Bump MediaMTX to 1.12.0
Rehoming this to ensure it lives on since PR merges have stalled in the original (and most excellent) @mrlt8 repo, I am surfacing a new release with the PRs I know work. Note The badges on the GitHub repo may be broken and the donation links still go to @mrlt8 (as they should!)
- Chore: Bump Flask to 3.1.*
- Chore: Bump Pydantic to 2.11.*
- Chore: Bump Python-dotenv to 1.1.*
- Chore: Bump MediaMTX to 1.11.3
- FIX: Add host_network: true for use in Home Assistant by @jdeath to allow communications in Docker
- FIX: Hardware accelerated rotation by @giorgi1324
- Enhancement: Add more details to the cams.m3u8 endpoint by @IDisposable
- FIX: Fix mixed case when URI_MAC=true by @unlifelike
- Update: Update Homebridge-Camera-FFMpeg documentation link by @donavanbecker
- FIX: Add formatting of {cam_name} and {img} to webhooks.py by @traviswparker which was lost
- Chore: Adjust everything for move to my GitHub repo and Docker Hub account
- FIX: Increased
MTX_WRITEQUEUESIZEto prevent issues with higher bitrates. - FIX: Restart RTMP livestream on fail (#1333)
- FIX: Restore user data on bridge restart (#1334)
- NEW:
SNAPSHOT_KEEPOption to delete old snapshots when saving snapshots with a timelapse-like custom format withSNAPSHOT_FORMAT. (#1330)- Example for 3 min:
SNAPSHOT_KEEP=180,SNAPSHOT_KEEP=180s,SNAPSHOT_KEEP=3m - Example for 3 days:
SNAPSHOT_KEEP=72h,SNAPSHOT_KEEP=3d - Example for 3 weeks:
SNAPSHOT_KEEP=21d,SNAPSHOT_KEEP=3w
- Example for 3 min:
- NEW:
RESTREAMIOoption for livestreaming via restream.io. (#1333)- Example
RESTREAMIO_FRONT_DOOR=re_My_Custom_Key123
- Example
- FIX: day/night FPS slowdown for V4 cameras (#1287) Thanks @cdoolin and @Answer-1!
- NEW: Update battery level in WebUI
FIXED: Could not disable WB_AUTH if WB_API is set. (#1304)
Simplify default credentials for the WebUI:
- This will not affect users who are setting their own
WB_PASSWORDandWB_API. - Default
WB_PASSWORDwill now be derived from the username part of the Wyze email address instead of using a randomly generated password.- Example: For the email address
[email protected], theWB_PASSWORDwill bejohn123.
- Example: For the email address
- Default
WB_APIwill be based on the wyze account for persistance.
NEW: STREAM_AUTH option to specify multiple users and paths:
-
Username and password should be separated by a
: -
An additional
:can be used to specify the allowed IP address for the user.- This does NOT work with docker desktop
- Specify multiple IPs using a comma
-
Use the
@to specify paths accessible to the user.- Paths are optional for each user.
- Multiple paths can be specified by using a comma. If none are provided, the user will have access to all paths/streams
-
Multiple users can be specified by using
|as a separatorEXAMPLE:
STREAM_AUTH=user:pass@cam-1,other-cam|second-user:password@just-one-cam|user3:pass-
user:passhas access tocam-1andother-cam -
second-user:passwordhas access tojust-one-cam -
user3:passhas access to all paths/camerasSee Wiki for more information and examples.
Recoding streams has been updated to use MediaMTX with the option to delete older clips.
Use RECORD_ALL or RECORD_CAM_NAME to enable recording.
RECORD_FILE_NAMEAvailable variables are%path,{CAM_NAME},{cam_name},%Y%m%d%H%M%S%f%s(time in strftime format).RECORD_PATHAvailable variables are%path,{CAM_NAME},{cam_name},%Y%m%d%H%M%S%f%s(time in strftime format).RECORD_LENGTHLength of each clip. Usesfor seconds ,hfor hours. Defaults to60sRECORD_KEEPDelete older clips. Usesfor seconds ,hfor hours. Set to 0s to disable automatic deletion. Defaults to0s
Note that as of release v3.10.0, which uses mediaMTX 1.12.0, requires the combination of your RECORD_FILE_NAME and RECORD_PATH settings
specifying recording's file complete path MUST reference ALL of %Y %m %d %H %M %S tokens, for example:
RECORD_FILE_NAME = "%H%M%S%" and RECORD_PATH_NAME = "{path}/{cam_name}/%Y/%m/%d%" would be valid. You can also just
ensure the combined path includes %s (which is the unix epoch value as an integer).
- How does this work?
- It uses the same SDK as the app to communicate directly with the cameras. See kroo/wyzecam for details.
- Does it use internet bandwidth when streaming?
- Not in most cases. The bridge will attempt to stream locally if possible but will fallback to streaming over the internet if you're trying to stream from a different location or from a shared camera. See the wiki for more details.
- Can this work offline/can I block all wyze services?
- No. Streaming should continue to work without an active internet connection, but will probably stop working after some time as the cameras were not designed to be used without the cloud. Some camera commands also depend on the cloud and may not function without an active connection. See wz_mini_hacks for firmware level modification to run the camera offline.
- Why aren't all wyze cams supported yet (OG/Doorbell Pro)?
- These cameras are using a different SDK and will require a different method to connect and stream. See the awesome cryze project by @carTloyal123.
Should work on most x64 systems as well as on most modern arm-based systems like the Raspberry Pi 3/4/5 or Apple Silicon M1/M2/M3.
The container can be run on its own, in Portainer, Unraid, as a Home Assistant Add-on, locally or remotely in the cloud.
Note
Some network adjustments may be needed - see this discussion for more information.
Important
Some newer camera firmware versions may cause issues with remote access via P2P. Local "LAN" access seems unaffected at this time. A temporary solution is to use a VPN. See the OpenVPN example.
| Camera | Model | Tutk Support | Latest FW |
|---|---|---|---|
| Wyze Cam v1 [HD only] | WYZEC1 | ✅ | 3.9.4.x |
| Wyze Cam V2 | WYZEC1-JZ | ✅ | 4.9.9.x |
| Wyze Cam V3 | WYZE_CAKP2JFUS | ✅ | 4.36.11.x |
| Wyze Cam V4 [2K] | HL_CAM4 | ✅ | 4.52.3.x |
| Wyze Cam Floodlight | WYZE_CAKP2JFUS | ✅ | 4.36.11.x |
| Wyze Cam Floodlight V2 [2k] | HL_CFL2 | ✅ | 4.53.2.x |
| Wyze Cam V3 Pro [2K] | HL_CAM3P | ✅ | 4.58.11.x |
| Wyze Cam Pan | WYZECP1_JEF | ✅ | 4.10.9.x |
| Wyze Cam Pan v2 | HL_PAN2 | ✅ | 4.49.11.x |
| Wyze Cam Pan v3 | HL_PAN3 | ✅ | 4.50.4.x |
| Wyze Cam Pan Pro [2K] | HL_PANP | ✅ | - |
| Wyze Cam Outdoor | WVOD1 | ✅ | 4.17.4.x |
| Wyze Cam Outdoor v2 | HL_WCO2 | ✅ | 4.48.4.x |
| Wyze Cam Doorbell | WYZEDB3 | ✅ | 4.25.1.x |
| Wyze Cam Doorbell v2 [2K] | HL_DB2 | ✅ | 4.51.1.x |
| Wyze Cam Doorbell Pro 2 | AN_RDB1 | ❓ | - |
| Wyze Battery Cam Pro | AN_RSCW | - | |
| Wyze Cam Flood Light Pro [2K] | LD_CFP | - | |
| Wyze Cam Doorbell Pro | GW_BE1 | - | |
| Wyze Cam OG | GW_GC1 | - | |
| Wyze Cam OG Telephoto 3x | GW_GC2 | - |
This is similar to the docker run command, but will save all your options in a yaml file.
- Install Docker Compose.
- Use the sample as a guide to create a
docker-compose.ymlfile with your wyze credentials. - Run
docker-compose up.
Once you're happy with your config you can use docker-compose up -d to run it in detached mode.
Caution
If your credentials contain a $ character, you need to escape it with another $ sign (e.g., pa$$word > pa$$$$word) or leave your credentials blank and use the webUI to login.
[!NOTE] You may need to update the WebUI links if you're changing the ports or using a reverse proxy.
To update your container, cd into the directory where your docker-compose.yml is located and run:
docker-compose pull # Pull new image
docker-compose up -d # Restart container in detached mode
docker image prune # Remove old imagesVisit the wiki page for additional information on Home Assistant.
- Camera Commands (MQTT/REST API)
- Two-Factor Authentication (2FA/MFA)
- ARM/Apple Silicon/Raspberry Pi
- Network Connection Modes
- Portainer
- Unraid
- Home Assistant
- Homebridge Camera FFmpeg
- HomeKit Secure Video
- WebUI API
The bridge features a basic Web-UI which can display a preview of all your cameras as well as direct links to all the video streams.
The web-ui can be accessed on the default port 5000:
http://localhost:5000/See also:
WebRTC should work automatically in Home Assistant mode, however, some additional configuration is required to get WebRTC working in the standard docker mode.
- WebRTC requires two additional ports to be configured in docker:
ports:
- 8889:8889 #WebRTC
- 8189:8189/udp # WebRTC/ICE- In addition, the
WB_IPenv needs to be set with the IP address of the server running the bridge.
environment:
- WB_IP=192.168.1.116- See documentation for additional information/options.
All environment variables are optional.
- Audio
- Bitrate and Resolution
- Camera Substreams
- MQTT Configuration
- Filtering Cameras
- Doorbell/Camera Rotation
- Custom FFmpeg Commands
- Interval Snapshots
- Stream Recording and Livestreaming
- rtsp-simple-server/MediaMTX Config
- Offline/IFTTT Webhook
- Proxy Stream from RTSP Firmware
- BOA HTTP Server/Motion Alerts
- Debugging Options
Honorable Mentions:
- @noelhibbard's script - Original script that the bridge is bassd on.
- kroo/wyzecam - Original library that the bridge is based on.
Video Streaming:
- gtxaspec/wz_mini_hacks - Firmware level modification for Ingenic based cameras with an RTSP server and self-hosted mode to use the cameras without the wyze services.
- thingino - Advanced custom firmware for some Ingenic-based wyze cameras.
- carTloyal123/cryze - Stream video from wyze cameras (Gwell cameras) that use the Iotvideo SDK from Tencent Cloud.
- xerootg/cryze_v2 - Stream video from wyze cameras (Gwell cameras) that use the Iotvideo SDK from Tencent Cloud.
- mnakada/atomcam_tools - Video streaming for Wyze v3.
General Wyze:
- shauntarves/wyze-sdk - python library to interact with wyze devices over the cloud.
