예제 #1
0
        public static async Task <IList <Segment> > Download(Segment indexSource, Uri mediaUrl, CancellationToken token)
        {
            var policy = HttpClientProvider.GetPolicySendAsync((e) =>
            {
                // All exception other then Cancellation due to timeout
                // result in termination
                if (!(e is OperationCanceledException))
                {
                    Logger.Error($"DownloadError {e.Message}");
                    return(false);
                }

                // Check if timeout or external cancellation.
                // Both reported as OperationCancelledException
                if (token.IsCancellationRequested)
                {
                    Logger.Warn($"Download Cancelled: {indexSource.Url}");
                    return(false);
                }

                Logger.Warn($"Download Timeout: {e.Message} {indexSource.Url}");
                return(true);
            });

            long             rangeHigh = 0;
            long             rangeLow  = 0;
            RangeHeaderValue ranges    = null;

            if (indexSource.ByteRange.Length > 0)
            {
                var byteRanges = new ByteRange(indexSource.ByteRange);
                ranges    = new RangeHeaderValue(byteRanges.Low, byteRanges.High);
                rangeHigh = byteRanges.High;
                rangeLow  = byteRanges.Low;
            }

            try
            {
                byte[] rawIndexData;

                using (var response = await policy.ExecuteAsync(() =>
                {
                    Logger.Info($"Download {indexSource.Url} {rangeLow}-{rangeHigh} {rangeHigh - rangeLow}");

                    // Watch out for https://github.com/App-vNext/Polly/issues/313
                    using (var request = new HttpRequestMessage(HttpMethod.Get, indexSource.Url))
                    {
                        if (ranges != null)
                        {
                            request.Headers.Range = ranges;
                        }

                        return(HttpClientProvider.NetClient.SendAsync(request, token));
                    }
                }))
                {
                    rawIndexData = await response.Content.ReadAsByteArrayAsync();
                }

                var index = ProcessIndexData(rawIndexData, (ulong)rangeHigh, mediaUrl);

                Logger.Info($"{index.Count} indexes {indexSource.Url}");

                return(index);
            }
            catch (Exception e)
            {
                throw new FMp4IndexerException($"Index {indexSource.Url} failed", e);
            }
        }