예제 #1
0
            public static void run__v2(string M3U8_FILE_URL, string OUTPUT_FILE_DIR, string OUTPUT_FILE_EXT)
            {
                using (var mc = m3u8_client_factory.Create())
                    using (var cts = new CancellationTokenSource())
                    {
                        var task = Task.Run(async() =>
                        {
                            var sw = Stopwatch.StartNew();

                            //-1-//
                            CONSOLE.WriteLine($"download m3u8-file: '{M3U8_FILE_URL}'...");
                            var m3u8FileUrl = new Uri(M3U8_FILE_URL);
                            var m3u8File    = await mc.DownloadFile(m3u8FileUrl, cts.Token);
                            CONSOLE.WriteLine($"success. parts count: {m3u8File.Parts.Count}\r\n");

                            //-2-//
                            var downloadParts = download_m3u8File_parallel__v2(mc, m3u8File, cts);

                            //-3-//
                            var downloadPartsSuccessCount = 0;
                            var downloadPartsErrorCount   = 0;
                            var totalBytes = 0;

                            var outputFileName = Path.Combine(OUTPUT_FILE_DIR, PathnameCleaner.CleanPathnameAndFilename(m3u8FileUrl.AbsolutePath).TrimStart('-') + OUTPUT_FILE_EXT);
                            using (var fs = File.OpenWrite(outputFileName))
                            {
                                fs.SetLength(0);

                                foreach (var downloadPart in downloadParts)
                                {
                                    if (downloadPart.Error != null)
                                    {
                                        downloadPartsErrorCount++;
                                        continue;
                                    }
                                    var bytes = downloadPart.Bytes;
                                    fs.Write(bytes, 0, bytes.Length);

                                    downloadPartsSuccessCount++;
                                    totalBytes += bytes.Length;
                                }
                            }

                            sw.Stop();
                            CONSOLE.WriteLine($"\r\nSuccess: downloaded & writed parts {downloadPartsSuccessCount} of {(downloadPartsErrorCount + downloadPartsSuccessCount)}\r\n" +
                                              $"(elapsed: {sw.Elapsed}, file: '{outputFileName}', size: {(totalBytes >> 20).ToString( "0,0" )} mb)\r\n");
                        })
                                   .ContinueWith(t =>
                        {
                            if (t.IsFaulted)
                            {
                                CONSOLE.WriteLineError("ERROR: " + t.Exception);
                            }
                        });

                        #region [.wait for keyboard break.]
                        task.WaitForTaskEndsOrKeyboardBreak(cts);
                        #endregion
                    }
            }
예제 #2
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);
            }
예제 #3
0
        private static void Main(string[] args)
        {
            try
            {
                #region [.set SecurityProtocol to 'Tls + Tls11 + Tls12 + Ssl3'.]
                ServicePointManager.SecurityProtocol = (SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12 | SecurityProtocolType.Ssl3);
                #endregion

                var M3U8_FILE_URL = ConfigurationManager.AppSettings["M3U8_FILE_URL"]; if (M3U8_FILE_URL.IsNullOrWhiteSpace())
                {
                    throw (new ArgumentNullException(nameof(M3U8_FILE_URL)));
                }
                var OUTPUT_FILE_DIR = ConfigurationManager.AppSettings["OUTPUT_FILE_DIR"]; if (OUTPUT_FILE_DIR.IsNullOrWhiteSpace())
                {
                    OUTPUT_FILE_DIR = @"E:\\";
                }
                var OUTPUT_FILE_EXT = ConfigurationManager.AppSettings["OUTPUT_FILE_EXT"]; if (OUTPUT_FILE_EXT.IsNullOrWhiteSpace())
                {
                    OUTPUT_FILE_EXT = ".avi";
                }

                //---v1.run( M3U8_FILE_URL, OUTPUT_FILE_DIR, OUTPUT_FILE_EXT );
                //v2.run__v1( M3U8_FILE_URL, OUTPUT_FILE_DIR, OUTPUT_FILE_EXT );
                //v2.run__v2( M3U8_FILE_URL, OUTPUT_FILE_DIR, OUTPUT_FILE_EXT );

                using (var cts = new CancellationTokenSource())
                {
                    var outputFileName = Path.Combine(OUTPUT_FILE_DIR, PathnameCleaner.CleanPathnameAndFilename(M3U8_FILE_URL).TrimStart('-') + OUTPUT_FILE_EXT);
                    v3.run(M3U8_FILE_URL, outputFileName, cts).WaitForTaskEndsOrKeyboardBreak(cts);
                }
            }
            catch (Exception ex)
            {
                CONSOLE.WriteLineError("ERROR: " + ex);
            }
            CONSOLE.WriteLine("\r\n\r\n[.....finita fusking comedy.....]\r\n\r\n", ConsoleColor.DarkGray);
            CONSOLE.ReadLine();
        }
예제 #4
0
            public static async Task run(string m3u8FileUrl, string outputFileName, CancellationTokenSource cts)
            {
                var p = new m3u8_processor.DownloadFileAndSaveInputParams()
                {
                    Cts                = cts,
                    m3u8FileUrl        = m3u8FileUrl,
                    OutputFileName     = outputFileName,
                    ResponseStepAction = new m3u8_processor.ResponseStepActionDelegate(t =>
                                                                                       CONSOLE.WriteLine($"{t.Part.OrderNumber} of {t.TotalPartCount}, '{t.Part.RelativeUrlName}'")
                                                                                       ),
                };

                await m3u8_processor.DownloadFileAndSave_Async(p);
            }
예제 #5
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}");
            }
예제 #6
0
        private static void Main(string[] args)
        {
            try
            {
                var M3U8_FILE_URL = ConfigurationManager.AppSettings["M3U8_FILE_URL"]; if (M3U8_FILE_URL.IsNullOrWhiteSpace())
                {
                    throw (new ArgumentNullException(nameof(M3U8_FILE_URL)));
                }
                var OUTPUT_FILE_DIR = ConfigurationManager.AppSettings["OUTPUT_FILE_DIR"]; if (OUTPUT_FILE_DIR.IsNullOrWhiteSpace())
                {
                    OUTPUT_FILE_DIR = Environment.CurrentDirectory;
                }
                var OUTPUT_FILE_EXT = ConfigurationManager.AppSettings["OUTPUT_FILE_EXT"]; if (OUTPUT_FILE_EXT.IsNullOrWhiteSpace())
                {
                    OUTPUT_FILE_EXT = ".avi";
                }
                //----------------------------------------------------------------------------------//

                CONSOLE.WriteLine($"M3U8-FILE-URL: '{M3U8_FILE_URL}'...");
                CONSOLE.WriteLine("(press 'escape' for cancel)\r\n", ConsoleColor.DarkGray);

                using (var cts = new CancellationTokenSource())
                {
                    var outputFileName = Path.Combine(OUTPUT_FILE_DIR, PathnameCleaner.CleanPathnameAndFilename(M3U8_FILE_URL).TrimStart('-') + OUTPUT_FILE_EXT);

                    var ip = new m3u8_processor.DownloadFileAndSaveInputParams()
                    {
                        Cts                    = cts,
                        m3u8FileUrl            = M3U8_FILE_URL,
                        OutputFileName         = outputFileName,
                        MaxDegreeOfParallelism = 64,
                        NetParams              = new m3u8_client.init_params()
                        {
                            AttemptRequestCount = 3,
                            Timeout             = TimeSpan.FromSeconds(30),
                            ConnectionClose     = false,
                        },
                        RequestStepAction = new m3u8_processor.RequestStepActionDelegate(p =>
                        {
                            var msg = $"{p.PartOrderNumber} of {p.TotalPartCount}, '{p.Part.RelativeUrlName}'";
                            if (p.Error != null)
                            {
                                CONSOLE.WriteLineError(msg + $" => {p.Error}");
                            }
                            else
                            {
                                CONSOLE.WriteLine(msg);
                            }
                        }),
                        ResponseStepAction = new m3u8_processor.ResponseStepActionDelegate(p =>
                        {
                            if (p.Part.Error != null)
                            {
                                CONSOLE.WriteLineError($" => {p.Part.Error}");
                            }
                        }),
                    };

                    var res = m3u8_processor.DownloadFileAndSave_Async(ip).WaitForTaskEndsOrKeyboardBreak(cts);

                    CONSOLE.WriteLine($"\r\nM3U8-FILE-URL: '{res.m3u8FileUrl}'");
                    CONSOLE.WriteLine($"OutputFileName: '{res.OutputFileName}'");
                    CONSOLE.WriteLine($"OutputFileName-Size: {(res.TotalBytes >> 20)}mb");
                    CONSOLE.WriteLine($"Total-Parts: {res.TotalParts}, Success: {res.PartsSuccessCount}, Error: {res.PartsErrorCount}");
                }
            }
            catch (Exception ex)
            {
                CONSOLE.WriteLineError("ERROR: " + ex);
            }
            CONSOLE.WriteLine("\r\n\r\n[.....finita fusking comedy.....]\r\n\r\n", ConsoleColor.DarkGray);
            CONSOLE.ReadLine();
        }