Ejemplo n.º 1
0
 public HLSDataProvider(IDemuxerController demuxerController, ClipDefinition currentClip)
 {
     this.demuxerController = demuxerController ??
                              throw new ArgumentNullException(nameof(demuxerController),
                                                              "demuxerController cannot be null");
     this.currentClip =
         currentClip ?? throw new ArgumentNullException(nameof(currentClip), "clip cannot be null");
 }
Ejemplo n.º 2
0
        public bool SupportsClip(ClipDefinition clip)
        {
            if (clip == null)
            {
                throw new ArgumentNullException(nameof(clip), "Clip cannot be null.");
            }

            return(string.Equals(clip.Type, "Dash", StringComparison.CurrentCultureIgnoreCase));
        }
Ejemplo n.º 3
0
 public RTSPDataProvider(IDemuxerController demuxerController, IRTSPClient rtpClient, ClipDefinition currentClip)
 {
     this.demuxerController = demuxerController ??
                              throw new ArgumentNullException(nameof(demuxerController),
                                                              "demuxerController cannot be null");
     this.rtspClient =
         rtpClient ?? throw new ArgumentNullException(nameof(rtpClient), "rtpClient cannot be null");
     this.currentClip =
         currentClip ?? throw new ArgumentNullException(nameof(currentClip), "clip cannot be null");
 }
Ejemplo n.º 4
0
        public void GetStreamsDescription_ClipWithNoSubtitles_ReturnsEmptyList()
        {
            var demuxerMock    = Substitute.For <IDemuxerController>();
            var clipDefinition = new ClipDefinition();
            var dataProvider   = new HLSDataProvider(demuxerMock, clipDefinition);

            var streamsDescription = dataProvider.GetStreamsDescription(StreamType.Subtitle);

            Assert.That(streamsDescription, Is.Empty);
        }
Ejemplo n.º 5
0
        public async Task Seek_Called_ResumesDemuxer()
        {
            var demuxerStub    = Substitute.For <IDemuxerController>();
            var clipDefinition = new ClipDefinition();
            var dataProvider   = new HLSDataProvider(demuxerStub, clipDefinition);

            await dataProvider.Seek(TimeSpan.FromSeconds(5), CancellationToken.None);

            demuxerStub.Received().Resume();
        }
        public static void CreateDataProvider_NotSupported()
        {
            var factory = Substitute.For <IDataProviderFactory>();
            var clip    = new ClipDefinition
            {
                Type = "FAKE"
            };

            Assert.DoesNotThrow(() => manager.RegisterDataProviderFactory(factory));
            Assert.Throws <ArgumentException>(() => manager.CreateDataProvider(clip));
        }
Ejemplo n.º 7
0
        public void OnChangeActiveStream_UnknownSubtitles_ThrowsArgumentException()
        {
            var demuxerMock       = Substitute.For <IDemuxerController>();
            var clipDefinition    = new ClipDefinition();
            var dataProvider      = new HLSDataProvider(demuxerMock, clipDefinition);
            var streamDescription = new StreamDescription
            {
                StreamType = StreamType.Subtitle
            };

            Assert.Throws <ArgumentException>(() => dataProvider.ChangeActiveStream(streamDescription));
        }
Ejemplo n.º 8
0
        public Task Start(ClipDefinition clip)
        {
            if (_currentState != State.Idle)
            {
                throw new InvalidOperationException($"{nameof(_currentState)} incorrect state {_currentState}");
            }

            rtspUrl     = clip.Url;
            _rtpRtspCts = new CancellationTokenSource();
            _rtspTask   = Task.Run(async() => await RtspReader());

            return(_rtspTask);
        }
Ejemplo n.º 9
0
        public void Start(ClipDefinition clip)
        {
            if (clip == null)
            {
                throw new ArgumentNullException(nameof(clip), "clip cannot be null");
            }

            if (clip.Url.Length < 7)
            {
                throw new ArgumentException("clip url cannot be empty");
            }

            url = clip.Url;

            try
            {
                Uri       uri       = new Uri(url);
                TcpClient tcpClient = new TcpClient();
                var       task      = Task.Run(async() => { await tcpClient.ConnectAsync(uri.Host, uri.Port > 0 ? uri.Port : 554); });
                task.Wait();

                rtspSocket = new Rtsp.RtspTcpTransport(tcpClient);
                if (rtspSocket.Connected == false)
                {
                    Logger.Error("Did not connect");
                    return;
                }

                // Connect a RTSP Listener to the RTSP Socket (or other Stream) to send RTSP messages and listen for RTSP replies
                rtspListener = new Rtsp.RtspListener(rtspSocket);

                rtspListener.MessageReceived += RtspMessageReceived;
                rtspListener.DataReceived    += RtpDataReceived;

                rtspListener.Start();

                RtspRequest optionsMessage = new RtspRequestOptions
                {
                    RtspUri = new Uri(url)
                };

                rtspListener.SendMessage(optionsMessage);
            }
            catch (Exception e)
            {
                Logger.Error(e, "Did not connect");
            }
        }
Ejemplo n.º 10
0
        private async Task ExecuteStart(ClipDefinition clip, CancellationToken ctx)
        {
            if (clip == null)
            {
                throw new ArgumentNullException(nameof(clip), "Clip cannot be null.");
            }

            if (clip.Url.Length < 7)
            {
                throw new ArgumentException("Clip URL cannot be empty.");
            }

            rtspUrl = clip.Url;
            TcpClient tcpClient = new TcpClient();

            tcpClient.SendTimeout    = 10000;
            tcpClient.ReceiveTimeout = 10000;
            try
            {
                Uri uri = new Uri(rtspUrl);
                await tcpClient.ConnectAsync(uri.Host, uri.Port > 0?uri.Port : 554).WaitAsync(ctx);
            }
            catch (Exception e)
            {
                Logger.Info(e.ToString());
                tcpClient.Dispose();
                throw;
            }

            rtspSocket = new Rtsp.RtspTcpTransport(tcpClient);
            if (rtspSocket.Connected == false)
            {
                throw new Exception("RTSP server not available at this time.");
            }

            rtspListener = new Rtsp.RtspListener(rtspSocket, rtspErrorSubject);
            rtspListener.MessageReceived += RtspMessageReceived;
            rtspListener.DataReceived    += RtpDataReceived;
            rtspListener.AutoReconnect    = false;
            rtspListener.Start();

            RtspRequest optionsMessage = new RtspRequestOptions
            {
                RtspUri = new Uri(rtspUrl)
            };

            rtspListener.SendMessage(optionsMessage);
        }
Ejemplo n.º 11
0
        public async Task PacketReady_DemuxerSendsNullPacket_ProducesEOSPackets()
        {
            var demuxerStub = Substitute.For <IDemuxerController>();

            demuxerStub.PacketReady()
            .Returns(Observable.Return <Packet>(null));
            var clipDefinition = new ClipDefinition();
            var dataProvider   = new HLSDataProvider(demuxerStub, clipDefinition);

            var packets = await dataProvider.PacketReady()
                          .ToList()
                          .ToTask();

            Assert.That(packets.Count, Is.EqualTo(2));
            Assert.That(packets.All(p => p.GetType() == typeof(EOSPacket)), Is.True);
        }
Ejemplo n.º 12
0
        public IDataProvider CreateDataProvider(ClipDefinition clip)
        {
            if (clip == null)
            {
                throw new ArgumentNullException("clip cannot be null");
            }

            var factory = dataProviders.FirstOrDefault(o => o.SupportsClip(clip));

            if (factory == null)
            {
                throw new ArgumentException("clip is not supported");
            }

            return(factory.Create(clip));
        }
Ejemplo n.º 13
0
        public IDataProvider Create(ClipDefinition clip)
        {
            if (clip == null)
            {
                throw new ArgumentNullException(nameof(clip), "clip cannot be null");
            }

            if (!SupportsClip(clip))
            {
                throw new ArgumentException("unsupported clip type");
            }

            var demuxer           = new FFmpegDemuxer(new FFmpegGlue());
            var demuxerController = new DemuxerController(demuxer);

            return(new HLSDataProvider(demuxerController, clip));
        }
        public static void CreateDataProvider_OK()
        {
            var factory  = Substitute.For <IDataProviderFactory>();
            var provider = Substitute.For <IDataProvider>();
            var clip     = new ClipDefinition
            {
                Type = "TEST"
            };

            factory.SupportsClip(Arg.Is(clip)).Returns(true);
            factory.Create(Arg.Is(clip)).Returns(provider);

            Assert.DoesNotThrow(() => manager.RegisterDataProviderFactory(factory));
            var receivedProvider = manager.CreateDataProvider(clip);

            Assert.That(receivedProvider, Is.EqualTo(provider));
        }
Ejemplo n.º 15
0
        public async Task Start(ClipDefinition clip, CancellationToken ctx)
        {
            try
            {
                IsStarted = false;
                await ExecuteStart(clip, ctx);

                IsStarted = true;
            }
            catch (TaskCanceledException)
            {
                rtspErrorSubject.OnNext("Connection timeout.");
            }
            catch (Exception e)
            {
                rtspErrorSubject.OnNext(e.Message);
            }
        }
Ejemplo n.º 16
0
        public void SetSource(ClipDefinition clip)
        {
            connector?.Dispose();

            dataProvider = dataProviders.CreateDataProvider(clip);

            if (clip.DRMDatas != null)
            {
                foreach (var drm in clip.DRMDatas)
                {
                    playerController.OnSetDrmConfiguration(drm);
                }
            }

            connector = new DataProviderConnector(playerController, dataProvider);

            dataProvider.Start();
        }
Ejemplo n.º 17
0
        public async Task SetSource(ClipDefinition clip)
        {
            drmManager.Clear();
            connector?.Dispose();

            dataProvider = dataProviders.CreateDataProvider(clip);

            if (clip.DRMDatas != null)
            {
                foreach (var drm in clip.DRMDatas)
                {
                    await drmManager.UpdateDrmConfiguration(drm);
                }
            }

            connector = new DataProviderConnector(playerController, dataProvider);

            dataProvider.Start();
        }
Ejemplo n.º 18
0
        public IDataProvider Create(ClipDefinition clip)
        {
            Logger.Info("Create.");
            if (clip == null)
            {
                throw new ArgumentNullException(nameof(clip), "Clip cannot be null.");
            }

            if (!SupportsClip(clip))
            {
                throw new ArgumentException("Unsupported clip type.");
            }

            var audioPipeline = CreateMediaPipeline(StreamType.Audio);

            audioPipeline.DisableAdaptiveStreaming = true;
            var videoPipeline = CreateMediaPipeline(StreamType.Video);

            return(new DashDataProvider(clip.Url, audioPipeline, videoPipeline));
        }
Ejemplo n.º 19
0
        public IDataProvider Create(ClipDefinition clip)
        {
            if (clip == null)
            {
                throw new ArgumentNullException(nameof(clip), "clip cannot be null");
            }

            if (!SupportsClip(clip))
            {
                throw new ArgumentException("unsupported clip type");
            }

            var rtspClient        = new RTSPClient();
            var demuxer           = new FFmpegDemuxer(new FFmpegGlue());
            var demuxerController = new DemuxerController(demuxer);

            demuxerController.SetDataSource(rtspClient.ChunkReady());

            return(new RTSPDataProvider(demuxerController, rtspClient, clip));
        }
Ejemplo n.º 20
0
        public IDataProvider Create(ClipDefinition clip)
        {
            Logger.Info("Create.");
            if (clip == null)
            {
                throw new ArgumentNullException(nameof(clip), "Clip cannot be null.");
            }

            if (!SupportsClip(clip))
            {
                throw new ArgumentException("Unsupported clip type.");
            }

            var audioPipeline = CreateMediaPipeline(StreamType.Audio);

            audioPipeline.DisableAdaptiveStreaming = true;
            var videoPipeline = CreateMediaPipeline(StreamType.Video);

            //For sake of the TV emulator performance it's important to stick with the lowest representation that is available.
            videoPipeline.DisableAdaptiveStreaming = (RuntimeInformation.ProcessArchitecture == Architecture.X86);

            return(new DashDataProvider(clip.Url, audioPipeline, videoPipeline));
        }
Ejemplo n.º 21
0
 public void SetSource(ClipDefinition clip)
 {
     playerThread.Factory.StartNew(() => proxied.SetSource(clip));
 }
Ejemplo n.º 22
0
 public Task SetSource(ClipDefinition clip)
 {
     return(playerThread.Factory.StartNew(async() => await proxied.SetSource(clip)).Unwrap());
 }