Skip to content

Commit e304f4f

Browse files
committed
Add support creality format for webrtc client #1600
1 parent 7d37f64 commit e304f4f

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

internal/webrtc/client.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ func streamsHandler(rawURL string) (core.Producer, error) {
5454
} else if format == "wyze" {
5555
// https://github.com/mrlt8/docker-wyze-bridge
5656
return wyzeClient(rawURL)
57+
} else if format == "creality" {
58+
return crealityClient(rawURL)
5759
} else {
5860
return whepClient(rawURL)
5961
}

internal/webrtc/client_creality.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package webrtc
2+
3+
import (
4+
"encoding/base64"
5+
"encoding/json"
6+
"io"
7+
"net/http"
8+
"strings"
9+
"time"
10+
11+
"github.com/AlexxIT/go2rtc/pkg/core"
12+
"github.com/AlexxIT/go2rtc/pkg/webrtc"
13+
)
14+
15+
// https://github.com/AlexxIT/go2rtc/issues/1600
16+
func crealityClient(url string) (core.Producer, error) {
17+
pc, err := PeerConnection(true)
18+
if err != nil {
19+
return nil, err
20+
}
21+
22+
prod := webrtc.NewConn(pc)
23+
prod.FormatName = "webrtc/creality"
24+
prod.Mode = core.ModeActiveProducer
25+
prod.Protocol = "http"
26+
prod.URL = url
27+
28+
medias := []*core.Media{
29+
{Kind: core.KindVideo, Direction: core.DirectionRecvonly},
30+
{Kind: core.KindAudio, Direction: core.DirectionRecvonly},
31+
}
32+
33+
// TODO: return webrtc.SessionDescription
34+
offer, err := prod.CreateCompleteOffer(medias)
35+
if err != nil {
36+
return nil, err
37+
}
38+
39+
body, err := offerToB64(offer)
40+
if err != nil {
41+
return nil, err
42+
}
43+
44+
req, err := http.NewRequest("POST", url, body)
45+
if err != nil {
46+
return nil, err
47+
}
48+
req.Header.Set("Content-Type", "plain/text")
49+
50+
// TODO: change http.DefaultClient settings
51+
client := http.Client{Timeout: time.Second * 5000}
52+
defer client.CloseIdleConnections()
53+
54+
res, err := client.Do(req)
55+
if err != nil {
56+
return nil, err
57+
}
58+
59+
answer, err := answerFromB64(res.Body)
60+
if err != nil {
61+
return nil, err
62+
}
63+
64+
if err = prod.SetAnswer(answer); err != nil {
65+
return nil, err
66+
}
67+
68+
return prod, nil
69+
}
70+
71+
func offerToB64(sdp string) (io.Reader, error) {
72+
// JS object
73+
v := map[string]string{
74+
"type": "offer",
75+
"sdp": sdp,
76+
}
77+
78+
// bytes
79+
b, err := json.Marshal(v)
80+
if err != nil {
81+
return nil, err
82+
}
83+
84+
// base64, why? who knows...
85+
s := base64.StdEncoding.EncodeToString(b)
86+
87+
return strings.NewReader(s), nil
88+
}
89+
90+
func answerFromB64(r io.Reader) (string, error) {
91+
// base64
92+
b, err := io.ReadAll(r)
93+
if err != nil {
94+
return "", err
95+
}
96+
97+
// bytes
98+
if b, err = base64.StdEncoding.DecodeString(string(b)); err != nil {
99+
return "", err
100+
}
101+
102+
// JS object
103+
var v map[string]string
104+
if err = json.Unmarshal(b, &v); err != nil {
105+
return "", err
106+
}
107+
108+
// string "v=0..."
109+
return v["sdp"], nil
110+
}

0 commit comments

Comments
 (0)