public async Task InitializeAsync(ISegmentManagerReaders segmentManagerReaders, Action checkConfiguration, Action checkForSamples, CancellationToken cancellationToken, Action <IProgramStreams> programStreamsHandler) { this._checkConfiguration = checkConfiguration; Task startReaderTask = this._segmentReaders.Manager.StartAsync(); MediaReader localReader = this; QueueWorker <WorkBuffer> queueWorker = new QueueWorker <WorkBuffer>((Action <WorkBuffer>)(wi => { IMediaParser mediaParser = localReader._mediaParser; if (null == wi) { mediaParser.ProcessEndOfData(); } else { if (null != wi.Metadata) { mediaParser.StartSegment(wi.Metadata); wi.Metadata = (ISegmentMetadata)null; } mediaParser.ProcessData(wi.Buffer, 0, wi.Length); } }), (Action <WorkBuffer>)(buffer => this._blockingPool.Free(buffer))); this._queueWorker = queueWorker; this._callbackReader = new CallbackReader(segmentManagerReaders.Readers, new Action <WorkBuffer>(queueWorker.Enqueue), this._blockingPool); this._bufferingManager.Initialize((IQueueThrottling)queueWorker, checkForSamples); try { await startReaderTask.ConfigureAwait(false); ContentType contentType = this._segmentReaders.Manager.ContentType; if ((ContentType)null == contentType) { Debug.WriteLine("MediaReader.CreateReaderPipeline() unable to determine content type, defaulting to transport stream"); contentType = ContentTypes.TransportStream; } else if (ContentTypes.Binary == contentType) { Debug.WriteLine("MediaReader.CreateReaderPipeline() detected binary content, defaulting to transport stream"); contentType = ContentTypes.TransportStream; } MediaParserParameters mediaParserParameters = new MediaParserParameters(); this._mediaParser = await this._mediaParserFactory.CreateAsync((IMediaParserParameters)mediaParserParameters, contentType, cancellationToken).ConfigureAwait(false); if (null == this._mediaParser) { throw new NotSupportedException("Unsupported content type: " + (object)contentType); } this._mediaParser.ConfigurationComplete += new EventHandler(this.ConfigurationComplete); this._mediaParser.Initialize(this._bufferingManager, programStreamsHandler); this._mediaParser.InitializeStream(this._segmentReaders.Manager.StreamMetadata); } catch (Exception ex) { this._bufferingManager.Shutdown((IQueueThrottling)queueWorker); throw; } }
public void Dispose() { if (0 != Interlocked.Exchange(ref this._isDisposed, 1)) { return; } using (this._callbackReader) ; using (this._queueWorker) ; using (this._blockingPool) ; using (this._mediaParser) ; this._callbackReader = (CallbackReader)null; this._queueWorker = (QueueWorker <WorkBuffer>)null; this._blockingPool = (IBlockingPool <WorkBuffer>)null; this._mediaParser = (IMediaParser)null; this._bufferingManager = (IBufferingManager)null; this._segmentReaders = (ISegmentManagerReaders)null; }
private async Task ReadResponseAsync(IMediaParser mediaParser, IWebStreamResponse webStreamResponse, WebResponse webResponse, SingleStreamMediaManager.QueueThrottle throttle, CancellationToken cancellationToken) { byte[] buffer = new byte[16384]; Task cancellationTask = CancellationTokenExtensions.AsTask(cancellationToken); try { ISegmentMetadata segmentMetadata = this._webMetadataFactory.CreateSegmentMetadata(webResponse, (ContentType)null); mediaParser.StartSegment(segmentMetadata); using (Stream stream = await webStreamResponse.GetStreamAsync(cancellationToken).ConfigureAwait(false)) { while (true) { Task waitTask = throttle.WaitAsync(); if (!waitTask.IsCompleted) { Task task = await TaskEx.WhenAny(waitTask, cancellationTask).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); } int length = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); if (length > 0) { mediaParser.ProcessData(buffer, 0, length); } else { break; } } } } finally { mediaParser.ProcessEndOfData(); } }
private async Task SimplePlayAsync(ContentType contentType, IWebReader webReader, IWebStreamResponse webStreamResponse, WebResponse webResponse, TaskCompletionSource <bool> configurationTaskCompletionSource, CancellationToken cancellationToken) { try { this._mediaStreamConfigurator.Initialize(); this._mediaStreamConfigurator.MediaManager = (IMediaManager)this; IMediaParser mediaParser = await this._mediaParserFactory.CreateAsync((IMediaParserParameters) new MediaParserParameters(), contentType, cancellationToken).ConfigureAwait(false); if (null == mediaParser) { throw new NotSupportedException("Unsupported content type: " + (object)contentType); } this.State = MediaManagerState.Opening; EventHandler configurationComplete = (EventHandler)null; configurationComplete = (EventHandler)((sender, args) => { mediaParser.ConfigurationComplete -= configurationComplete; configurationTaskCompletionSource.TrySetResult(true); }); mediaParser.ConfigurationComplete += configurationComplete; using (IBufferingManager bufferingManager = this._bufferingManagerFactory()) { SingleStreamMediaManager.QueueThrottle throttle = new SingleStreamMediaManager.QueueThrottle(); bufferingManager.Initialize((IQueueThrottling)throttle, new Action(this._mediaStreamConfigurator.CheckForSamples)); mediaParser.Initialize(bufferingManager, (Action <IProgramStreams>)null); IStreamMetadata streamMetadata = this._webMetadataFactory.CreateStreamMetadata(webResponse, (ContentType)null); mediaParser.InitializeStream(streamMetadata); Task reader = (Task)null; try { using (webReader) { try { if (null == webStreamResponse) { webStreamResponse = await webReader.GetWebStreamAsync((Uri)null, false, cancellationToken, (Uri)null, new long?(), new long?(), webResponse).ConfigureAwait(false); } reader = this.ReadResponseAsync(mediaParser, webStreamResponse, webResponse, throttle, cancellationToken); Task task = await TaskEx.WhenAny((Task)configurationTaskCompletionSource.Task, CancellationTokenExtensions.AsTask(cancellationToken)).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); await MediaStreamSourceExtensions.PlayAsync(this._mediaStreamConfigurator, (IEnumerable <IMediaParserMediaStream>) mediaParser.MediaStreams, new TimeSpan?(), cancellationToken).ConfigureAwait(false); this.State = MediaManagerState.Playing; await reader.ConfigureAwait(false); reader = (Task)null; } finally { if (null != webStreamResponse) { webStreamResponse.Dispose(); } } } } catch (OperationCanceledException ex) { } catch (Exception ex) { string message = ExceptionExtensions.ExtendedMessage(ex); Debug.WriteLine("SingleStreamMediaManager.SimplePlayAsync() failed: " + message); this.SetMediaState(MediaManagerState.Error, message); } this.State = MediaManagerState.Closing; if (null != reader) { try { await reader.ConfigureAwait(false); } catch (OperationCanceledException ex) { } catch (Exception ex) { Debug.WriteLine("SingleStreamMediaManager.SimplePlayAsync() reader failed: " + ExceptionExtensions.ExtendedMessage(ex)); } } mediaParser.ConfigurationComplete -= configurationComplete; mediaParser.EnableProcessing = false; mediaParser.FlushBuffers(); bufferingManager.Flush(); bufferingManager.Shutdown((IQueueThrottling)throttle); await this._mediaStreamConfigurator.CloseAsync().ConfigureAwait(false); } } catch (Exception ex) { Debug.WriteLine("SingleStreamMediaManager.SimplePlayAsync() cleanup failed: " + ExceptionExtensions.ExtendedMessage(ex)); } this._mediaStreamConfigurator.MediaManager = (IMediaManager)null; if (!configurationTaskCompletionSource.Task.IsCompleted) { configurationTaskCompletionSource.TrySetCanceled(); } this.State = MediaManagerState.Closed; await this._reportStateTask.WaitAsync().ConfigureAwait(false); }
public void Dispose() { if (0 != Interlocked.Exchange(ref _isDisposed, 1)) return; using (_callbackReader) { } using (_queueWorker) { } using (_blockingPool) { } using (_mediaParser) { } _callbackReader = null; _queueWorker = null; _blockingPool = null; _mediaParser = null; _bufferingManager = null; _segmentReaders = null; }
public async Task InitializeAsync(ISegmentManagerReaders segmentManagerReaders, Action checkConfiguration, Action checkForSamples, CancellationToken cancellationToken, Action<IProgramStreams> programStreamsHandler) { _checkConfiguration = checkConfiguration; var startReaderTask = _segmentReaders.Manager.StartAsync(); var localReader = this; var queueWorker = new QueueWorker<WorkBuffer>( wi => { //Debug.WriteLine("MediaReader dequeued " + wi); var mediaParser = localReader._mediaParser; if (null == wi) mediaParser.ProcessEndOfData(); else { if (null != wi.Metadata) { mediaParser.StartSegment(wi.Metadata); wi.Metadata = null; } mediaParser.ProcessData(wi.Buffer, 0, wi.Length); } }, buffer => _blockingPool.Free(buffer)); _queueWorker = queueWorker; _callbackReader = new CallbackReader(segmentManagerReaders.Readers, queueWorker.Enqueue, _blockingPool); _bufferingManager.Initialize(queueWorker, checkForSamples); try { await startReaderTask.ConfigureAwait(false); var streamContentType = _segmentReaders.Manager.StreamContentType; if (null == streamContentType) { Debug.WriteLine("MediaReader.CreateReaderPipeline() unable to determine content type, defaulting to transport stream"); streamContentType = ContentTypes.TransportStream; } else if (ContentTypes.Binary == streamContentType) { Debug.WriteLine("MediaReader.CreateReaderPipeline() detected binary content, defaulting to transport stream"); streamContentType = ContentTypes.TransportStream; } var mediaParserParameters = new MediaParserParameters(); _mediaParser = await _mediaParserFactory.CreateAsync(mediaParserParameters, streamContentType, cancellationToken).ConfigureAwait(false); if (null == _mediaParser) throw new NotSupportedException("Unsupported stream content type: " + streamContentType); _mediaParser.ConfigurationComplete += ConfigurationComplete; _mediaParser.Initialize(_bufferingManager, programStreamsHandler); _mediaParser.InitializeStream(_segmentReaders.Manager.StreamMetadata); } catch (Exception) { _bufferingManager.Shutdown(queueWorker); throw; } }
async Task ReadResponseAsync(IMediaParser mediaParser, IWebStreamResponse webStreamResponse, WebResponse webResponse, QueueThrottle throttle, CancellationToken cancellationToken) { //Debug.WriteLine("SingleStreamMediaManager.ReadResponseAsync()"); var buffer = new byte[16 * 1024]; var cancellationTask = cancellationToken.AsTask(); try { var segmentMetadata = _webMetadataFactory.CreateSegmentMetadata(webResponse); mediaParser.StartSegment(segmentMetadata); using (var stream = await webStreamResponse.GetStreamAsync(cancellationToken).ConfigureAwait(false)) { for (; ; ) { var waitTask = throttle.WaitAsync(); if (!waitTask.IsCompleted) { await Task.WhenAny(waitTask, cancellationTask).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); } var length = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); if (length <= 0) return; mediaParser.ProcessData(buffer, 0, length); } } } finally { mediaParser.ProcessEndOfData(); //Debug.WriteLine("SingleStreamMediaManager.ReadResponseAsync() done"); } }