Esempio n. 1
0
        public static Task <RTCMediaStreamTrackConfiguration> GetTrackConfigurationForCapabilities(RTCRtpCapabilities sourceCapabilities, RTCRtpCodecCapability preferredCodec)
        {
            if (preferredCodec == null)
            {
                throw new ArgumentNullException(nameof(preferredCodec));
            }

            return(Task.Run(() =>
            {
                var capabilities = RTCRtpCapabilities.Clone(sourceCapabilities);

                // scoope: move prefered codec to be first in the list
                {
                    var itemsToRemove = capabilities.Codecs.Where(x => x.PreferredPayloadType == preferredCodec.PreferredPayloadType).ToList();
                    if (itemsToRemove.Count > 0)
                    {
                        RTCRtpCodecCapability codecCapability = itemsToRemove.First();
                        var modifyList = capabilities.Codecs.ToList();
                        if (codecCapability != null && modifyList.IndexOf(codecCapability) > 0)
                        {
                            modifyList.Remove(codecCapability);
                            modifyList.Insert(0, codecCapability);
                        }
                        capabilities.Codecs = modifyList;
                    }
                }

                RTCMediaStreamTrackConfiguration configuration = new RTCMediaStreamTrackConfiguration()
                {
                    Capabilities = capabilities
                };
                return configuration;
            }));
        }
Esempio n. 2
0
        public Task <IList <ICodec> > GetCodecsAsync(MediaKind kind)
        {
            IList <ICodec> videoCodecsList = new List <ICodec>();
            IList <ICodec> audioCodecsList = new List <ICodec>();

            if (kind == MediaKind.AudioCodec)
            {
                return(Task.Run(() =>
                {
                    RTCRtpCapabilities audioCapabilities = RTCRtpSender.GetCapabilities(new WebRtcFactory(new WebRtcFactoryConfiguration()), "audio");
                    IReadOnlyList <RTCRtpCodecCapability> audioCodecs = audioCapabilities.Codecs;
                    foreach (var item in audioCodecs)
                    {
                        string payload = item.PreferredPayloadType.ToString();

                        Codec audioCodec = new Codec();
                        audioCodec.SetMediaKind(MediaKind.AudioCodec);
                        audioCodec.SetId(payload);
                        audioCodec.SetDisplayName(item.Name + " " + payload);
                        audioCodec.SetRate((int)item.ClockRate);

                        audioCodecsList.Add(audioCodec);
                    }
                    return audioCodecsList;
                }));
            }

            if (kind == MediaKind.VideoCodec)
            {
                return(Task.Run(() =>
                {
                    RTCRtpCapabilities videoCapabilities = RTCRtpSender.GetCapabilities(new WebRtcFactory(new WebRtcFactoryConfiguration()), "video");
                    IReadOnlyList <RTCRtpCodecCapability> videoCodecs = videoCapabilities.Codecs;
                    foreach (var item in videoCodecs)
                    {
                        string payload = item.PreferredPayloadType.ToString();

                        Codec videoCodec = new Codec();
                        videoCodec.SetMediaKind(MediaKind.VideoCodec);
                        videoCodec.SetId(payload);
                        videoCodec.SetDisplayName(item.Name + " " + payload);
                        videoCodec.SetRate((int)item.ClockRate);

                        videoCodecsList.Add(videoCodec);
                    }

                    return videoCodecsList;
                }));
            }
            else
            {
                return(null);
            }
        }
Esempio n. 3
0
        public void ReceiverGetAudioCapabilities()
        {
            RTCRtpCapabilities capabilities = RTCRtpReceiver.GetCapabilities(TrackKind.Audio);

            Assert.NotNull(capabilities);
            Assert.NotNull(capabilities.codecs);
            Assert.IsNotEmpty(capabilities.codecs);
            Assert.NotNull(capabilities.headerExtensions);
            Assert.IsNotEmpty(capabilities.headerExtensions);

            foreach (var codec in capabilities.codecs)
            {
                Assert.NotNull(codec);
                Assert.IsNotEmpty(codec.mimeType);
            }
            foreach (var extensions in capabilities.headerExtensions)
            {
                Assert.NotNull(extensions);
                Assert.IsNotEmpty(extensions.uri);
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Creates a peer connection.
        /// </summary>
        /// <returns>True if connection to a peer is successfully created.</returns>
        private async Task <bool> CreatePeerConnection(CancellationToken cancelationToken)
        {
            Debug.Assert(_peerConnection == null);
            if (cancelationToken.IsCancellationRequested)
            {
                return(false);
            }

            var config = new RTCConfiguration()
            {
                BundlePolicy = RTCBundlePolicy.Balanced,
#if ORTCLIB
                SignalingMode = _signalingMode,
                GatherOptions = new RTCIceGatherOptions()
                {
                    IceServers = new List <RTCIceServer>(_iceServers),
                }
#else
                IceTransportPolicy = RTCIceTransportPolicy.All,
                IceServers         = _iceServers
#endif
            };

            Debug.WriteLine("Conductor: Creating peer connection.");
            _peerConnection = new RTCPeerConnection(config);

            if (_peerConnection == null)
            {
                throw new NullReferenceException("Peer connection is not created.");
            }

#if !ORTCLIB
            _peerConnection.EtwStatsEnabled = _etwStatsEnabled;
            _peerConnection.ConnectionHealthStatsEnabled = _peerConnectionStatsEnabled;
#endif
            if (cancelationToken.IsCancellationRequested)
            {
                return(false);
            }
#if ORTCLIB
            OrtcStatsManager.Instance.Initialize(_peerConnection);
#endif
            OnPeerConnectionCreated?.Invoke();

            _peerConnection.OnIceCandidate += PeerConnection_OnIceCandidate;
#if ORTCLIB
            _peerConnection.OnTrack     += PeerConnection_OnAddTrack;
            _peerConnection.OnTrackGone += PeerConnection_OnRemoveTrack;
            _peerConnection.OnIceConnectionStateChange += () => { Debug.WriteLine("Conductor: Ice connection state change, state=" + (null != _peerConnection ? _peerConnection.IceConnectionState.ToString() : "closed")); };
#else
            _peerConnection.OnAddStream             += PeerConnection_OnAddStream;
            _peerConnection.OnRemoveStream          += PeerConnection_OnRemoveStream;
            _peerConnection.OnConnectionHealthStats += PeerConnection_OnConnectionHealthStats;
#endif
            Debug.WriteLine("Conductor: Getting user media.");
            RTCMediaStreamConstraints mediaStreamConstraints = new RTCMediaStreamConstraints
            {
                // Always include audio/video enabled in the media stream,
                // so it will be possible to enable/disable audio/video if
                // the call was initiated without microphone/camera
                audioEnabled = true,
                videoEnabled = true
            };

            if (cancelationToken.IsCancellationRequested)
            {
                return(false);
            }

#if ORTCLIB
            var tracks = await _media.GetUserMedia(mediaStreamConstraints);

            if (tracks != null)
            {
                RTCRtpCapabilities audioCapabilities = RTCRtpSender.GetCapabilities("audio");
                RTCRtpCapabilities videoCapabilities = RTCRtpSender.GetCapabilities("video");

                _mediaStream = new MediaStream(tracks);
                Debug.WriteLine("Conductor: Adding local media stream.");
                IList <MediaStream> mediaStreamList = new List <MediaStream>();
                mediaStreamList.Add(_mediaStream);
                foreach (var mediaStreamTrack in tracks)
                {
                    //Create stream track configuration based on capabilities
                    RTCMediaStreamTrackConfiguration configuration = null;
                    if (mediaStreamTrack.Kind == MediaStreamTrackKind.Audio && audioCapabilities != null)
                    {
                        configuration =
                            await Helper.GetTrackConfigurationForCapabilities(audioCapabilities, AudioCodec);
                    }
                    else if (mediaStreamTrack.Kind == MediaStreamTrackKind.Video && videoCapabilities != null)
                    {
                        configuration =
                            await Helper.GetTrackConfigurationForCapabilities(videoCapabilities, VideoCodec);
                    }
                    if (configuration != null)
                    {
                        _peerConnection.AddTrack(mediaStreamTrack, mediaStreamList, configuration);
                    }
                }
            }
#else
            _mediaStream = await _media.GetUserMedia(mediaStreamConstraints);
#endif

            if (cancelationToken.IsCancellationRequested)
            {
                return(false);
            }

#if !ORTCLIB
            Debug.WriteLine("Conductor: Adding local media stream.");
            _peerConnection.AddStream(_mediaStream);
#endif
            OnAddLocalStream?.Invoke(new MediaStreamEvent()
            {
                Stream = _mediaStream
            });

            if (cancelationToken.IsCancellationRequested)
            {
                return(false);
            }
            return(true);
        }