Skip to content

Commit 549da02

Browse files
authored
Merge pull request #1745 from seydx/optimize-ring
Optimize ring
2 parents 2b5f942 + d286980 commit 549da02

File tree

7 files changed

+778
-521
lines changed

7 files changed

+778
-521
lines changed

README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ Ultimate camera streaming application with support for RTSP, WebRTC, HomeKit, FF
6969
* [Source: Hass](#source-hass)
7070
* [Source: ISAPI](#source-isapi)
7171
* [Source: Nest](#source-nest)
72+
* [Source: Ring](#source-ring)
7273
* [Source: Roborock](#source-roborock)
7374
* [Source: WebRTC](#source-webrtc)
7475
* [Source: WebTorrent](#source-webtorrent)
@@ -199,6 +200,7 @@ Available source types:
199200
- [bubble](#source-bubble) - streaming from ESeeCloud/dvr163 NVR
200201
- [dvrip](#source-dvrip) - streaming from DVR-IP NVR
201202
- [tapo](#source-tapo) - TP-Link Tapo cameras with [two way audio](#two-way-audio) support
203+
- [ring](#source-ring) - Ring cameras with [two way audio](#two-way-audio) support
202204
- [kasa](#source-tapo) - TP-Link Kasa cameras
203205
- [gopro](#source-gopro) - GoPro cameras
204206
- [ivideon](#source-ivideon) - public cameras from [Ivideon](https://tv.ivideon.com/) service
@@ -220,6 +222,7 @@ Supported sources:
220222
- [Hikvision ISAPI](#source-isapi) cameras
221223
- [Roborock vacuums](#source-roborock) models with cameras
222224
- [Exec](#source-exec) audio on server
225+
- [Ring](#source-ring) cameras
223226
- [Any Browser](#incoming-browser) as IP-camera
224227

225228
Two-way audio can be used in browser with [WebRTC](#module-webrtc) technology. The browser will give access to the microphone only for HTTPS sites ([read more](https://stackoverflow.com/questions/52759992/how-to-access-camera-and-microphone-in-chrome-without-https)).
@@ -646,6 +649,16 @@ streams:
646649
nest-doorbell: nest:?client_id=***&client_secret=***&refresh_token=***&project_id=***&device_id=***
647650
```
648651

652+
#### Source: Ring
653+
654+
This source type support Ring cameras with [two way audio](#two-way-audio) support. If you have a `refresh_token` and `device_id` - you can use it in `go2rtc.yaml` config file. Otherwise, you can use the go2rtc interface and add your ring account (WebUI > Add > Ring). Once added, it will list all your Ring cameras.
655+
656+
```yaml
657+
streams:
658+
ring: ring:?device_id=XXX&refresh_token=XXX
659+
ring_snapshot: ring:?device_id=XXX&refresh_token=XXX&snapshot
660+
```
661+
649662
#### Source: Roborock
650663

651664
*[New in v1.3.0](https://github.com/AlexxIT/go2rtc/releases/tag/v1.3.0)*

internal/ring/ring.go

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package ring
22

33
import (
4-
"encoding/json"
54
"net/http"
65
"net/url"
76

7+
"fmt"
8+
89
"github.com/AlexxIT/go2rtc/internal/api"
910
"github.com/AlexxIT/go2rtc/internal/streams"
1011
"github.com/AlexxIT/go2rtc/pkg/core"
@@ -21,16 +22,16 @@ func Init() {
2122

2223
func apiRing(w http.ResponseWriter, r *http.Request) {
2324
query := r.URL.Query()
24-
var ringAPI *ring.RingRestClient
25-
var err error
25+
var ringAPI *ring.RingApi
2626

2727
// Check auth method
2828
if email := query.Get("email"); email != "" {
2929
// Email/Password Flow
3030
password := query.Get("password")
3131
code := query.Get("code")
3232

33-
ringAPI, err = ring.NewRingRestClient(ring.EmailAuth{
33+
var err error
34+
ringAPI, err = ring.NewRestClient(ring.EmailAuth{
3435
Email: email,
3536
Password: password,
3637
}, nil)
@@ -44,7 +45,7 @@ func apiRing(w http.ResponseWriter, r *http.Request) {
4445
if _, err = ringAPI.GetAuth(code); err != nil {
4546
if ringAPI.Using2FA {
4647
// Return 2FA prompt
47-
json.NewEncoder(w).Encode(map[string]interface{}{
48+
api.ResponseJSON(w, map[string]interface{}{
4849
"needs_2fa": true,
4950
"prompt": ringAPI.PromptFor2FA,
5051
})
@@ -53,36 +54,39 @@ func apiRing(w http.ResponseWriter, r *http.Request) {
5354
http.Error(w, err.Error(), http.StatusInternalServerError)
5455
return
5556
}
56-
} else {
57+
} else if refreshToken := query.Get("refresh_token"); refreshToken != "" {
5758
// Refresh Token Flow
58-
refreshToken := query.Get("refresh_token")
5959
if refreshToken == "" {
6060
http.Error(w, "either email/password or refresh_token is required", http.StatusBadRequest)
6161
return
6262
}
6363

64-
ringAPI, err = ring.NewRingRestClient(ring.RefreshTokenAuth{
64+
var err error
65+
ringAPI, err = ring.NewRestClient(ring.RefreshTokenAuth{
6566
RefreshToken: refreshToken,
6667
}, nil)
68+
6769
if err != nil {
6870
http.Error(w, err.Error(), http.StatusInternalServerError)
6971
return
7072
}
73+
} else {
74+
http.Error(w, "either email/password or refresh token is required", http.StatusBadRequest)
75+
return
7176
}
7277

73-
// Fetch devices
7478
devices, err := ringAPI.FetchRingDevices()
7579
if err != nil {
7680
http.Error(w, err.Error(), http.StatusInternalServerError)
7781
return
7882
}
7983

80-
// Create clean query with only required parameters
8184
cleanQuery := url.Values{}
8285
cleanQuery.Set("refresh_token", ringAPI.RefreshToken)
8386

8487
var items []*api.Source
8588
for _, camera := range devices.AllCameras {
89+
cleanQuery.Set("camera_id", fmt.Sprint(camera.ID))
8690
cleanQuery.Set("device_id", camera.DeviceID)
8791

8892
// Stream source

0 commit comments

Comments
 (0)