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);
        }