コード例 #1
0
        private async Task <M3U8Parser> FetchPlaylistAsync(CancellationToken cancellationToken)
        {
            var urls = Urls;

            if (urls == null || urls.Count < 1)
            {
                return(null);
            }

            foreach (Uri playlist in urls)
            {
                UpdateSubPlaylistCache(playlist);
                cancellationToken.ThrowIfCancellationRequested();
                WebResponse webResponse = null;
                if (null == StreamMetadata)
                {
                    webResponse = new WebResponse();
                }

                var parsedPlaylist = await _subPlaylistCache.ReadAsync((actualUri, bytes) =>
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    if (bytes.Length < 1)
                    {
                        return(null);
                    }
                    var parser = new M3U8Parser();
                    using (var memoryStream = new MemoryStream(bytes))
                    {
                        parser.Parse(actualUri, memoryStream);
                    }

                    return(parser);
                }, cancellationToken, webResponse).ConfigureAwait(false);

                if (null != parsedPlaylist)
                {
                    if (null != webResponse)
                    {
                        StreamMetadata = _webMetadataFactory.CreateStreamMetadata(webResponse);
                    }

                    return(parsedPlaylist);
                }
            }

            return(null);
        }
コード例 #2
0
        private Task OpenStream(Action <ISegmentMetadata> setMetadata, CancellationToken cancellationToken)
        {
            this.ThrowIfDisposed();
            WebResponse webResponse = new WebResponse();
            IRetry      retry       = this._retryManager.CreateRetry(2, 200, new Func <Exception, bool>(RetryPolicy.IsWebExceptionRetryable));

            return(RetryExtensions.CallAsync(retry, (Func <Task>)(async() =>
            {
                long?nullable1;
                long?nullable2;
                while (true)
                {
                    if (this._startOffset.HasValue && this._endOffset.HasValue)
                    {
                        nullable1 = this._endOffset;
                        nullable2 = this._startOffset;
                        nullable1 = nullable1.HasValue & nullable2.HasValue ? new long?(nullable1.GetValueOrDefault() - nullable2.GetValueOrDefault()) : new long?();
                        long?nullable3;
                        if (!nullable1.HasValue)
                        {
                            nullable2 = new long?();
                            nullable3 = nullable2;
                        }
                        else
                        {
                            nullable3 = new long?(nullable1.GetValueOrDefault() + 1L);
                        }
                        this._expectedBytes = nullable3;
                    }
                    else
                    {
                        this._expectedBytes = new long?();
                    }
                    this._response = await this._webReader.GetWebStreamAsync(this._actualUrl ?? this._segment.Url, false, cancellationToken, this._segment.ParentUrl, this._startOffset, this._endOffset, webResponse).ConfigureAwait(false);
                    if (!this._response.IsSuccessStatusCode)
                    {
                        HttpStatusCode statusCode = (HttpStatusCode)this._response.HttpStatusCode;
                        if (HttpStatusCode.NotFound != statusCode && !RetryPolicy.IsRetryable(statusCode))
                        {
                            this._response.EnsureSuccessStatusCode();
                        }
                        bool canRetry = await retry.CanRetryAfterDelayAsync(cancellationToken).ConfigureAwait(false);
                        if (!canRetry)
                        {
                            if ((Uri)null != this._actualUrl && this._actualUrl != this._segment.Url)
                            {
                                this._actualUrl = (Uri)null;
                            }
                            else
                            {
                                this._response.EnsureSuccessStatusCode();
                            }
                        }
                        this._response.Dispose();
                        this._response = (IWebStreamResponse)null;
                    }
                    else
                    {
                        break;
                    }
                }
                this._actualUrl = this._response.ActualUrl;
                long?contentLength = this._response.ContentLength;
                if (!this._endOffset.HasValue)
                {
                    nullable1 = contentLength;
                    long?nullable3;
                    if (!nullable1.HasValue)
                    {
                        nullable2 = new long?();
                        nullable3 = nullable2;
                    }
                    else
                    {
                        nullable3 = new long?(nullable1.GetValueOrDefault() - 1L);
                    }
                    this._endOffset = nullable3;
                }
                if (!this._expectedBytes.HasValue)
                {
                    this._expectedBytes = contentLength;
                }
                SegmentReader segmentReader1 = this;
                ConfiguredTaskAwaitable <Stream> configuredTaskAwaitable = this._response.GetStreamAsync(cancellationToken).ConfigureAwait(false);
                PositionStream positionStream = new PositionStream(await configuredTaskAwaitable);
                segmentReader1._responseStream = (Stream)positionStream;
                Task <Stream> filterStreamTask = this._segment.CreateFilterAsync(this._responseStream, cancellationToken);
                if (null != filterStreamTask)
                {
                    SegmentReader segmentReader2 = this;
                    configuredTaskAwaitable = filterStreamTask.ConfigureAwait(false);
                    Stream stream = await configuredTaskAwaitable;
                    segmentReader2._readStream = stream;
                }
                else
                {
                    this._readStream = this._responseStream;
                }
                ISegmentMetadata segmentMetadata = this._webMetadataFactory.CreateSegmentMetadata(webResponse, (ContentType)null);
                setMetadata(segmentMetadata);
            }), cancellationToken));
        }
コード例 #3
0
        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);
        }
コード例 #4
0
        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();
            }
        }
コード例 #5
0
        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       = null;
                                    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);
        }