mirror of
https://github.com/harshabose/client.git
synced 2025-09-26 19:31:20 +08:00
150 lines
3.9 KiB
Go
150 lines
3.9 KiB
Go
package client
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
|
|
"github.com/pion/interceptor"
|
|
"github.com/pion/interceptor/pkg/cc"
|
|
"github.com/pion/webrtc/v4"
|
|
|
|
"github.com/harshabose/tools/pkg/multierr"
|
|
)
|
|
|
|
type Client struct {
|
|
peerConnections map[string]*PeerConnection
|
|
mediaEngine *webrtc.MediaEngine
|
|
settingsEngine *webrtc.SettingEngine
|
|
interceptorRegistry *interceptor.Registry
|
|
estimatorChan chan cc.BandwidthEstimator
|
|
api *webrtc.API
|
|
ctx context.Context
|
|
cancel context.CancelFunc
|
|
}
|
|
|
|
func NewClient(
|
|
ctx context.Context, cancel context.CancelFunc,
|
|
mediaEngine *webrtc.MediaEngine, interceptorRegistry *interceptor.Registry,
|
|
settings *webrtc.SettingEngine, options ...ClientOption,
|
|
) (*Client, error) {
|
|
if mediaEngine == nil {
|
|
mediaEngine = &webrtc.MediaEngine{}
|
|
}
|
|
if interceptorRegistry == nil {
|
|
interceptorRegistry = &interceptor.Registry{}
|
|
}
|
|
if settings == nil {
|
|
settings = &webrtc.SettingEngine{}
|
|
}
|
|
|
|
settings.DetachDataChannels()
|
|
|
|
peerConnections := &Client{
|
|
mediaEngine: mediaEngine,
|
|
interceptorRegistry: interceptorRegistry,
|
|
settingsEngine: settings,
|
|
peerConnections: make(map[string]*PeerConnection),
|
|
estimatorChan: make(chan cc.BandwidthEstimator, 10),
|
|
ctx: ctx,
|
|
cancel: cancel,
|
|
}
|
|
|
|
for _, option := range options {
|
|
if err := option(peerConnections); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
peerConnections.api = webrtc.NewAPI(webrtc.WithMediaEngine(peerConnections.mediaEngine), webrtc.WithInterceptorRegistry(peerConnections.interceptorRegistry), webrtc.WithSettingEngine(*peerConnections.settingsEngine))
|
|
|
|
return peerConnections, nil
|
|
}
|
|
|
|
func NewClientFromConfig(
|
|
ctx context.Context, cancel context.CancelFunc,
|
|
mediaEngine *webrtc.MediaEngine, interceptorRegistry *interceptor.Registry,
|
|
settings *webrtc.SettingEngine, config *ClientConfig,
|
|
) (*Client, error) {
|
|
return NewClient(
|
|
ctx, cancel, mediaEngine, interceptorRegistry, settings,
|
|
config.ToOptions()..., // The magic spread operator!
|
|
)
|
|
}
|
|
|
|
func (client *Client) CreatePeerConnection(label string, config webrtc.Configuration, options ...PeerConnectionOption) (*PeerConnection, error) {
|
|
var err error
|
|
|
|
if _, exists := client.peerConnections[label]; exists {
|
|
return nil, errors.New("peer connection already exists")
|
|
}
|
|
|
|
// TODO: CHANGE THE SIGNATURE; SENDING A CANCEL FUNC IS IDIOTIC
|
|
if client.peerConnections[label], err = CreatePeerConnection(client.ctx, client.cancel, label, client.api, config, options...); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return client.peerConnections[label], nil
|
|
}
|
|
|
|
func (client *Client) CreatePeerConnectionFromConfig(config PeerConnectionConfig) (*PeerConnection, error) {
|
|
pc, err := client.CreatePeerConnection(config.Name, config.RTCConfig, config.ToOptions()...)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := config.CreateDataChannels(pc); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := config.CreateMediaSources(pc); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if err := config.CreateMediaSinks(pc); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return pc, nil
|
|
}
|
|
|
|
func (client *Client) GetPeerConnection(label string) (*PeerConnection, error) {
|
|
if _, exists := client.peerConnections[label]; !exists {
|
|
return nil, errors.New("peer connection not found")
|
|
}
|
|
return client.peerConnections[label], nil
|
|
}
|
|
|
|
func (client *Client) WaitUntilClosed() {
|
|
<-client.ctx.Done()
|
|
}
|
|
|
|
func (client *Client) Connect(category string) error {
|
|
var merr error
|
|
for _, pc := range client.peerConnections {
|
|
if err := pc.Connect(category); err != nil {
|
|
merr = multierr.Append(merr, err)
|
|
}
|
|
}
|
|
|
|
return merr
|
|
}
|
|
|
|
func (client *Client) ClosePeerConnection(label string) error {
|
|
pc, err := client.GetPeerConnection(label)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return pc.Close()
|
|
}
|
|
|
|
func (client *Client) Close() error {
|
|
for _, peerConnection := range client.peerConnections {
|
|
if err := peerConnection.Close(); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|