package mediadevices import ( "sync" "github.com/pion/webrtc/v4" ) // MediaStream is an interface that represents a collection of existing tracks. type MediaStream interface { // GetAudioTracks implements https://w3c.github.io/mediacapture-main/#dom-mediastream-getaudiotracks GetAudioTracks() []Track // GetVideoTracks implements https://w3c.github.io/mediacapture-main/#dom-mediastream-getvideotracks GetVideoTracks() []Track // GetTracks implements https://w3c.github.io/mediacapture-main/#dom-mediastream-gettracks GetTracks() []Track // AddTrack implements https://w3c.github.io/mediacapture-main/#dom-mediastream-addtrack AddTrack(t Track) // RemoveTrack implements https://w3c.github.io/mediacapture-main/#dom-mediastream-removetrack RemoveTrack(t Track) } type mediaStream struct { tracks map[Track]struct{} l sync.RWMutex } const trackTypeDefault webrtc.RTPCodecType = 0 // NewMediaStream creates a MediaStream interface that's defined in // https://w3c.github.io/mediacapture-main/#dom-mediastream func NewMediaStream(tracks ...Track) (MediaStream, error) { m := mediaStream{tracks: make(map[Track]struct{})} for _, track := range tracks { if _, ok := m.tracks[track]; !ok { m.tracks[track] = struct{}{} } } return &m, nil } func (m *mediaStream) GetAudioTracks() []Track { return m.queryTracks(webrtc.RTPCodecTypeAudio) } func (m *mediaStream) GetVideoTracks() []Track { return m.queryTracks(webrtc.RTPCodecTypeVideo) } func (m *mediaStream) GetTracks() []Track { return m.queryTracks(trackTypeDefault) } // queryTracks returns all tracks that are the same kind as t. // If t is 0, which is the default, queryTracks will return all the tracks. func (m *mediaStream) queryTracks(t webrtc.RTPCodecType) []Track { m.l.RLock() defer m.l.RUnlock() result := make([]Track, 0) for track := range m.tracks { if track.Kind() == t || t == trackTypeDefault { result = append(result, track) } } return result } func (m *mediaStream) AddTrack(t Track) { m.l.Lock() defer m.l.Unlock() if _, ok := m.tracks[t]; ok { return } m.tracks[t] = struct{}{} } func (m *mediaStream) RemoveTrack(t Track) { m.l.Lock() defer m.l.Unlock() delete(m.tracks, t) }