Beispiel #1
0
        /// <summary>
        /// <para>Events:</para>
        /// <para>@emits icestatechange - (iceState: IceState)</para>
        /// <para>@emits iceselectedtuplechange - (iceSelectedTuple: TransportTuple)</para>
        /// <para>@emits dtlsstatechange - (dtlsState: DtlsState)</para>
        /// <para>@emits sctpstatechange - (sctpState: SctpState)</para>
        /// <para>@emits trace - (trace: TransportTraceEventData)</para>
        /// <para>Observer events:</para>
        /// <para>@emits close</para>
        /// <para>@emits newproducer - (producer: Producer)</para>
        /// <para>@emits newconsumer - (consumer: Consumer)</para>
        /// <para>@emits newdataproducer - (dataProducer: DataProducer)</para>
        /// <para>@emits newdataconsumer - (dataConsumer: DataConsumer)</para>
        /// <para>@emits icestatechange - (iceState: IceState)</para>
        /// <para>@emits iceselectedtuplechange - (iceSelectedTuple: TransportTuple)</para>
        /// <para>@emits dtlsstatechange - (dtlsState: DtlsState)</para>
        /// <para>@emits sctpstatechange - (sctpState: SctpState)</para>
        /// <para>@emits trace - (trace: TransportTraceEventData)</para>
        /// </summary>
        /// <param name="loggerFactory"></param>
        /// <param name="transportInternalData"></param>
        /// <param name="sctpParameters"></param>
        /// <param name="sctpState"></param>
        /// <param name="channel"></param>
        /// <param name="payloadChannel"></param>
        /// <param name="appData"></param>
        /// <param name="getRouterRtpCapabilities"></param>
        /// <param name="getProducerById"></param>
        /// <param name="getDataProducerById"></param>
        /// <param name="iceRole"></param>
        /// <param name="iceParameters"></param>
        /// <param name="iceCandidates"></param>
        /// <param name="iceState"></param>
        /// <param name="iceSelectedTuple"></param>
        /// <param name="dtlsParameters"></param>
        /// <param name="dtlsState"></param>
        /// <param name="dtlsRemoteCert"></param>
        public WebRtcTransport(ILoggerFactory loggerFactory,
                               TransportInternalData transportInternalData,
                               SctpParameters?sctpParameters,
                               SctpState?sctpState,
                               Channel channel,
                               PayloadChannel payloadChannel,
                               Dictionary <string, object>?appData,
                               Func <RtpCapabilities> getRouterRtpCapabilities,
                               Func <string, Producer?> getProducerById,
                               Func <string, DataProducer?> getDataProducerById,
                               string iceRole,
                               IceParameters iceParameters,
                               IceCandidate[] iceCandidates,
                               IceState iceState,
                               TransportTuple?iceSelectedTuple,
                               DtlsParameters dtlsParameters,
                               DtlsState dtlsState,
                               string?dtlsRemoteCert) : base(loggerFactory, transportInternalData, sctpParameters, sctpState, channel, payloadChannel, appData, getRouterRtpCapabilities, getProducerById, getDataProducerById)
        {
            _logger = loggerFactory.CreateLogger <WebRtcTransport>();

            // Data
            IceRole          = iceRole;
            IceParameters    = iceParameters;
            IceCandidates    = iceCandidates;
            IceState         = iceState;
            IceSelectedTuple = iceSelectedTuple;
            DtlsParameters   = dtlsParameters;
            DtlsState        = dtlsState;
            DtlsRemoteCert   = dtlsRemoteCert;

            HandleWorkerNotifications();
        }
Beispiel #2
0
        /// <summary>
        /// <para>Events:</para>
        /// <para>@emits transportclose</para>
        /// <para>@emits producerclose</para>
        /// <para>@emits producerpause</para>
        /// <para>@emits producerresume</para>
        /// <para>@emits score - (score: ConsumerScore)</para>
        /// <para>@emits layerschange - (layers: ConsumerLayers | undefined)</para>
        /// <para>@emits trace - (trace: ConsumerTraceEventData)</para>
        /// <para>@emits @close</para>
        /// <para>@emits @producerclose</para>
        /// <para>Observer events:</para>
        /// <para>@emits close</para>
        /// <para>@emits pause</para>
        /// <para>@emits resume</para>
        /// <para>@emits score - (score: ConsumerScore)</para>
        /// <para>@emits layerschange - (layers: ConsumerLayers | undefined)</para>
        /// <para>@emits rtp - (packet: Buffer)</para>
        /// <para>@emits trace - (trace: ConsumerTraceEventData)</para>
        /// </summary>
        /// <param name="loggerFactory"></param>
        /// <param name="consumerInternalData"></param>
        /// <param name="kind"></param>
        /// <param name="rtpParameters"></param>
        /// <param name="type"></param>
        /// <param name="channel"></param>
        /// <param name="appData"></param>
        /// <param name="paused"></param>
        /// <param name="producerPaused"></param>
        /// <param name="score"></param>
        /// <param name="preferredLayers"></param>
        public Consumer(ILoggerFactory loggerFactory,
                        ConsumerInternalData consumerInternalData,
                        MediaKind kind,
                        RtpParameters rtpParameters,
                        ConsumerType type,
                        Channel channel,
                        PayloadChannel payloadChannel,
                        Dictionary <string, object>?appData,
                        bool paused,
                        bool producerPaused,
                        ConsumerScore?score,
                        ConsumerLayers?preferredLayers
                        )
        {
            _logger = loggerFactory.CreateLogger <Consumer>();

            // Internal
            _internal = consumerInternalData;

            // Data
            Kind          = kind;
            RtpParameters = rtpParameters;
            Type          = type;

            _channel        = channel;
            _payloadChannel = payloadChannel;
            AppData         = appData;
            _paused         = paused;
            ProducerPaused  = producerPaused;
            Score           = score;
            PreferredLayers = preferredLayers;

            HandleWorkerNotifications();
        }
Beispiel #3
0
        /// <summary>
        /// <para>Events:</para>
        /// <para>@emits transportclose</para>
        /// <para>@emits @close</para>
        /// <para>Observer events:</para>
        /// <para>@emits close</para>
        /// </summary>
        /// <param name="loggerFactory"></param>
        /// <param name="dataProducerInternalData"></param>
        /// <param name="sctpStreamParameters"></param>
        /// <param name="label"></param>
        /// <param name="protocol"></param>
        /// <param name="channel"></param>
        /// <param name="payloadChannel"></param>
        /// <param name="appData"></param>
        public DataProducer(ILoggerFactory loggerFactory,
                            DataProducerInternalData dataProducerInternalData,
                            SctpStreamParameters sctpStreamParameters,
                            string label,
                            string protocol,
                            Channel channel,
                            PayloadChannel payloadChannel,
                            Dictionary <string, object>?appData
                            )
        {
            _logger = loggerFactory.CreateLogger <DataProducer>();

            // Internal
            _internal = dataProducerInternalData;

            // Data
            SctpStreamParameters = sctpStreamParameters;
            Label    = label;
            Protocol = protocol;

            _channel        = channel;
            _payloadChannel = payloadChannel;
            AppData         = appData;

            HandleWorkerNotifications();
        }
Beispiel #4
0
        /// <summary>
        /// <para>Events:</para>
        /// <para>@emits transportclose</para></para>
        /// <para>@emits score - (score: ProducerScore[])</para>
        /// <para>@emits videoorientationchange - (videoOrientation: ProducerVideoOrientation)</para>
        /// <para>@emits trace - (trace: ProducerTraceEventData)</para>
        /// <para>@emits @close</para>
        /// <para>Observer events:</para>
        /// <para>@emits close</para>
        /// <para>@emits pause</para>
        /// <para>@emits resume</para>
        /// <para>@emits score - (score: ProducerScore[])</para>
        /// <para>@emits videoorientationchange - (videoOrientation: ProducerVideoOrientation)</para>
        /// <para>@emits trace - (trace: ProducerTraceEventData)</para>
        /// </summary>
        /// <param name="loggerFactory"></param>
        /// <param name="producerInternalData"></param>
        /// <param name="kind"></param>
        /// <param name="rtpParameters"></param>
        /// <param name="type"></param>
        /// <param name="consumableRtpParameters"></param>
        /// <param name="channel"></param>
        /// <param name="appData"></param>
        /// <param name="paused"></param>
        public Producer(ILoggerFactory loggerFactory,
                        ProducerInternalData producerInternalData,
                        MediaKind kind,
                        RtpParameters rtpParameters,
                        ProducerType type,
                        RtpParameters consumableRtpParameters,
                        Channel channel,
                        PayloadChannel payloadChannel,
                        Dictionary <string, object>?appData,
                        bool paused
                        )
        {
            _logger = loggerFactory.CreateLogger <Producer>();

            // Internal
            _internal = producerInternalData;

            // Data
            Kind                    = kind;
            RtpParameters           = rtpParameters;
            Type                    = type;
            ConsumableRtpParameters = consumableRtpParameters;

            _channel        = channel;
            _payloadChannel = payloadChannel;
            AppData         = appData;
            _paused         = paused;

            if (_isCheckConsumer)
            {
                _checkConsumersTimer = new Timer(CheckConsumers, null, TimeSpan.FromSeconds(CheckConsumersTimeSeconds), TimeSpan.FromMilliseconds(-1));
            }
            HandleWorkerNotifications();
        }
Beispiel #5
0
        /// <summary>
        /// <para>Events:</para>
        /// <para>@emits sctpstatechange - (sctpState: SctpState)</para>
        /// <para>@emits trace - (trace: TransportTraceEventData)</para>
        /// <para>Observer events:</para>
        /// <para>@emits close</para>
        /// <para>@emits newproducer - (producer: Producer)</para>
        /// <para>@emits newconsumer - (consumer: Consumer)</para>
        /// <para>@emits newdataproducer - (dataProducer: DataProducer)</para>
        /// <para>@emits newdataconsumer - (dataConsumer: DataConsumer)</para>
        /// <para>@emits sctpstatechange - (sctpState: SctpState)</para>
        /// <para>@emits trace - (trace: TransportTraceEventData)</para>
        /// </summary>
        /// <param name="loggerFactory"></param>
        /// <param name="transportInternalData"></param>
        /// <param name="sctpParameters"></param>
        /// <param name="sctpState"></param>
        /// <param name="channel"></param>
        /// <param name="payloadChannel"></param>
        /// <param name="appData"></param>
        /// <param name="getRouterRtpCapabilities"></param>
        /// <param name="getProducerById"></param>
        /// <param name="getDataProducerById"></param>
        public PipeTransport(ILoggerFactory loggerFactory,
                             TransportInternalData transportInternalData,
                             SctpParameters?sctpParameters,
                             SctpState?sctpState,
                             Channel channel,
                             PayloadChannel payloadChannel,
                             Dictionary <string, object>?appData,
                             Func <RtpCapabilities> getRouterRtpCapabilities,
                             Func <string, Producer?> getProducerById,
                             Func <string, DataProducer?> getDataProducerById,
                             TransportTuple tuple,
                             bool rtx,
                             SrtpParameters?srtpParameters
                             ) : base(loggerFactory, transportInternalData, sctpParameters, sctpState, channel, payloadChannel, appData, getRouterRtpCapabilities, getProducerById, getDataProducerById)
        {
            _loggerFactory = loggerFactory;
            _logger        = loggerFactory.CreateLogger <PipeTransport>();

            // Data
            Tuple          = tuple;
            Rtx            = rtx;
            SrtpParameters = srtpParameters;

            HandleWorkerNotifications();
        }
Beispiel #6
0
        /// <summary>
        /// <para>Events:</para>
        /// <para>@emits routerclose</para>
        /// <para>@emits @close</para>
        /// <para>@emits @newproducer - (producer: Producer)</para>
        /// <para>@emits @producerclose - (producer: Producer)</para>
        /// <para>@emits @newdataproducer - (dataProducer: DataProducer)</para>
        /// <para>@emits @dataproducerclose - (dataProducer: DataProducer)</para>
        /// <para>Observer events:</para>
        /// <para>@emits close</para>
        /// <para>@emits newproducer - (producer: Producer)</para>
        /// <para>@emits newconsumer - (producer: Producer)</para>
        /// <para>@emits newdataproducer - (dataProducer: DataProducer)</para>
        /// <para>@emits newdataconsumer - (dataProducer: DataProducer)</para>
        /// </summary>
        /// <param name="loggerFactory"></param>
        /// <param name="transportInternalData"></param>
        /// <param name="sctpParameters"></param>
        /// <param name="sctpState"></param>
        /// <param name="channel"></param>
        /// <param name="payloadChannel"></param>
        /// <param name="appData"></param>
        /// <param name="getRouterRtpCapabilities"></param>
        /// <param name="getProducerById"></param>
        /// <param name="getDataProducerById"></param>
        protected Transport(ILoggerFactory loggerFactory,
                            TransportInternalData transportInternalData,
                            SctpParameters?sctpParameters,
                            SctpState?sctpState,
                            Channel channel,
                            PayloadChannel payloadChannel,
                            Dictionary <string, object>?appData,
                            Func <RtpCapabilities> getRouterRtpCapabilities,
                            Func <string, Producer?> getProducerById,
                            Func <string, DataProducer?> getDataProducerById
                            )
        {
            _loggerFactory = loggerFactory;
            _logger        = loggerFactory.CreateLogger <Transport>();

            // Internal
            Internal = transportInternalData;

            // Data
            SctpParameters = sctpParameters;
            SctpState      = sctpState;

            Channel                  = channel;
            PayloadChannel           = payloadChannel;
            AppData                  = appData;
            GetRouterRtpCapabilities = getRouterRtpCapabilities;
            GetProducerById          = getProducerById;
            GetDataProducerById      = getDataProducerById;

            ProducersLock.Set();
            ConsumersLock.Set();
            DataProducersLock.Set();
            DataConsumersLock.Set();
            CloseLock.Set();
        }
Beispiel #7
0
 /// <summary>
 /// <para>Events:</para>
 /// <para>@emits volumes - (volumes: AudioLevelObserverVolume[])</para>
 /// <para>@emits silence</para>
 /// <para>Observer events:</para>
 /// <para>@emits close</para>
 /// <para>@emits pause</para>
 /// <para>@emits resume</para>
 /// <para>@emits addproducer - (producer: Producer)</para>
 /// <para>@emits removeproducer - (producer: Producer)</para>
 /// <para>@emits volumes - (volumes: AudioLevelObserverVolume[])</para>
 /// <para>@emits silence</para>
 /// </summary>
 /// <param name="loggerFactory"></param>
 /// <param name="rtpObserverInternalData"></param>
 /// <param name="channel"></param>
 /// <param name="payloadChannel"></param>
 /// <param name="appData"></param>
 /// <param name="getProducerById"></param>
 public ActiveSpeakerObserver(ILoggerFactory loggerFactory,
                              RtpObserverInternalData rtpObserverInternalData,
                              Channel channel,
                              PayloadChannel payloadChannel,
                              Dictionary <string, object>?appData,
                              Func <string, Producer?> getProducerById
                              ) : base(loggerFactory, rtpObserverInternalData, channel, payloadChannel, appData, getProducerById)
 {
     _logger = loggerFactory.CreateLogger <ActiveSpeakerObserver>();
 }
Beispiel #8
0
        /// <summary>
        /// <para>Events:</para>
        /// <para>@emits rtcp - (packet: Buffer)</para>
        /// <para>@emits trace - (trace: TransportTraceEventData)</para>
        /// <para>Observer events:</para>
        /// <para>@emits close</para>
        /// <para>@emits newdataproducer - (dataProducer: DataProducer)</para>
        /// <para>@emits newdataconsumer - (dataProducer: DataProducer)</para>
        /// <para>@emits trace - (trace: TransportTraceEventData)</para>
        /// </summary>
        /// <param name="loggerFactory"></param>
        /// <param name="transportInternalData"></param>
        /// <param name="sctpParameters"></param>
        /// <param name="sctpState"></param>
        /// <param name="channel"></param>
        /// <param name="appData"></param>
        /// <param name="getRouterRtpCapabilities"></param>
        /// <param name="getProducerById"></param>
        /// <param name="getDataProducerById"></param>
        public DirectTransport(ILoggerFactory loggerFactory,
                               TransportInternalData transportInternalData,
                               SctpParameters?sctpParameters,
                               SctpState?sctpState,
                               Channel channel,
                               PayloadChannel payloadChannel,
                               Dictionary <string, object>?appData,
                               Func <RtpCapabilities> getRouterRtpCapabilities,
                               Func <string, Producer?> getProducerById,
                               Func <string, DataProducer?> getDataProducerById
                               ) : base(loggerFactory, transportInternalData, sctpParameters, sctpState, channel, payloadChannel, appData, getRouterRtpCapabilities, getProducerById, getDataProducerById)
        {
            _logger = loggerFactory.CreateLogger <DirectTransport>();

            // Data

            HandleWorkerNotifications();
        }
Beispiel #9
0
        /// <summary>
        /// <para>Events:</para>
        /// <para>@emits routerclose</para>
        /// <para>@emits @close</para>
        /// <para>Observer events:</para>
        /// <para>@emits close</para>
        /// <para>@emits pause</para>
        /// <para>@emits resume</para>
        /// <para>@emits addproducer - (producer: Producer)</para>
        /// <para>@emits removeproducer - (producer: Producer)</para>
        /// </summary>
        /// <param name="loggerFactory"></param>
        /// <param name="rtpObserverInternalData"></param>
        /// <param name="channel"></param>
        /// <param name="payloadChannel"></param>
        /// <param name="appData"></param>
        /// <param name="getProducerById"></param>
        protected RtpObserver(ILoggerFactory loggerFactory,
                              RtpObserverInternalData rtpObserverInternalData,
                              Channel channel,
                              PayloadChannel payloadChannel,
                              Dictionary <string, object>?appData,
                              Func <string, Producer?> getProducerById
                              )
        {
            _logger = loggerFactory.CreateLogger <RtpObserver>();

            // Internal
            Internal = rtpObserverInternalData;

            Channel         = channel;
            PayloadChannel  = payloadChannel;
            AppData         = appData;
            GetProducerById = getProducerById;
            HandleWorkerNotifications();
        }
Beispiel #10
0
 /// <summary>
 /// <para>Events:</para>
 /// <para>@emits workerclose</para>
 /// <para>@emits @close</para>
 /// <para>Observer events:</para>
 /// <para>@emits close</para>
 /// <para>@emits newtransport - (transport: Transport)</para>
 /// <para>@emits newrtpobserver - (rtpObserver: RtpObserver)</para>
 /// </summary>
 /// <param name="logger"></param>
 /// <param name="routerId"></param>
 /// <param name="rtpCapabilities"></param>
 /// <param name="channel"></param>
 /// <param name="payloadChannel"></param>
 /// <param name="appData"></param>
 public Router(ILoggerFactory loggerFactory,
               string routerId,
               RtpCapabilities rtpCapabilities,
               Channel channel,
               PayloadChannel payloadChannel,
               Dictionary <string, object>?appData
               )
 {
     _loggerFactory = loggerFactory;
     _logger        = loggerFactory.CreateLogger <Router>();
     _internal      = new RouterInternalData
     {
         RouterId = routerId
     };
     RtpCapabilities = rtpCapabilities;
     _channel        = channel;
     _payloadChannel = payloadChannel;
     AppData         = appData;
 }
Beispiel #11
0
        /// <summary>
        /// <para>Events:</para>
        /// <para>@emits died - (error: Error)</para>
        /// <para>@emits @success</para>
        /// <para>@emits @failure - (error: Error)</para>
        /// <para>Observer events:</para>
        /// <para>@emits close</para>
        /// <para>@emits newrouter - (router: Router)</para>
        /// </summary>
        /// <param name="loggerFactory"></param>
        /// <param name="hostEnvironment"></param>
        /// <param name="mediasoupOptions"></param>
        public Worker(ILoggerFactory loggerFactory, MediasoupOptions mediasoupOptions)
        {
            _loggerFactory = loggerFactory;
            _logger        = loggerFactory.CreateLogger <Worker>();
            _closeLock.Set();

            var workerPath = mediasoupOptions.MediasoupStartupSettings.WorkerPath;

            if (workerPath.IsNullOrWhiteSpace())
            {
                // 见:https://docs.microsoft.com/en-us/dotnet/core/rid-catalog
                string rid;
                if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
                {
                    rid = "linux";
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
                {
                    rid = "osx";
                }
                else if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
                {
                    rid = "win";
                }
                else
                {
                    throw new NotSupportedException("Unsupported platform");
                }

                var location  = Assembly.GetEntryAssembly() !.Location;
                var directory = Path.GetDirectoryName(location) !;
                workerPath = Path.Combine(directory, "runtimes", rid, "native", "mediasoup-worker");
            }

            var workerSettings = mediasoupOptions.MediasoupSettings.WorkerSettings;

            AppData = workerSettings.AppData;

            var env = new[] { $"MEDIASOUP_VERSION={mediasoupOptions.MediasoupStartupSettings.MediasoupVersion}" };

            var args = new List <string>
            {
                workerPath
            };

            if (workerSettings.LogLevel.HasValue)
            {
                args.Add($"--logLevel={workerSettings.LogLevel.Value.GetEnumMemberValue()}");
            }
            if (!workerSettings.LogTags.IsNullOrEmpty())
            {
                workerSettings.LogTags !.ForEach(m => args.Add($"--logTag={m.GetEnumMemberValue()}"));
            }
            if (workerSettings.RtcMinPort.HasValue)
            {
                args.Add($"--rtcMinPort={workerSettings.RtcMinPort}");
            }
            if (workerSettings.RtcMaxPort.HasValue)
            {
                args.Add($"--rtcMaxPort={workerSettings.RtcMaxPort}");
            }
            if (!workerSettings.DtlsCertificateFile.IsNullOrWhiteSpace())
            {
                args.Add($"--dtlsCertificateFile={workerSettings.DtlsCertificateFile}");
            }
            if (!workerSettings.DtlsPrivateKeyFile.IsNullOrWhiteSpace())
            {
                args.Add($"--dtlsPrivateKeyFile={workerSettings.DtlsPrivateKeyFile}");
            }

            _logger.LogDebug($"Worker() | Spawning worker process: {args.JoinAsString(" ")}");

            _pipes = new Pipe[StdioCount];

            // fd 0 (stdin)   : Just ignore it. (忽略标准输入)
            // fd 1 (stdout)  : Pipe it for 3rd libraries that log their own stuff.
            // fd 2 (stderr)  : Same as stdout.
            // fd 3 (channel) : Producer Channel fd.
            // fd 4 (channel) : Consumer Channel fd.
            // fd 5 (channel) : Producer PayloadChannel fd.
            // fd 6 (channel) : Consumer PayloadChannel fd.
            for (var i = 1; i < StdioCount; i++)
            {
                _pipes[i] = new Pipe()
                {
                    Writeable = true, Readable = true
                };
            }

            try
            {
                // 和 Node.js 不同,_child 没有 error 事件。不过,Process.Spawn 可抛出异常。
                _child = Process.Spawn(new ProcessOptions()
                {
                    File        = workerPath,
                    Arguments   = args.ToArray(),
                    Environment = env,
                    Detached    = false,
                    Streams     = _pipes,
                }, OnExit);

                ProcessId = _child.Id;
            }
            catch (Exception ex)
            {
                _child = null;
                CloseAsync().ConfigureAwait(false).GetAwaiter().GetResult();

                if (!_spawnDone)
                {
                    _spawnDone = true;
                    _logger.LogError(ex, $"Worker() | Worker process failed [pid:{ProcessId}]");
                    Emit("@failure", ex);
                }
                else
                {
                    // 执行到这里的可能性?
                    _logger.LogError(ex, $"Worker() | Worker process error [pid:{ProcessId}]");
                    Emit("died", ex);
                }
            }

            _channel = new Channel(_loggerFactory.CreateLogger <Channel>(), _pipes[3], _pipes[4], ProcessId);
            _channel.MessageEvent += OnChannelMessage;

            _payloadChannel = new PayloadChannel(_loggerFactory.CreateLogger <PayloadChannel>(), _pipes[5], _pipes[6], ProcessId);

            _pipes.ForEach(m => m?.Resume());
        }
Beispiel #12
0
 public void SendRtcp(byte[] rtcpPacket)
 {
     PayloadChannel.Notify("transport.sendRtcp", Internal, null, rtcpPacket);
 }