mirror of
https://github.com/AlexxIT/go2rtc.git
synced 2025-09-26 20:31:11 +08:00
153 lines
3.9 KiB
Go
153 lines
3.9 KiB
Go
package yandex
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"github.com/AlexxIT/go2rtc/internal/webrtc"
|
|
"github.com/AlexxIT/go2rtc/pkg/core"
|
|
xwebrtc "github.com/AlexxIT/go2rtc/pkg/webrtc"
|
|
"github.com/google/uuid"
|
|
"github.com/gorilla/websocket"
|
|
pion "github.com/pion/webrtc/v4"
|
|
)
|
|
|
|
func goloomClient(serviceURL, serviceName, roomId, participantId, credentials string) (core.Producer, error) {
|
|
conn, _, err := websocket.DefaultDialer.Dial(serviceURL, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer func() {
|
|
time.Sleep(time.Second)
|
|
_ = conn.Close()
|
|
}()
|
|
|
|
s := fmt.Sprintf(`{"hello": {
|
|
"credentials":"%s","participantId":"%s","roomId":"%s","serviceName":"%s","sdkInitializationId":"%s",
|
|
"capabilitiesOffer":{},"sendAudio":false,"sendSharing":false,"sendVideo":false,
|
|
"sdkInfo":{"hwConcurrency":4,"implementation":"browser","version":"5.4.0"},
|
|
"participantAttributes":{"description":"","name":"mike","role":"SPEAKER"},
|
|
"participantMeta":{"description":"","name":"mike","role":"SPEAKER","sendAudio":false,"sendVideo":false}
|
|
},"uid":"%s"}`,
|
|
credentials, participantId, roomId, serviceName,
|
|
uuid.NewString(), uuid.NewString(),
|
|
)
|
|
|
|
err = conn.WriteMessage(websocket.TextMessage, []byte(s))
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if _, _, err = conn.ReadMessage(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
pc, err := webrtc.PeerConnection(true)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
prod := xwebrtc.NewConn(pc)
|
|
prod.FormatName = "yandex"
|
|
prod.Mode = core.ModeActiveProducer
|
|
prod.Protocol = "wss"
|
|
|
|
var connState core.Waiter
|
|
|
|
prod.Listen(func(msg any) {
|
|
switch msg := msg.(type) {
|
|
case pion.PeerConnectionState:
|
|
switch msg {
|
|
case pion.PeerConnectionStateConnecting:
|
|
case pion.PeerConnectionStateConnected:
|
|
connState.Done(nil)
|
|
default:
|
|
connState.Done(errors.New("webrtc: " + msg.String()))
|
|
}
|
|
}
|
|
})
|
|
|
|
go func() {
|
|
for {
|
|
var msg map[string]json.RawMessage
|
|
if err = conn.ReadJSON(&msg); err != nil {
|
|
return
|
|
}
|
|
|
|
for k, v := range msg {
|
|
switch k {
|
|
case "uid":
|
|
continue
|
|
case "serverHello":
|
|
case "subscriberSdpOffer":
|
|
var sdp subscriberSdp
|
|
if err = json.Unmarshal(v, &sdp); err != nil {
|
|
return
|
|
}
|
|
//log.Trace().Msgf("offer:\n%s", sdp.Sdp)
|
|
if err = prod.SetOffer(sdp.Sdp); err != nil {
|
|
return
|
|
}
|
|
if sdp.Sdp, err = prod.GetAnswer(); err != nil {
|
|
return
|
|
}
|
|
//log.Trace().Msgf("answer:\n%s", sdp.Sdp)
|
|
|
|
var raw []byte
|
|
if raw, err = json.Marshal(sdp); err != nil {
|
|
return
|
|
}
|
|
s = fmt.Sprintf(`{"uid":"%s","subscriberSdpAnswer":%s}`, uuid.NewString(), raw)
|
|
if err = conn.WriteMessage(websocket.TextMessage, []byte(s)); err != nil {
|
|
return
|
|
}
|
|
case "webrtcIceCandidate":
|
|
var candidate webrtcIceCandidate
|
|
if err = json.Unmarshal(v, &candidate); err != nil {
|
|
return
|
|
}
|
|
if err = prod.AddCandidate(candidate.Candidate); err != nil {
|
|
return
|
|
}
|
|
}
|
|
//log.Trace().Msgf("%s : %s", k, v)
|
|
}
|
|
|
|
if msg["ack"] != nil {
|
|
continue
|
|
}
|
|
|
|
s = fmt.Sprintf(`{"uid":%s,"ack":{"status":{"code":"OK"}}}`, msg["uid"])
|
|
if err = conn.WriteMessage(websocket.TextMessage, []byte(s)); err != nil {
|
|
return
|
|
}
|
|
}
|
|
}()
|
|
|
|
if err = connState.Wait(); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
s = fmt.Sprintf(`{"uid":"%s","setSlots":{"slots":[{"width":0,"height":0}],"audioSlotsCount":0,"key":1,"shutdownAllVideo":false,"withSelfView":false,"selfViewVisibility":"ON_LOADING_THEN_HIDE","gridConfig":{}}}`, uuid.NewString())
|
|
if err = conn.WriteMessage(websocket.TextMessage, []byte(s)); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return prod, nil
|
|
}
|
|
|
|
type subscriberSdp struct {
|
|
PcSeq int `json:"pcSeq"`
|
|
Sdp string `json:"sdp"`
|
|
}
|
|
|
|
type webrtcIceCandidate struct {
|
|
PcSeq int `json:"pcSeq"`
|
|
Target string `json:"target"`
|
|
Candidate string `json:"candidate"`
|
|
SdpMid string `json:"sdpMid"`
|
|
SdpMlineIndex int `json:"sdpMlineIndex"`
|
|
}
|