コード例 #1
0
 public download_m3u8File_parts_parallel_params_t(m3u8_client _mc, m3u8_file_t _m3u8File, DownloadFileAndSaveInputParams ip) : this()
 {
     mc                     = _mc;
     m3u8File               = _m3u8File;
     cts                    = ip.Cts;
     requestStepAction      = ip.RequestStepAction;
     responseStepAction     = ip.ResponseStepAction;
     maxDegreeOfParallelism = ip.MaxDegreeOfParallelism;
 }
コード例 #2
0
        public static m3u8_client Create(int attemptRequestCountByPart = 10, TimeSpan?timeout = null)
        {
            var ip = new init_params()
            {
                Timeout             = timeout,
                AttemptRequestCount = Math.Max(attemptRequestCountByPart, 1),
            };
            var mc = new m3u8_client(ip);

            return(mc);
        }
コード例 #3
0
            private static IEnumerable <m3u8_part_ts> download_m3u8File_parallel__v2(m3u8_client mc, m3u8_file_t m3u8_file
                                                                                     , CancellationTokenSource cts = null, int maxDegreeOfParallelism = 64)
            {
                var ct                = (cts?.Token).GetValueOrDefault(CancellationToken.None);
                var baseAddress       = m3u8_file.BaseAddress;
                var totalPatrs        = m3u8_file.Parts.Count;
                var successPartNumber = 0;

                var expectedPartNumber = m3u8_file.Parts.FirstOrDefault().OrderNumber;
                var maxPartNumber      = m3u8_file.Parts.LastOrDefault().OrderNumber;
                var sourceQueue        = new Queue <m3u8_part_ts>(m3u8_file.Parts);
                var downloadPartsSet   = new SortedSet <m3u8_part_ts>(default(m3u8_part_ts.comparer));

                using (DefaultConnectionLimitSaver.Create(maxDegreeOfParallelism))
                    using (var canExtractPartEvent = new AutoResetEvent(false))
                        using (var semaphore = new SemaphoreSlim(maxDegreeOfParallelism))
                        {
                            var task_download = Task.Run(() =>
                            {
                                for ( ; sourceQueue.Count != 0;)
                                {
                                    semaphore.Wait();
                                    var part = sourceQueue.Dequeue();
#if DEBUG
                                    CONSOLE.WriteLine($"start download part: {part}...");
#endif
                                    mc.DownloadPart(part, baseAddress, ct)
                                    .ContinueWith(t =>
                                    {
                                        if (t.IsFaulted)
                                        {
                                            Interlocked.Increment(ref expectedPartNumber);

                                            CONSOLE.WriteLine($"'{t.Exception.GetType().Name}': '{t.Exception.Message}'.", ConsoleColor.Red);
                                        }
                                        else if (!t.IsCanceled)
                                        {
                                            Interlocked.Increment(ref successPartNumber);

                                            var downloadPart = t.Result;
#if DEBUG
                                            CONSOLE.WriteLine($"end download part: {downloadPart}.");
#endif
                                            lock ( downloadPartsSet )
                                            {
                                                downloadPartsSet.Add(downloadPart);
                                                canExtractPartEvent.Set();
                                            }
                                        }
                                    });
                                }
                            }, ct);

                            for ( ; expectedPartNumber <= maxPartNumber && !ct.IsCancellationRequested;)
                            {
#if DEBUG
                                CONSOLE.WriteLine($"wait part #{expectedPartNumber}...");
#endif
                                canExtractPartEvent.WaitOne();

                                lock ( downloadPartsSet )
                                {
                                    for ( ; downloadPartsSet.Count != 0;)
                                    {
                                        var min_part = downloadPartsSet.Min;
                                        if (expectedPartNumber == min_part.OrderNumber)
                                        {
                                            CONSOLE.WriteLine($"receive part #{expectedPartNumber}.");

                                            downloadPartsSet.Remove(min_part);

                                            Interlocked.Increment(ref expectedPartNumber);

                                            semaphore.Release();

                                            yield return(min_part);
                                        }
                                        else
                                        {
                                            break;
                                        }
                                    }
                                }
                            }
                        }

                ct.ThrowIfCancellationRequested();

                CONSOLE.WriteLine($"\r\n total parts processed: {successPartNumber} of {totalPatrs}");
            }
コード例 #4
0
            private static IReadOnlyCollection <m3u8_part_ts> download_m3u8File_parallel(m3u8_client mc, m3u8_file_t m3u8_file
                                                                                         , CancellationTokenSource cts = null, int maxDegreeOfParallelism = 64)
            {
                var ct               = (cts?.Token).GetValueOrDefault(CancellationToken.None);
                var baseAddress      = m3u8_file.BaseAddress;
                var totalPatrs       = m3u8_file.Parts.Count;
                var globalPartNumber = 0;
                var downloadPartsSet = new SortedSet <m3u8_part_ts>(default(m3u8_part_ts.comparer));

                using (DefaultConnectionLimitSaver.Create(maxDegreeOfParallelism))
                {
                    Parallel.ForEach(m3u8_file.Parts, new ParallelOptions()
                    {
                        MaxDegreeOfParallelism = maxDegreeOfParallelism, CancellationToken = ct
                    },
                                     (part, loopState, idx) =>
                    {
                        var n = Interlocked.Increment(ref globalPartNumber);
                        try
                        {
                            CONSOLE.WriteLine($"#{n} of {totalPatrs}). '{part.RelativeUrlName}'...");
                            var downloadPart = mc.DownloadPart(part, baseAddress, ct).Result;
                            if ((downloadPart.Error != null) && !ct.IsCancellationRequested)
                            {
                                CONSOLE.WriteLineError($"#{n} of {totalPatrs}). FAILED: {downloadPart.Error}{Environment.NewLine}");
                            }

                            lock ( downloadPartsSet )
                            {
                                downloadPartsSet.Add(downloadPart);
                            }
                        }
                        catch (Exception ex)
                        {
                            #region [.code.]
                            var aex = ex as AggregateException;
                            if ((aex == null) || !aex.InnerExceptions.All(e => (e is OperationCanceledException)))
                            {
                                CONSOLE.WriteLineError("ERROR: " + ex);
                            }
                            #endregion
                        }
                    });
                }

                ct.ThrowIfCancellationRequested();

                CONSOLE.WriteLine($"\r\n total parts processed: {globalPartNumber} of {totalPatrs}");

                return(downloadPartsSet);
            }