-
Notifications
You must be signed in to change notification settings - Fork 1
/
http.go
108 lines (88 loc) · 2.52 KB
/
http.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package main
import (
"encoding/json"
"github.com/pion/webrtc/v3"
"log"
"net/http"
)
var iceServers []string
func InitWebRTCPApi(icesrvs []string) {
iceServers = icesrvs
}
func OnNewPeer(w http.ResponseWriter, r *http.Request) {
// Only allow one HTTP method to call this API
if r.Method != "POST" {
log.Println("Invalid HTTP method!")
http.Error(w, "Invalid HTTP method!", http.StatusBadRequest)
return
}
// Check that the offer sent to us is not malformed and that we can continue
var offer webrtc.SessionDescription
if err := json.NewDecoder(r.Body).Decode(&offer); err != nil {
http.Error(w, "Bad session description!", http.StatusBadRequest)
return
}
// Create a peer and add the video track to it so
peerConnection := MakePeer()
peerConnection.OnConnectionStateChange(func(state webrtc.PeerConnectionState) {
log.Printf("PeerConnection state changed: %s", state)
switch state {
case webrtc.PeerConnectionStateDisconnected:
fallthrough
case webrtc.PeerConnectionStateFailed:
log.Println("Explicitly closing peer connection...")
_ = peerConnection.Close()
}
})
// Initialise the object with the offer we got from the peer (to negotiate
if err := peerConnection.SetRemoteDescription(offer); err != nil {
log.Panicln(err)
}
// Apply negotiation algo to decide on communication/what tracks get sent
answer, err := peerConnection.CreateAnswer(nil)
if err != nil {
panic(err)
}
gatherComplete := webrtc.GatheringCompletePromise(peerConnection)
// Initialise peer object with our reply to the offer presented by peer
if err = peerConnection.SetLocalDescription(answer); err != nil {
panic(err)
}
// Wait for us to check whether/how we can communicate with peer (via ICE)
<-gatherComplete
// Send our reply to peer as via HTTP
response, err := json.Marshal(peerConnection.LocalDescription())
if err != nil {
log.Panicln(err)
}
w.Header().Set("Content-Type", "application/json")
if _, err := w.Write(response); err != nil {
log.Panicln(err)
}
}
func MakePeer() *webrtc.PeerConnection {
peerConnection, err := webrtc.NewPeerConnection(webrtc.Configuration{
ICEServers: []webrtc.ICEServer{
{
URLs: iceServers,
},
},
})
if err != nil {
log.Panicln(err)
}
rtpSender, err := peerConnection.AddTrack(track)
if err != nil {
log.Panicln(err)
}
go InfiniteRTCPRead(rtpSender)
return peerConnection
}
func InfiniteRTCPRead(client *webrtc.RTPSender) {
rtcpBuf := make([]byte, 1500)
for {
if _, _, rtcpErr := client.Read(rtcpBuf); rtcpErr != nil {
return
}
}
}