mrlt8 / docker-wyze-bridge

WebRTC/RTSP/RTMP/LL-HLS bridge for Wyze cams in a docker container
GNU Affero General Public License v3.0
2.49k stars 152 forks source link

Support for Wyze Video Doorbell Pro? #276

Open terryhonn opened 2 years ago

terryhonn commented 2 years ago

Are there plans to support the new Video Doorbell Pro, model WWVDP? I hope so... if not, who wants to buy a Wyze Video Doorbell Pro? ;-)

mrlt8 commented 2 years ago

I'll have a look at the app.

Is the pro 100% battery operated or can it also be powered like the non pro?

terryhonn commented 2 years ago

The Pro has both power options, as well. Thanks for taking a look!

mrlt8 commented 2 years ago

Any chance it works like the WYZEDB3? I don't see anything for WWVDP, so I'm wondering if the pro is actually the WYZEDB3-S?

Edit: looks like the pro is actually the GW_BE1

terryhonn commented 2 years ago

Edit: looks like the pro is actually the GW_BE1

I don't know if that means it's possible, or not, but if there's anything I can do to help, please let me know!

mrlt8 commented 2 years ago

The doorbell pro seems to be made by Gwell and has a model number of GW_BE1.

Does the doorbell even show up in the bridge? Looks like it might be using their "mars" platform or whatever that is and streams over KVS which is what they're using for the WebRTC streams...

I wonder if they're trying to move away from TUTK to AWS which could be the reason for the forced updates coming next month.

terryhonn commented 2 years ago

That's too bad. I really like the doorbell, much more 'polished' than the original, but if I can't consume the stream locally in some way, it doesn't work for me.

Thanks for looking into it though!

On Tue, Jan 11, 2022 at 8:07 AM mrlt8 @.***> wrote:

The doorbell pro seems to be made by Gwell and has a model number of GW_BE1.

Does the doorbell even show up in the bridge? Looks like it might be using their "mars" platform or whatever that is and streams over KVS which is what they're using for the WebRTC streams...

I wonder if they're trying to move away from TUTK to AWS which could be the reason for the forced updates coming next month.

— Reply to this email directly, view it on GitHub https://github.com/mrlt8/docker-wyze-bridge/issues/276#issuecomment-1009997312, or unsubscribe https://github.com/notifications/unsubscribe-auth/ACAD2ME3DO5TB6FNNA5NIN3UVQ2QPANCNFSM5LO4ZWOA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you authored the thread.Message ID: @.***>

Z1mDMan commented 2 years ago

Does that mean it's a feature that's coming eventually or is it not possible? I also have one of these and I'm willing to do what I can to help test this.

mrlt8 commented 2 years ago

This bridge is currently based around the cameras that use the Throughtek Kalay SDK "tutk" to stream video. From what I could tell, it seems like the new Doorbell Pro is not using tutk, so we can't use that SDK to connect to the doorbell.

Starting with v1.1.0, we added the option to try to pull the WebRTC credentials if available. You could try adding WEBRTC=True to your docker-compose.yml to see if can pull the credentials of the doorbell.

terryhonn commented 2 years ago

Added the WebRTC env to an instance and included the WVDP in the FILTER_NAMES var. When the bridge starts up, it pulls the info for 3 cams and then does this:

Would you rather I open a separate bug report, since this doesn't appear to be directly related to the WVDP?


  File "/app/wyze_bridge.py", line 584, in <module>
    wb.run()
  File "/app/wyze_bridge.py", line 49, in run
    self.get_webrtc()
  File "/app/wyze_bridge.py", line 401, in get_webrtc
    if wss := wyzecam.api.get_cam_webrtc(self.auth, cam.mac):
  File "/app/wyzecam/api.py", line 230, in get_cam_webrtc
    resp.raise_for_status()
  File "/usr/local/lib/python3.10/site-packages/requests/models.py", line 960, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://webrtc.api.wyze.com/signaling/device/REDACTED/use_trickle=true```
mrlt8 commented 2 years ago

That's a known issue that has already been patched in the dev branch.

It just means the auth tokens are expired and temporarily adding FRESH_DATA=True should get you past that.

terryhonn commented 2 years ago

I had tried forcing the fresh data, but still getting the error. I uninstalled and reinstalled (this instance is the HASS Addon, BTW), and enabled WebRTC from the start. It says it's starting 1/11 cameras (I have 12 in the Wyze app, however a few are either disabled or turned off), and it gets through the first 3 and then throws the same error.

  File "/app/wyze_bridge.py", line 584, in <module>
    wb.run()
  File "/app/wyze_bridge.py", line 49, in run
    self.get_webrtc()
  File "/app/wyze_bridge.py", line 401, in get_webrtc
    if wss := wyzecam.api.get_cam_webrtc(self.auth, cam.mac):
  File "/app/wyzecam/api.py", line 230, in get_cam_webrtc
    resp.raise_for_status()
  File "/usr/local/lib/python3.10/site-packages/requests/models.py", line 960, in raise_for_status
    raise HTTPError(http_error_msg, response=self)
requests.exceptions.HTTPError: 404 Client Error: Not Found for url: https://webrtc.api.wyze.com/signaling/device/2CAA8EF6E97F?use_trickle=true

The device it is puking on is a regular Wyze Video Doorbell, not the Pro. Happy to help with debugging, just tell me what to do. Thanks!

Z1mDMan commented 2 years ago

I have a Wyze Video Doorbell Pro and was hoping to help test this. I am also getting errors when I try using these environment variables. I removed WEBRTC=True for now. I don't think I'm running the dev branch. Is this working in dev?

mrlt8 commented 2 years ago

Has anyone tried to see what kind of traffic is going between the app and camera?

@Z1mDMan Could you try blocking your phone or the doorbell from the internet to see if we can even communicate with it locally?

gtxaspec commented 2 years ago

anyone happen to have the firmware update link for this new model doorbell?

zenlav commented 1 year ago

I also have a Doorbell Pro and can help with any testing. Would really like to get this working

Z1mDMan commented 1 year ago

Has anyone tried to see what kind of traffic is going between the app and camera?

@Z1mDMan Could you try blocking your phone or the doorbell from the internet to see if we can even communicate with it locally?

Wow sorry I completely missed this. Is this still something that would help? I can easily block things from the internet on my network.

Z1mDMan commented 1 year ago

I see that there's a homebridge plugin that discovers this doorbell however it only shows up as a switch not a camera. https://github.com/jfarmer08/homebridge-wyze-smart-home Does this help at all?

mrlt8 commented 1 year ago

I think that will let you to "power" on/off the camera over their web API which I believe uses AWS IoT core to communicate with the cameras.

I believe they're using WebRTC for the doorbell Pro over AWS Kinesis - can you see the doorbell if you go to view.wyze.com?

zenlav commented 1 year ago

I cannot view my Doorbell Pro from view.wyze.com

mrlt8 commented 1 year ago

Thanks for the data point. Not sure why they're using a different method for this camera alone. They seem to have gone back to the regular tutk video stream for the other "pro" 2k cams.

holocronology commented 1 year ago

Well, glad I found this, as I've been wracking by brain trying to get it to work.

Any update on this?

If it is any help, the interface for the camera view is similar to that of the newer v2 sensors.

Z1mDMan commented 1 year ago

I think that will let you to "power" on/off the camera over their web API which I believe uses AWS IoT core to communicate with the cameras.

I believe they're using WebRTC for the doorbell Pro over AWS Kinesis - can you see the doorbell if you go to view.wyze.com?

I wasn't able to see it on view.wyze.com either but I did notice it now gets exposed as a switch in homebridge-wyze-smart-home plugin. Doesn't seem to do anything but it's a start.

it does show on view.wyze.com now but as unsupported.

carTloyal123 commented 1 year ago

Any updates on this? It seems that the video doorbell pro will not be able to be supported without major work. Is that correct or are there ways to help here?

mrlt8 commented 1 year ago

Correct. The doorbell pro seems to be the only camera in the wyze lineup manufactured by gwell and stream over webrtc instead of using the throughtek SDK (tutk) to stream and control the camera like the rest of their products. So I don't think we'll be able to support it with the current method we're using to pull the streams locally.

Wyze seems to be trying to get the rest of their cameras to stream over webrtc - cam plus web view/smart displays. Still haven't confirmed it, but I believe the latest app/firmware is also using webrtc, so we may eventually be able to support all the cameras via webrtc.

carTloyal123 commented 1 year ago

Understood, is there any work that can be done to add WebRTC to this repo or is it a big enough change to warrant an entire re-write?

mrlt8 commented 1 year ago

Right now, we're using the tutk protocol to pull the video and audio frames from the camera and repackage that into an RTSP stream, so if we could find a library that can connect and pull the WebRTC stream from the AWS IoT Core server, then we may be able to use that as a replacement.

mmatus1112 commented 1 year ago

any updates on this? Devices like RING DOORBELL have a fantastic integration into Home Assistant and it would be awesome if the wyze doorbell pro could have something similar...

carTloyal123 commented 1 year ago

I have been slowly looking into it but nothing up and running yet. There are a few libraries that will convert the WebRTV stream to digestible frames but I have not started any implementation as I am working on another Wyze project at the moment. Will update when I have more info/time to get started on this.

carTloyal123 commented 1 year ago

@mrlt8 I have been doing some research today and it looks like we can get a live HLS video stream URL from AWS Kinesis with some pretty straightforward methods provided by the AWS SDK. My question is, can we even scrape the correct authentication and credentials to setup that stream? I have a doorbell pro so I am happy to help but I must say I am pretty new to reverse engineering network calls. Are you familar with how we might be able to get some of the data being passed between the camera, bridge and Wyze AWS endpoints? It looks like we need the below information to get somewhere with this:

var options = {
                    accessKeyId: $('#accessKeyId').val(),
                    secretAccessKey: $('#secretAccessKey').val(),
                    sessionToken: $('#sessionToken').val() || undefined,
                    region: $('#region').val(),
                    endpoint: $('#endpoint').val() || undefined
                }
                var kinesisVideo = new AWS.KinesisVideo(options);
                var kinesisVideoArchivedContent = new AWS.KinesisVideoArchivedMedia(options);
kinesisVideoArchivedContent.getHLSStreamingSessionURL({
                            StreamName: streamName,
                            PlaybackMode: $('#playbackMode').val(),
                            HLSFragmentSelector: {
                                FragmentSelectorType: $('#fragmentSelectorType').val(),
                                TimestampRange: $('#playbackMode').val() === "LIVE" ? undefined : {
                                    StartTimestamp: new Date($('#startTimestamp').val()),
                                    EndTimestamp: new Date($('#endTimestamp').val())
                                }
                            },
                            ContainerFormat: $('#containerFormat').val(),
                            DiscontinuityMode: $('#discontinuityMode').val(),
                            DisplayFragmentTimestamp: $('#displayFragmentTimestamp').val(),
                            MaxMediaPlaylistFragmentResults: parseInt($('#maxResults').val()),
                            Expires: parseInt($('#expires').val())

Most of these are options that can be set once but the interesting parts will be the accessKey and secretKey.

Let me know if you have any ideas on this or how we can test my device and scrape some of the needed information.

Other link for AWS example I am referencing: https://github.com/aws-samples/amazon-kinesis-video-streams-media-viewer

EDIT: I was also thinking that even if the camera stream runs through AWS the camera itself has to be creating and sending some stream of video from the doorbell pro or the bridge and I am wondering if that is possible to uncover and use directly for a direct connection to the system instead of involving an outside service.

mrlt8 commented 1 year ago

I'm not very familiar with AWS, but I believe the camera pulls a couple of AWS related certificates on boot. I believe the cameras also use AWS's IOT Core to "power" on/off the cameras and for the other missing commands.

I don't think the secretKey ever gets revealed, but I was able to open a web socket connection with the credentials that the bridge can pull with the WEBRTC=True option. However, I the gwell cameras seem to use a different "mars" API endpoint https://wyze-mars-service.wyzecam.com, so I don't know if they even support the standard WebRTC like the cameras that support the official web view.

You could try to run the app through a proxy to try to capture the traffic related to "mars", but you'll need a way to disable the certificate pinning on your device.

I believe the KVS live view endpoint should be at "plugin/mars/live_replay_url", but I'm not familiar with that area of the wyze API.

carTloyal123 commented 1 year ago

I am also not super familiar with the AWS or Kinesis tech just been reading about it. Are you able to see a live stream from the normal Wyzecams using WebRTC and the credentials provided?

What leads you to think that the KVS live view endpoint will be at plugin/mars/live_replay_url? I just want to understand the current knowledge before diving too deep. Thanks!

carTloyal123 commented 1 year ago

it looks like you can connect to the websocket but the authorization is not working for me from what I can tell. Are you able to connect to the websocket without getting a 403 HTTP error?

It looks like all of the info needed to connect to the WebRTC stream is given in the WSS url but decoding what each part is actually used for when connected to KVS seems to be trial and error at the moment.

mrlt8 commented 1 year ago

You can see some of the API endpoints if you decrypt the official apk/ipa.

You may be able to get some of the values from the wss if you URL decode it with something like https://meyerweb.com/eric/tools/dencoder/.

I believe the new Wyze OG cameras are also being built by gwell so we may have the same issues streaming from those cameras.

mrlt8 commented 1 year ago

Hey @carTloyal123, v1.11 should decode the signalingUrl, so you should be able to use that to open a web socket connection!

carTloyal123 commented 1 year ago

@mrlt8 Thank you I will check it out and see what I can find. If the new cameras are also Gwell over AWS hopefully we can find a way to tap into that.

carTloyal123 commented 1 year ago

It looks like Wyze has an api service that handles all of the KVS and AWS setup. They have an api call that might just simply return the live streaming URL but maybe that is already what the WebRTC calls are doing that you have added.

Something calling to "https://ams-api.wyzecam.com:443/api/v1/kinesis/live_replay_url/get" that takes normal API call params for authentication plus the following:

{
   "sc": "a9ecb0f8ea7b4da2b6ab56542403d769",
   "sv": "2c36005f9d714dfcb08aa261c2f6edd3",
   "device_mac": "XXXX",
   "device_model":"GW_BE1", # for Video Doorbell Pro
   "max_manifest_fragment": 1000,
   "expires":3600,
   "begin_time":1673458804,
   "end_time": 1673458814
}

Going to look at using the existing API infrastructure to add this additional call and see what it returns.

carTloyal123 commented 1 year ago

Looks like I am able to ping the endpoint but the authorization status is not working correctly. Any ideas here? Here is some output:

URL: 
https://ams-api.wyzecam.com:443/api/v1/kinesis/live_replay_url/get

Headers:
{'X-API-Key': 'WMXHYf79Nr5gIlt3r0r7p9Tcw5bvs6BB4U8O8nGJ', 'Phone-Id': 'XXX', 'User-Agent': 'Wyze/2.38.3.3 (iPhone; iOS 16.2; Scale/3.00)', 'Content-Type': 'application/json'}

{
  "sc": "a9ecb0f8ea7b4da2b6ab56542403d769",
  "sv": "2c36005f9d714dfcb08aa261c2f6edd3",
  "app_ver": "2.38.3.3",
  "app_name": "com.hualai.WyzeCam___2.38.3.3",
  "phone_system_type": "1",
  "ts": "1673492859864",
  "access_token": "XXX",
  "phone_id": "XXX",
  "device_mac": "GW_BE1_XXX",
  "device_model": "GW_BE1",
  "max_manifest_fragment": "1000",
  "expires": "3600",
  "begin_time": "1673492281204",
  "end_time": "1673492281214"
}

Response:
{"ts":1673492918150,"code":"3005","msg":"UnauthorizedOperation","data":{}}
mrlt8 commented 1 year ago

We're currently getting the signalingUrl from webrtc.api.wyze.com:

https://github.com/mrlt8/docker-wyze-bridge/blob/be460259166da9fa977bfb22b41abdb4017374de/app/wyzecam/api.py#L235

I did try the live_replay_url but seems like it only works for certain models? Keep getting 3005 except for the v2 which responds with an empty live_replay_url:

{
    "ts": 1673501945477,
    "code": "1",
    "msg": "",
    "data": {
        "live_replay_url": ""
    }
}

Is it returning a valid url when the request is made from the app? I believe some of the API endpoints require a signature.

carTloyal123 commented 1 year ago

Yeah I have been getting the empty live url for my V2 cams and then the authorization error for the Doorbell Pro. The signaling URL is good to have but it seems we need to have additional AWS credentials in order to connect to that signaling channel and receive data. I will look into it more but the format from the Kinesis dev webpage suggests we need more information.

What kind of signature do you mean? Like a different API key than the one I have listed?

mrlt8 commented 1 year ago

The signaling url is pre-signed to avoid leaking their keys: https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-query-string-auth.html

The webrtc.api.wyze.com api should also return the turn auth/credentials in addition to the signalingUrl.

What kind of signature do you mean? Like a different API key than the one I have listed?

Some of the other Wyze API endpoints seem to require a signature or signature2 header:

signature2: d121afe2ab054386badf71a293c726ae

Luckily, none of the endpoints that the bridge currently uses require the signature header, but I have seen some endpoints that do.

carTloyal123 commented 1 year ago

So I think I've made some progress on the WebRTC stuff. I have a JavaScript client that will connect to the web socket and negotiate the webrtc details. The issue I am finding is that the cameras have to be prompted in some way to actually send frames over the webrtc protocol. This is likely just another wyze endpoint that pings and starts the camera streaming. It makes sense because the camera is battery operated so it isn't streaming all the time. Any thoughts on how to tell the device to start streaming would be awesome. I'll continue to look into the same thing as well as port over the code to python for use in this plugin.

mrlt8 commented 1 year ago

Awesome! Is that for the doorbell or the cam? I think the next step would be to send the SDP_OFFER followed by the ICE_CANDIDATE?

Here are some other potential API endpoints:

https://ams-api.wyzecam.com:443/api/v1/kinesis/live_url/get
https://wyze-mars-service.wyzecam.com/plugin/mars/live_replay_url?did=<mac>&startTime=<timestamp>&endTime=<timestamp+300>

I believe the mars one requires the Signature2 header.

carTloyal123 commented 1 year ago

Yeah the webrtc setup is totally complete and that is for the doorbell pro. My client is fully configured and just waitingto receive webrtc tracks or streams. The issue is that once the webrtc connection is setup the doorbell cam has to be prompted somehow to start sending data over the webrtc connection or even has to be prompted to setup its end of the connection then send frames. This seems to be why in the app when you connect to the doorbell you actually get a little setting up connection screen while it waits for webrtc to begin on both sides. The strange thing is that the signaling endpoint returns a signalToken but I do not know what to do with that. It's possible that they are using custom web socket servers through aws which somehow incorporate the token but it's hard to tell. From all I have ready Amazon simply creates a signaling server on request and the websocket setup is from them.

The live url endpoint seems to return nothing for the v3 cams implying they probably don't use it and for the doorbell pro I can't seem to authorize the request correctly. The mars endpoint seems to be for getting stored events that the cameras have recorded which is useful but not entirely.

carTloyal123 commented 1 year ago

I'll test my webrtc client with the v3 cams and see if that gets anywhere.

carTloyal123 commented 1 year ago

Quick update: WebRTC for V3 cams is working. I have a JavaScript implementation that will stream the video to a webpage. Just need to investigate converting that to python and how to convert the frame data to something more friendly if needed.

On the other hand, same exact setup does not work with Video Doorbell Pro so not sure what is going on with that. I imagine it has to do with some extra authentication or again, pinging the doorbell somehow to start sending data over the connection. Might have to do with pinging the doorbell bridge to setup the live connection.

mrlt8 commented 1 year ago

Awesome, can you post some more details for the non-doorbells? We could probably stick that into the webUI for now.

As for the doorbell, are you getting the signaling url from webrtc.api? Have you tried:

https://wyze-mars-service.wyzecam.com/signaling/device/{mac}?use_trickle=true

Is the doorbell pro showing up as unsupported on view.wyze.com? It could be like the outdoor cams which aren't supported on the web view because they also need a wake command sent to the base station.

holocronology commented 1 year ago

I would be happy to join in the testing.

mrlt8 commented 1 year ago

Ok, so I had a look at the wyze app to see if we can wake the doorbell and it looks like the Doorbell Pro (mars) and the new OG/3X (gemini) are actually using Tencent Cloud's P2P protocol for streaming video to the app.

For reference, the other cameras (Hualai) are using the ThroughTek Kalay platform.

carTloyal123 commented 1 year ago

That's very good to know. How are you profiling the app to find extra info?

I'll look into that platform and see about adding it alongside the TUTK platform that is already implemented.

So WebRTC is basically only for some of the updated firmware on V2 cams? Is it worth continuing to work on WebRTC and implementing it in the bridge?

carTloyal123 commented 1 year ago

You can see some of the test code I was using for the WebRTC/AWS Kinesis here at this repo: https://github.com/carTloyal123/wyze-webrtc-kinesis-tools

I will clean it up when I have time but a decent bit of it will be useful in the client script.