public static async Task <TReturn> ReadStreamAsync <TReturn>(this IWebReader webReader, Uri url, Retry retry, Func <Uri, Stream, CancellationToken, Task <TReturn> > reader, CancellationToken cancellationToken) { TReturn @return; while (true) { using (IWebStreamResponse webStreamAsync = await webReader.GetWebStreamAsync(url, false, cancellationToken, (Uri)null, new long?(), new long?(), (WebResponse)null)) { if (webStreamAsync.IsSuccessStatusCode) { Uri actualUrl = webStreamAsync.ActualUrl; using (Stream stream = await webStreamAsync.GetStreamAsync(cancellationToken).ConfigureAwait(false)) { @return = await reader(actualUrl, stream, cancellationToken).ConfigureAwait(false); break; } } else { if (!RetryPolicy.IsRetryable((HttpStatusCode)webStreamAsync.HttpStatusCode)) { webStreamAsync.EnsureSuccessStatusCode(); } bool canRetry = await retry.CanRetryAfterDelayAsync(cancellationToken).ConfigureAwait(false); if (!canRetry) { webStreamAsync.EnsureSuccessStatusCode(); } } } } return(@return); }
public virtual async Task <ISegmentManager> CreateAsync(ISegmentManagerParameters parameters, ContentType contentType, CancellationToken cancellationToken) { ISegmentManager segmentManager1; foreach (Uri uri in (IEnumerable <Uri>)parameters.Source) { Uri localUrl = uri; IRetry retry = RetryManagerExtensions.CreateWebRetry(this._retryManager, 3, 333); ISegmentManager segmentManager = await retry.CallAsync <ISegmentManager>((Func <Task <ISegmentManager> >)(async() => { IWebReader webReader = this._webReaderManager.CreateReader(localUrl, ContentTypes.Pls.Kind, (IWebReader)null, ContentTypes.Pls); ISegmentManager segmentManager2; try { using (IWebStreamResponse webStreamResponse = await webReader.GetWebStreamAsync(localUrl, false, cancellationToken, (Uri)null, new long?(), new long?(), (WebResponse)null).ConfigureAwait(false)) { if (!webStreamResponse.IsSuccessStatusCode) { webReader.Dispose(); segmentManager2 = (ISegmentManager)null; } else { using (Stream stream = await webStreamResponse.GetStreamAsync(cancellationToken).ConfigureAwait(false)) segmentManager2 = await this.ReadPlaylistAsync(webReader, webStreamResponse.ActualUrl, stream, cancellationToken).ConfigureAwait(false); } } } catch (Exception ex) { webReader.Dispose(); throw; } return(segmentManager2); }), cancellationToken); if (null != segmentManager) { segmentManager1 = segmentManager; goto label_10; } } segmentManager1 = (ISegmentManager)null; label_10: return(segmentManager1); }
public static async Task <TReturn> ReadStreamAsync <TReturn>(this IWebReader webReader, Uri url, IRetry retry, Func <Uri, Stream, TReturn> reader, CancellationToken cancellationToken) { TReturn @return; while (true) { using (IWebStreamResponse webStreamResponse = await webReader.GetWebStreamAsync(url, true, cancellationToken, (Uri)null, new long?(), new long?(), (WebResponse)null).ConfigureAwait(false)) { if (webStreamResponse.IsSuccessStatusCode) { Uri actualUrl = webStreamResponse.ActualUrl; using (Stream stream = await webStreamResponse.GetStreamAsync(cancellationToken).ConfigureAwait(false)) { using (MemoryStream memoryStream = new MemoryStream((int)(webStreamResponse.ContentLength ?? 4096L))) { await stream.CopyToAsync((Stream)memoryStream, 4096, cancellationToken).ConfigureAwait(false); memoryStream.Position = 0L; @return = reader(actualUrl, (Stream)memoryStream); break; } } } else { if (!RetryPolicy.IsRetryable((HttpStatusCode)webStreamResponse.HttpStatusCode)) { webStreamResponse.EnsureSuccessStatusCode(); } bool canRetry = await retry.CanRetryAfterDelayAsync(cancellationToken).ConfigureAwait(false); if (!canRetry) { webStreamResponse.EnsureSuccessStatusCode(); } } } } return(@return); }
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 async Task <IMediaStreamConfigurator> OpenMediaAsync(ICollection <Uri> source, CancellationToken cancellationToken) { this.State = MediaManagerState.OpenMedia; WebResponse response = new WebResponse(); IMediaStreamConfigurator streamConfigurator; using (IWebReader rootReader = WebReaderManagerExtensions.CreateRootReader(this._webReaderManager, (ContentType)null)) { using (IEnumerator <Uri> enumerator = source.GetEnumerator()) { label_25: if (enumerator.MoveNext()) { Uri url = enumerator.Current; IWebReader webReader = (IWebReader)null; IWebStreamResponse webStream = (IWebStreamResponse)null; CancellationTokenSource playCancellationTokenSource = (CancellationTokenSource)null; Task playTask = (Task)null; try { webReader = WebReaderExtensions.CreateChild(rootReader, url, ContentKind.Unknown, this.ContentType); webStream = await webReader.GetWebStreamAsync((Uri)null, false, cancellationToken, (Uri)null, new long?(), new long?(), response).ConfigureAwait(false); if (webStream.IsSuccessStatusCode) { ContentType contentType = response.ContentType; if (!((ContentType)null == contentType)) { if ((ContentType)null == contentType || ContentKind.Playlist == contentType.Kind) { throw new FileNotFoundException("Content not supported with this media manager"); } TaskCompletionSource <bool> configurationTaskCompletionSource = new TaskCompletionSource <bool>(); playCancellationTokenSource = new CancellationTokenSource(); CancellationTokenSource localPlayCancellationTokenSource = playCancellationTokenSource; Task cancelPlayTask = configurationTaskCompletionSource.Task.ContinueWith((Action <Task <bool> >)(t => { if (!t.IsFaulted && !t.IsCanceled) { return; } localPlayCancellationTokenSource.Cancel(); })); TaskCollector.Default.Add(cancelPlayTask, "SingleStreamMediaManager play cancellation"); IWebReader localWebReader = webReader; IWebStreamResponse localWebStream = webStream; CancellationToken playCancellationToken = playCancellationTokenSource.Token; playTask = TaskEx.Run((Func <Task>)(() => this.SimplePlayAsync(contentType, localWebReader, localWebStream, response, configurationTaskCompletionSource, playCancellationToken)), playCancellationToken); bool lockTaken = false; object obj; try { Monitor.Enter(obj = this._lock, ref lockTaken); this._playCancellationTokenSource = playCancellationTokenSource; playCancellationTokenSource = (CancellationTokenSource)null; this._playTask = playTask; playTask = (Task)null; } finally { if (lockTaken) { Monitor.Exit(obj); } } bool isConfigured = await configurationTaskCompletionSource.Task.ConfigureAwait(false); if (isConfigured) { webReader = (IWebReader)null; webStream = (IWebStreamResponse)null; streamConfigurator = this._mediaStreamConfigurator; goto label_33; } else { goto label_25; } } else { goto label_25; } } else { goto label_25; } } finally { if (null != webStream) { webStream.Dispose(); } if (null != webReader) { webReader.Dispose(); } if (null != playCancellationTokenSource) { playCancellationTokenSource.Cancel(); } if (null != playTask) { TaskCollector.Default.Add(playTask, "SingleStreamMediaManager play task"); } } } } } throw new FileNotFoundException(); label_33: return(streamConfigurator); }
async Task SimplePlayAsync(ContentType contentType, IWebReader webReader, IWebStreamResponse webStreamResponse, WebResponse webResponse, TaskCompletionSource<bool> configurationTaskCompletionSource, CancellationToken cancellationToken) { try { _mediaStreamConfigurator.Initialize(); _mediaStreamConfigurator.MediaManager = this; var mediaParser = await _mediaParserFactory.CreateAsync(new MediaParserParameters(), contentType, cancellationToken).ConfigureAwait(false); if (null == mediaParser) throw new NotSupportedException("Unsupported content type: " + contentType); State = MediaManagerState.Opening; EventHandler configurationComplete = null; configurationComplete = (sender, args) => { // ReSharper disable once AccessToModifiedClosure mediaParser.ConfigurationComplete -= configurationComplete; configurationTaskCompletionSource.TrySetResult(true); }; mediaParser.ConfigurationComplete += configurationComplete; using (var bufferingManager = _bufferingManagerFactory()) { var throttle = new QueueThrottle(); bufferingManager.Initialize(throttle, _mediaStreamConfigurator.CheckForSamples); mediaParser.Initialize(bufferingManager); var streamMetadata = _webMetadataFactory.CreateStreamMetadata(webResponse); mediaParser.InitializeStream(streamMetadata); Task reader = null; try { using (webReader) { try { if (null == webStreamResponse) webStreamResponse = await webReader.GetWebStreamAsync(null, false, cancellationToken, response: webResponse).ConfigureAwait(false); reader = ReadResponseAsync(mediaParser, webStreamResponse, webResponse, throttle, cancellationToken); await Task.WhenAny(configurationTaskCompletionSource.Task, cancellationToken.AsTask()).ConfigureAwait(false); cancellationToken.ThrowIfCancellationRequested(); await _mediaStreamConfigurator.PlayAsync(mediaParser.MediaStreams, null, cancellationToken).ConfigureAwait(false); State = MediaManagerState.Playing; await reader.ConfigureAwait(false); reader = null; } finally { if (null != webStreamResponse) webStreamResponse.Dispose(); } } } catch (OperationCanceledException) { } catch (Exception ex) { var message = ex.ExtendedMessage(); Debug.WriteLine("SingleStreamMediaManager.SimplePlayAsync() failed: " + message); SetMediaState(MediaManagerState.Error, message); } State = MediaManagerState.Closing; if (null != reader) { try { await reader.ConfigureAwait(false); } catch (OperationCanceledException) { } catch (Exception ex) { Debug.WriteLine("SingleStreamMediaManager.SimplePlayAsync() reader failed: " + ex.ExtendedMessage()); } } mediaParser.ConfigurationComplete -= configurationComplete; mediaParser.EnableProcessing = false; mediaParser.FlushBuffers(); bufferingManager.Flush(); bufferingManager.Shutdown(throttle); await _mediaStreamConfigurator.CloseAsync().ConfigureAwait(false); } } catch (Exception ex) { Debug.WriteLine("SingleStreamMediaManager.SimplePlayAsync() cleanup failed: " + ex.ExtendedMessage()); } _mediaStreamConfigurator.MediaManager = null; if (!configurationTaskCompletionSource.Task.IsCompleted) configurationTaskCompletionSource.TrySetCanceled(); State = MediaManagerState.Closed; await _reportStateTask.WaitAsync().ConfigureAwait(false); }