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"); }
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)); }
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"); }
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); }
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)); }
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)); }
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); }
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"); } }
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); }
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); }
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)); }
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)); }
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); } }
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(); }
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(); }
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)); }
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)); }
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)); }
public void SetSource(ClipDefinition clip) { playerThread.Factory.StartNew(() => proxied.SetSource(clip)); }
public Task SetSource(ClipDefinition clip) { return(playerThread.Factory.StartNew(async() => await proxied.SetSource(clip)).Unwrap()); }