mirror of
https://github.com/livekit/livekit.git
synced 2026-03-30 15:35:41 +00:00
Due to the order of events in MediaTrackReceiver and friends, SubscribedTrack will be closed before the track is removed from RoomTrackManager. Because of this, when a track is unpublished, it's possible to be subscribed to the track as it's closing. By introducing a closing state, we'd prevent accidental subscription to closing tracks.
126 lines
3.5 KiB
Go
126 lines
3.5 KiB
Go
/*
|
|
* Copyright 2023 LiveKit, Inc
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package rtc
|
|
|
|
import (
|
|
"sync"
|
|
|
|
"github.com/livekit/livekit-server/pkg/rtc/types"
|
|
"github.com/livekit/livekit-server/pkg/utils"
|
|
"github.com/livekit/protocol/livekit"
|
|
)
|
|
|
|
// RoomTrackManager holds tracks that are published to the room
|
|
type RoomTrackManager struct {
|
|
lock sync.RWMutex
|
|
changedNotifier *utils.ChangeNotifierManager
|
|
removedNotifier *utils.ChangeNotifierManager
|
|
tracks map[livekit.TrackID]*TrackInfo
|
|
}
|
|
|
|
type TrackInfo struct {
|
|
Track types.MediaTrack
|
|
PublisherIdentity livekit.ParticipantIdentity
|
|
PublisherID livekit.ParticipantID
|
|
}
|
|
|
|
func NewRoomTrackManager() *RoomTrackManager {
|
|
return &RoomTrackManager{
|
|
tracks: make(map[livekit.TrackID]*TrackInfo),
|
|
changedNotifier: utils.NewChangeNotifierManager(),
|
|
removedNotifier: utils.NewChangeNotifierManager(),
|
|
}
|
|
}
|
|
|
|
func (r *RoomTrackManager) AddTrack(track types.MediaTrack, publisherIdentity livekit.ParticipantIdentity, publisherID livekit.ParticipantID) {
|
|
r.lock.Lock()
|
|
r.tracks[track.ID()] = &TrackInfo{
|
|
Track: track,
|
|
PublisherIdentity: publisherIdentity,
|
|
PublisherID: publisherID,
|
|
}
|
|
r.lock.Unlock()
|
|
|
|
r.NotifyTrackChanged(track.ID())
|
|
}
|
|
|
|
func (r *RoomTrackManager) RemoveTrack(track types.MediaTrack) {
|
|
r.lock.Lock()
|
|
// ensure we are removing the same track as added
|
|
info, ok := r.tracks[track.ID()]
|
|
if !ok || info.Track != track {
|
|
r.lock.Unlock()
|
|
return
|
|
}
|
|
delete(r.tracks, track.ID())
|
|
r.lock.Unlock()
|
|
|
|
n := r.removedNotifier.GetNotifier(string(track.ID()))
|
|
if n != nil {
|
|
n.NotifyChanged()
|
|
}
|
|
|
|
r.changedNotifier.RemoveNotifier(string(track.ID()), true)
|
|
r.removedNotifier.RemoveNotifier(string(track.ID()), true)
|
|
}
|
|
|
|
func (r *RoomTrackManager) GetTrackInfo(trackID livekit.TrackID) *TrackInfo {
|
|
r.lock.RLock()
|
|
defer r.lock.RUnlock()
|
|
|
|
info := r.tracks[trackID]
|
|
if info == nil {
|
|
return nil
|
|
}
|
|
// when track is about to close, do not resolve
|
|
if info.Track != nil && !info.Track.IsOpen() {
|
|
return nil
|
|
}
|
|
return info
|
|
}
|
|
|
|
func (r *RoomTrackManager) NotifyTrackChanged(trackID livekit.TrackID) {
|
|
n := r.changedNotifier.GetNotifier(string(trackID))
|
|
if n != nil {
|
|
n.NotifyChanged()
|
|
}
|
|
}
|
|
|
|
// HasObservers lets caller know if the current media track has any observers
|
|
// this is used to signal interest in the track. when another MediaTrack with the same
|
|
// trackID is being used, track is not considered to be observed.
|
|
func (r *RoomTrackManager) HasObservers(track types.MediaTrack) bool {
|
|
n := r.changedNotifier.GetNotifier(string(track.ID()))
|
|
if n == nil || !n.HasObservers() {
|
|
return false
|
|
}
|
|
|
|
info := r.GetTrackInfo(track.ID())
|
|
if info == nil || info.Track != track {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (r *RoomTrackManager) GetOrCreateTrackChangeNotifier(trackID livekit.TrackID) *utils.ChangeNotifier {
|
|
return r.changedNotifier.GetOrCreateNotifier(string(trackID))
|
|
}
|
|
|
|
func (r *RoomTrackManager) GetOrCreateTrackRemoveNotifier(trackID livekit.TrackID) *utils.ChangeNotifier {
|
|
return r.removedNotifier.GetOrCreateNotifier(string(trackID))
|
|
}
|