public LocalVideoLink(VideoRouter parent, VideoSource source, IPeerConnection target) { if (source is null) { throw new ArgumentNullException(nameof(source)); } if (target is null) { throw new ArgumentNullException(nameof(target)); } if (null == source.VideoTrackSource) { throw new InvalidProgramException("VideoTrackSource is NULL"); } TargetPeerConnection = target; VideoSource = source; _parent = parent ?? throw new ArgumentNullException(nameof(parent)); // Create track var trackId = Guid.NewGuid(); _track = parent.PeerConnectionFactory.CreateVideoTrack(trackId.ToString(), source.VideoTrackSource); // Find the first available transceiver (or create it) GetOrCreateTransceiver(out var transceiver, out var isReusingTransceiver); Transceiver = transceiver; // Next, set/replace the track: Transceiver.ToBusyState(_track); // If we're re-using an existing transceivers. // Transceiver metadata will need to be sent for clients to update their UIs. // If we are creating new transceivers, no need to do this, // since PeerConnection will re-negotiate automatically if (isReusingTransceiver) { RaiseTransceiverMetadataUdatedEvent(); } // If stream id has not been set, set it. // WebRTC does not allow us to change the stream id, but we don't care either, // we just want it to be unique. if (string.IsNullOrWhiteSpace(Transceiver.Sender.StreamId)) { Transceiver.Sender.StreamId = Guid.NewGuid().ToString(); } // Add track to peer _logger.Debug($"Local track created {_track}"); }
public VideoSource CreateVideoSource(Guid videoClientId, MediaQuality mediaQuality) { ThrowWhenKeyNotExist(videoClientId); if (_indexById[videoClientId].VideoSources.ContainsKey(mediaQuality)) { throw new InvalidOperationException(); } var t = new VideoSource(_indexById[videoClientId], mediaQuality); _indexById[videoClientId].VideoSources[mediaQuality] = t; return(t); }
void OnVideoSourceAdded(Client client, VideoSource videoSource, MediaQuality mediaQuality) { _signallingThread.EnsureCurrentThread(); // As new video source is added, // we'll have to connect this source to any existing sending-PeerConnection foreach (var otherClients in _clients .OtherThan(client) .Where(other => other.DesiredMediaQuality == mediaQuality && other.PeerConnections.Count > 0)) { var localVideoLink = new LocalVideoLink( this, videoSource, otherClients.PeerConnections[0]); _localVideoLinks.Add(localVideoLink); _logger.Debug($"Added {localVideoLink} into {_localVideoLinks}"); } }
public void RemoveByVideoSource(VideoSource videoSource) { if (_indexByVideoSource.ContainsKey(videoSource)) { var links = _indexByVideoSource[videoSource].ToList(); for (int i = 0; i < links.Count; i++) { var link = links[i]; if (false == _indexByPeerConnection.ContainsKey(link.TargetPeerConnection)) { throw new InvalidProgramException(); } using (link) { _indexByPeerConnection.Remove(link.TargetPeerConnection, link); } } _indexByVideoSource.Remove(videoSource); } }