Files
meet-api/peer.go
Smile Rex f85d36b183
All checks were successful
Create and publish a Docker image 🚀 / build-and-push-image (push) Successful in 1m34s
add files and ci
2026-01-26 15:18:05 +03:00

101 lines
1.8 KiB
Go

package main
import (
"encoding/json"
"github.com/google/uuid"
"github.com/gorilla/websocket"
"github.com/pion/webrtc/v4"
)
type Peer struct {
ID string
Conn *websocket.Conn
PC *webrtc.PeerConnection
Room *Room
Senders map[string]*webrtc.RTPSender
}
type Signal struct {
Type string `json:"type"`
Data json.RawMessage `json:"data"`
}
func NewPeer(conn *websocket.Conn) *Peer {
pc, _ := webrtc.NewPeerConnection(webrtc.Configuration{})
p := &Peer{
ID: uuid.NewString(),
Conn: conn,
PC: pc,
Senders: make(map[string]*webrtc.RTPSender),
}
pc.OnTrack(func(track *webrtc.TrackRemote, _ *webrtc.RTPReceiver) {
localTrack := NewTrack(track)
p.Room.ForwardTrack(p, localTrack)
for {
pkt, _, err := track.ReadRTP()
if err != nil {
return
}
localTrack.Write(pkt)
}
})
pc.OnICECandidate(func(c *webrtc.ICECandidate) {
if c == nil {
return
}
msg, _ := json.Marshal(c.ToJSON())
p.Send("ice", msg)
})
return p
}
func (p *Peer) AddTrack(track *Track) {
_, err := p.PC.AddTrack(track.Local)
if err != nil {
return
}
p.Send("renegotiate", nil)
}
func (p *Peer) ReadLoop() {
defer p.Conn.Close()
for {
var msg Signal
if err := p.Conn.ReadJSON(&msg); err != nil {
return
}
switch msg.Type {
case "offer":
var offer webrtc.SessionDescription
json.Unmarshal(msg.Data, &offer)
p.PC.SetRemoteDescription(offer)
answer, _ := p.PC.CreateAnswer(nil)
p.PC.SetLocalDescription(answer)
data, _ := json.Marshal(answer)
p.Send("answer", data)
case "ice":
var c webrtc.ICECandidateInit
json.Unmarshal(msg.Data, &c)
p.PC.AddICECandidate(c)
}
}
}
func (p *Peer) Send(t string, data []byte) {
msg := Signal{Type: t, Data: data}
p.Conn.WriteJSON(msg)
}