Exemplo n.º 1
0
        void GetOrCreateTransceiver(out RtpTransceiver transceiver, out bool isReusingTransceivers)
        {
            var mediaKind    = _track.Kind;
            var transceivers = TargetPeerConnection.Native.GetTransceivers();

            transceiver           = null;
            isReusingTransceivers = true;
            for (var i = 0; i < transceivers.Count; i++)
            {
                if (transceivers[i].ReusabilityState == TransceiverReusabilityState.Available &&
                    false == string.IsNullOrWhiteSpace(transceivers[i].Mid) &&
                    transceivers[i].MediaKind == mediaKind &&
                    transceivers[i].Direction != RtpTransceiverDirection.RecvOnly)
                {
                    transceiver = transceivers[i];
                    break;
                }
            }
            // If no available transceiver, create a new one
            if (transceiver is null || true)
            {
                transceiver           = TargetPeerConnection.Native.AddTransceiver(mediaKind, RtpTransceiverDirection.SendOnly);
                isReusingTransceivers = false;
            }

            transceiver.CustomData = this;
        }
Exemplo n.º 2
0
        internal void OnRemoteTrackRemoved(RtpTransceiver transceiver)
        {
            _signallingThread.EnsureCurrentThread();
            VideoRouterThrowHelper.WhenInvalidReceiver(transceiver);

            _remoteVideoLinks.RemoveByRemoteTrack(transceiver.Receiver);
            _logger.Info($"Removed {transceiver.Receiver} from {_remoteVideoLinks}");
        }
Exemplo n.º 3
0
        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}");
        }
Exemplo n.º 4
0
        public static void WhenInvalidReceiver(RtpTransceiver transceiver)
        {
            var track = transceiver.Receiver.Track;

            if (track == null)
            {
                throw new InvalidProgramException("Track is NULL");
            }

            if (string.IsNullOrWhiteSpace(track.Id))
            {
                throw new ArgumentNullException($"Track id is null for {transceiver}, Track {transceiver.Receiver.Track}");
            }
        }
Exemplo n.º 5
0
        internal void OnRemoteTrackAdded(Client client, IPeerConnection peerConnection, RtpTransceiver transceiver)
        {
            _signallingThread.EnsureCurrentThread();
            Require.NotNull(peerConnection);
            VideoRouterThrowHelper.WhenInvalidReceiver(transceiver);

            // Ignore audio tracks for now
            if (transceiver.Receiver.Track.Kind != MediaKind.Video)
            {
                return;
            }

            // What's the video source that this track should be connected to?
            var transceiverMid = transceiver.Mid;
            var videoSource    = client.VideoSources
                                 .FirstOrDefault(kv => string.Equals(kv.Value.ExpectedTransceiverMid, transceiverMid, StringComparison.InvariantCultureIgnoreCase))
                                 .Value;

            // videoSource could be null when the client doesn't have any input devices,
            // therefore it never calls SetRemoteTransceiverMetadata()
            if (videoSource != null)
            {
                VideoRouterThrowHelper.WhenSourceIsEmpty(videoSource, transceiver.Receiver);

                var remoteVideoLink = new RemoteVideoLink(peerConnection, videoSource, transceiver.Receiver);
                _remoteVideoLinks.AddOrUpdate(remoteVideoLink);
                _logger.Info($"Added {remoteVideoLink} into {_remoteVideoLinks}");
            }
        }
Exemplo n.º 6
0
 public RtpTransceiverNative(RtpTransceiver rtpTransceiverNative) : base(rtpTransceiverNative)
 {
     _rtpTransceiver = rtpTransceiverNative;
 }
Exemplo n.º 7
0
 public PlatformRtpTransceiver(RtpTransceiver transceiver) : base(transceiver) => _transceiver = transceiver;
Exemplo n.º 8
0
 private RTCRtpTransceiver(RtpTransceiver nativeTransceiver) : base(nativeTransceiver)
 {
 }