mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-11-01 20:22:33 +08:00
Code refactoring for SwitchBot format support #1629
This commit is contained in:
@@ -41,7 +41,7 @@ func streamsHandler(rawURL string) (core.Producer, error) {
|
|||||||
// https://aws.amazon.com/kinesis/video-streams/
|
// https://aws.amazon.com/kinesis/video-streams/
|
||||||
// https://docs.aws.amazon.com/kinesisvideostreams-webrtc-dg/latest/devguide/what-is-kvswebrtc.html
|
// https://docs.aws.amazon.com/kinesisvideostreams-webrtc-dg/latest/devguide/what-is-kvswebrtc.html
|
||||||
// https://github.com/orgs/awslabs/repositories?q=kinesis+webrtc
|
// https://github.com/orgs/awslabs/repositories?q=kinesis+webrtc
|
||||||
return kinesisClient(rawURL, query, "webrtc/kinesis", &kinesisClientOpts{})
|
return kinesisClient(rawURL, query, "webrtc/kinesis", nil)
|
||||||
} else if format == "openipc" {
|
} else if format == "openipc" {
|
||||||
return openIPCClient(rawURL, query)
|
return openIPCClient(rawURL, query)
|
||||||
} else if format == "switchbot" {
|
} else if format == "switchbot" {
|
||||||
|
|||||||
@@ -34,12 +34,10 @@ func (k kinesisResponse) String() string {
|
|||||||
return fmt.Sprintf("type=%s, payload=%s", k.Type, k.Payload)
|
return fmt.Sprintf("type=%s, payload=%s", k.Type, k.Payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
type kinesisClientOpts struct {
|
func kinesisClient(
|
||||||
SessionDescriptionModifier func(*pion.SessionDescription) ([]byte, error)
|
rawURL string, query url.Values, format string,
|
||||||
MediaModifier func() ([]*core.Media, error)
|
sdpOffer func(prod *webrtc.Conn, query url.Values) (any, error),
|
||||||
}
|
) (core.Producer, error) {
|
||||||
|
|
||||||
func kinesisClient(rawURL string, query url.Values, format string, opts *kinesisClientOpts) (core.Producer, error) {
|
|
||||||
// 1. Connect to signalign server
|
// 1. Connect to signalign server
|
||||||
conn, _, err := websocket.DefaultDialer.Dial(rawURL, nil)
|
conn, _, err := websocket.DefaultDialer.Dial(rawURL, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -113,34 +111,33 @@ func kinesisClient(rawURL string, query url.Values, format string, opts *kinesis
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
medias := []*core.Media{
|
var payload any
|
||||||
{Kind: core.KindVideo, Direction: core.DirectionRecvonly},
|
|
||||||
{Kind: core.KindAudio, Direction: core.DirectionRecvonly},
|
if sdpOffer == nil {
|
||||||
}
|
medias := []*core.Media{
|
||||||
if opts.MediaModifier != nil {
|
{Kind: core.KindVideo, Direction: core.DirectionRecvonly},
|
||||||
medias, err = opts.MediaModifier()
|
{Kind: core.KindAudio, Direction: core.DirectionRecvonly},
|
||||||
if err != nil {
|
}
|
||||||
|
|
||||||
|
// 4. Create offer
|
||||||
|
var offer string
|
||||||
|
if offer, err = prod.CreateOffer(medias); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// 5. Send offer
|
||||||
|
payload = pion.SessionDescription{
|
||||||
|
Type: pion.SDPTypeOffer,
|
||||||
|
SDP: offer,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if payload, err = sdpOffer(prod, query); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Create offer
|
|
||||||
offer, err := prod.CreateOffer(medias)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. Send offer
|
|
||||||
req.Action = "SDP_OFFER"
|
req.Action = "SDP_OFFER"
|
||||||
sessionDescription := pion.SessionDescription{
|
req.Payload, _ = json.Marshal(payload)
|
||||||
Type: pion.SDPTypeOffer,
|
|
||||||
SDP: offer,
|
|
||||||
}
|
|
||||||
if opts.SessionDescriptionModifier != nil {
|
|
||||||
req.Payload, _ = opts.SessionDescriptionModifier(&sessionDescription)
|
|
||||||
} else {
|
|
||||||
req.Payload, _ = json.Marshal(sessionDescription)
|
|
||||||
}
|
|
||||||
if err = conn.WriteJSON(req); err != nil {
|
if err = conn.WriteJSON(req); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -234,5 +231,5 @@ func wyzeClient(rawURL string) (core.Producer, error) {
|
|||||||
"ice_servers": []string{string(kvs.Servers)},
|
"ice_servers": []string{string(kvs.Servers)},
|
||||||
}
|
}
|
||||||
|
|
||||||
return kinesisClient(kvs.URL, query, "webrtc/wyze", &kinesisClientOpts{})
|
return kinesisClient(kvs.URL, query, "webrtc/wyze", nil)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,62 +1,40 @@
|
|||||||
package webrtc
|
package webrtc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/AlexxIT/go2rtc/pkg/core"
|
"github.com/AlexxIT/go2rtc/pkg/core"
|
||||||
pion "github.com/pion/webrtc/v3"
|
"github.com/AlexxIT/go2rtc/pkg/webrtc"
|
||||||
)
|
)
|
||||||
|
|
||||||
// SessionDescription is used to expose local and remote session descriptions.
|
|
||||||
type SwitchBotSessionDescription struct {
|
|
||||||
Type string `json:"type"`
|
|
||||||
SDP string `json:"sdp"`
|
|
||||||
Resolution SwitchBotResolution `json:"resolution"`
|
|
||||||
PlayType int `json:"play_type"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func switchbotClient(rawURL string, query url.Values) (core.Producer, error) {
|
func switchbotClient(rawURL string, query url.Values) (core.Producer, error) {
|
||||||
return kinesisClient(rawURL, query, "webrtc/switchbot", &kinesisClientOpts{
|
return kinesisClient(rawURL, query, "webrtc/switchbot", func(prod *webrtc.Conn, query url.Values) (any, error) {
|
||||||
SessionDescriptionModifier: func(sd *pion.SessionDescription) ([]byte, error) {
|
medias := []*core.Media{
|
||||||
resolution, ok := parseSwitchBotResolution(query.Get("resolution"))
|
{Kind: core.KindVideo, Direction: core.DirectionRecvonly},
|
||||||
if !ok {
|
}
|
||||||
resolution = SwitchBotResolutionSD
|
|
||||||
}
|
offer, err := prod.CreateOffer(medias)
|
||||||
json, err := json.Marshal(SwitchBotSessionDescription{
|
if err != nil {
|
||||||
Type: sd.Type.String(),
|
return nil, err
|
||||||
SDP: sd.SDP,
|
}
|
||||||
Resolution: resolution,
|
|
||||||
PlayType: 0,
|
v := struct {
|
||||||
})
|
Type string `json:"type"`
|
||||||
return json, err
|
SDP string `json:"sdp"`
|
||||||
},
|
Resolution int `json:"resolution"`
|
||||||
MediaModifier: func() ([]*core.Media, error) {
|
PlayType int `json:"play_type"`
|
||||||
return []*core.Media{
|
}{
|
||||||
{Kind: core.KindVideo, Direction: core.DirectionRecvonly},
|
Type: "offer",
|
||||||
//{Kind: core.KindAudio, Direction: core.DirectionRecvonly},
|
SDP: offer,
|
||||||
//{Kind: core.KindAudio, Direction: core.DirectionSendRecv},
|
}
|
||||||
//{Kind: "Data", Direction: core.DirectionSendRecv},
|
|
||||||
}, nil
|
switch query.Get("resolution") {
|
||||||
},
|
case "hd":
|
||||||
|
v.Resolution = 0
|
||||||
|
case "sd":
|
||||||
|
v.Resolution = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
return v, nil
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type SwitchBotResolution int
|
|
||||||
|
|
||||||
const (
|
|
||||||
SwitchBotResolutionHD SwitchBotResolution = 0
|
|
||||||
SwitchBotResolutionSD = 1
|
|
||||||
)
|
|
||||||
|
|
||||||
func parseSwitchBotResolution(str string) (SwitchBotResolution, bool) {
|
|
||||||
var (
|
|
||||||
resolutionMap = map[string]SwitchBotResolution{
|
|
||||||
"hd": SwitchBotResolutionHD,
|
|
||||||
"sd": SwitchBotResolutionSD,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
c, ok := resolutionMap[strings.ToLower(str)]
|
|
||||||
return c, ok
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user