package localserver // import ( // "encoding/json" // "fmt" // "sync/atomic" // "github.com/pion/webrtc/v3" // ) // const ( // SPEAKING = "speaking" // STOP_SPEAKING = "stop_speaking" // MUTE = "mute" // UNMUTE = "unmute" // ) // type WebrtcCallSoundManager struct{} // func NewWebrtcCallSoundManager() *WebrtcCallSoundManager { // return new(WebrtcCallSoundManager) // } // func (w *WebrtcCallSoundManager) HandleCallEvent(from string, squadId string, eventId string, payload map[string]interface{}, data []byte, manager *WebRTCCallManager) (err error) { // done, errCh := make(chan struct{}), make(chan error) // go func() { // logger.Println("got an event in call sound manager", from, eventId, payload) // switch eventId { // case UNMUTE: // if e := w.unmute(from, squadId, manager); e != nil { // errCh <- e // return // } // case MUTE: // if e := w.mute(from, squadId, manager); e != nil { // errCh <- e // return // } // case SPEAKING: // if e := w.sendSpeakingEvent(from, squadId, manager); e != nil { // errCh <- e // return // } // case STOP_SPEAKING: // if e := w.sendStopSpeakingEvent(from, squadId, manager); e != nil { // errCh <- e // return // } // } // done <- struct{}{} // }() // select { // case <-done: // return nil // case err = <-errCh: // return // } // } // func (w *WebrtcCallSoundManager) unmute(peerId string, squadId string, manager *WebRTCCallManager) (err error) { // if _, ok := manager.Squads[squadId]; !ok { // err = fmt.Errorf("no correponding squad found") // return // } // logger.Println("sending unnmute event", peerId) // manager.RemoteTracksMux.RLock() // for _, v := range manager.RemoteTracks[peerId] { // if v.Track.Kind() == webrtc.RTPCodecTypeAudio { // atomic.SwapInt32(v.rdv, 0) // } // } // manager.RemoteTracksMux.RUnlock() // manager.SquadMapMux.Lock() // defer manager.SquadMapMux.Unlock() // for _, member := range manager.Squads[squadId].Members { // manager.DataChannelMapMux.Lock() // if _, ok := manager.DataChannels[member]; ok && member != peerId { // bs, marshalErr := json.Marshal(map[string]interface{}{ // "type": UNMUTE, // "from": peerId, // "payload": map[string]interface{}{}, // }) // if marshalErr != nil { // logger.Println(err) // manager.DataChannelMapMux.Unlock() // continue // } // lock: // for { // if atomic.CompareAndSwapUint32(manager.DataChannels[member].l, 0, 1) { // defer atomic.SwapUint32(manager.DataChannels[member].l, 0) // if sendErr := manager.DataChannels[member].DataChannel.SendText(string(bs)); sendErr != nil { // logger.Println(sendErr) // } // break lock // } else { // continue // } // } // } // manager.DataChannelMapMux.Unlock() // } // return // } // func (w *WebrtcCallSoundManager) mute(peerId string, squadId string, manager *WebRTCCallManager) (err error) { // if _, ok := manager.Squads[squadId]; !ok { // err = fmt.Errorf("no correponding squad found") // return // } // logger.Println("sending mute event", peerId) // manager.RemoteTracksMux.RLock() // for _, v := range manager.RemoteTracks[peerId] { // if v.Track.Kind() == webrtc.RTPCodecTypeAudio { // atomic.SwapInt32(v.rdv, 1) // } // } // manager.RemoteTracksMux.RUnlock() // manager.SquadMapMux.Lock() // defer manager.SquadMapMux.Unlock() // for _, member := range manager.Squads[squadId].Members { // manager.DataChannelMapMux.Lock() // if _, ok := manager.DataChannels[member]; ok && member != peerId { // bs, marshalErr := json.Marshal(map[string]interface{}{ // "type": MUTE, // "from": peerId, // "payload": map[string]interface{}{}, // }) // if marshalErr != nil { // logger.Println(err) // manager.DataChannelMapMux.Unlock() // continue // } // lock: // for { // if atomic.CompareAndSwapUint32(manager.DataChannels[member].l, 0, 1) { // defer atomic.SwapUint32(manager.DataChannels[member].l, 0) // if sendErr := manager.DataChannels[member].DataChannel.SendText(string(bs)); sendErr != nil { // logger.Println(sendErr) // } // break lock // } else { // continue // } // } // } // manager.DataChannelMapMux.Unlock() // } // return // } // func (w *WebrtcCallSoundManager) sendSpeakingEvent(peerId string, squadId string, manager *WebRTCCallManager) (err error) { // if _, ok := manager.Squads[squadId]; !ok { // err = fmt.Errorf("no correponding squad found") // return // } // logger.Println("sending speaking event", peerId) // manager.SquadMapMux.Lock() // defer manager.SquadMapMux.Unlock() // for _, member := range manager.Squads[squadId].Members { // manager.DataChannelMapMux.Lock() // if _, ok := manager.DataChannels[member]; ok && member != peerId { // bs, marshalErr := json.Marshal(map[string]interface{}{ // "type": SPEAKING, // "from": peerId, // "payload": map[string]interface{}{ // "userId": peerId, // "speaking": true, // }, // }) // if marshalErr != nil { // logger.Println(err) // manager.DataChannelMapMux.Unlock() // continue // } // lock: // for { // if atomic.CompareAndSwapUint32(manager.DataChannels[member].l, 0, 1) { // defer atomic.SwapUint32(manager.DataChannels[member].l, 0) // if sendErr := manager.DataChannels[member].DataChannel.SendText(string(bs)); sendErr != nil { // logger.Println(sendErr) // } // break lock // } else { // continue // } // } // } // manager.DataChannelMapMux.Unlock() // } // return // } // func (w *WebrtcCallSoundManager) sendStopSpeakingEvent(peerId string, squadId string, manager *WebRTCCallManager) (err error) { // if _, ok := manager.Squads[squadId]; !ok { // err = fmt.Errorf("no correponding squad found") // return // } // logger.Println("sending stop speaking event", peerId) // manager.SquadMapMux.Lock() // defer manager.SquadMapMux.Unlock() // for _, member := range manager.Squads[squadId].Members { // manager.DataChannelMapMux.Lock() // if _, ok := manager.DataChannels[member]; ok && member != peerId { // bs, marshalErr := json.Marshal(map[string]interface{}{ // "type": STOP_SPEAKING, // "from": peerId, // "payload": map[string]interface{}{ // "userId": peerId, // "speaking": false, // }, // }) // if marshalErr != nil { // logger.Println(err) // manager.DataChannelMapMux.Unlock() // continue // } // lock: // for { // if atomic.CompareAndSwapUint32(manager.DataChannels[member].l, 0, 1) { // defer atomic.SwapUint32(manager.DataChannels[member].l, 0) // if sendErr := manager.DataChannels[member].DataChannel.SendText(string(bs)); sendErr != nil { // logger.Println(sendErr) // } // break lock // } else { // continue // } // } // } // manager.DataChannelMapMux.Unlock() // } // return // }