增加代理、自定义HLS KEY选项

This commit is contained in:
nilaoda 2022-09-20 22:51:28 +08:00
parent 0b02ecd2c8
commit e84558d908
11 changed files with 153 additions and 48 deletions

View File

@ -36,6 +36,9 @@ namespace N_m3u8DL_RE.Common.Resource
public static string cmd_selectAudio_more { get => GetText("cmd_selectAudio_more"); } public static string cmd_selectAudio_more { get => GetText("cmd_selectAudio_more"); }
public static string cmd_selectSubtitle { get => GetText("cmd_selectSubtitle"); } public static string cmd_selectSubtitle { get => GetText("cmd_selectSubtitle"); }
public static string cmd_selectSubtitle_more { get => GetText("cmd_selectSubtitle_more"); } public static string cmd_selectSubtitle_more { get => GetText("cmd_selectSubtitle_more"); }
public static string cmd_customHLSMethod { get => GetText("cmd_customHLSMethod"); }
public static string cmd_customHLSKey { get => GetText("cmd_customHLSKey"); }
public static string cmd_customHLSIv { get => GetText("cmd_customHLSIv"); }
public static string cmd_Input { get => GetText("cmd_Input"); } public static string cmd_Input { get => GetText("cmd_Input"); }
public static string cmd_keys { get => GetText("cmd_keys"); } public static string cmd_keys { get => GetText("cmd_keys"); }
public static string cmd_keyText { get => GetText("cmd_keyText"); } public static string cmd_keyText { get => GetText("cmd_keyText"); }
@ -57,6 +60,7 @@ namespace N_m3u8DL_RE.Common.Resource
public static string cmd_urlProcessorArgs { get => GetText("cmd_urlProcessorArgs"); } public static string cmd_urlProcessorArgs { get => GetText("cmd_urlProcessorArgs"); }
public static string cmd_useShakaPackager { get => GetText("cmd_useShakaPackager"); } public static string cmd_useShakaPackager { get => GetText("cmd_useShakaPackager"); }
public static string cmd_concurrentDownload { get => GetText("cmd_concurrentDownload"); } public static string cmd_concurrentDownload { get => GetText("cmd_concurrentDownload"); }
public static string cmd_useSystemProxy { get => GetText("cmd_useSystemProxy"); }
public static string cmd_liveKeepSegments { get => GetText("cmd_liveKeepSegments"); } public static string cmd_liveKeepSegments { get => GetText("cmd_liveKeepSegments"); }
public static string cmd_liveRecordLimit { get => GetText("cmd_liveRecordLimit"); } public static string cmd_liveRecordLimit { get => GetText("cmd_liveRecordLimit"); }
public static string cmd_liveRealTimeMerge { get => GetText("cmd_liveRealTimeMerge"); } public static string cmd_liveRealTimeMerge { get => GetText("cmd_liveRealTimeMerge"); }

View File

@ -244,17 +244,41 @@ namespace N_m3u8DL_RE.Common.Resource
zhTW: "錄製直播時即時合併", zhTW: "錄製直播時即時合併",
enUS: "Real-time merge into file when recording live" enUS: "Real-time merge into file when recording live"
), ),
["cmd_useSystemProxy"] = new TextContainer
(
zhCN: "使用系统默认代理",
zhTW: "使用系統默認代理",
enUS: "Use system default proxy"
),
["cmd_livePerformAsVod"] = new TextContainer ["cmd_livePerformAsVod"] = new TextContainer
( (
zhCN: "以点播方式下载直播流", zhCN: "以点播方式下载直播流",
zhTW: "以點播方式下載直播流", zhTW: "以點播方式下載直播流",
enUS: "Download live streams as vod" enUS: "Download live streams as vod"
), ),
["cmd_customHLSMethod"] = new TextContainer
(
zhCN: "指定HLS加密方式 (AES_128|AES_128_ECB|CENC|CHACHA20|NONE|SAMPLE_AES|SAMPLE_AES_CTR|UNKNOWN)",
zhTW: "指定HLS加密方式 (AES_128|AES_128_ECB|CENC|CHACHA20|NONE|SAMPLE_AES|SAMPLE_AES_CTR|UNKNOWN)",
enUS: "Set HLS encryption method (AES_128|AES_128_ECB|CENC|CHACHA20|NONE|SAMPLE_AES|SAMPLE_AES_CTR|UNKNOWN)"
),
["cmd_customHLSKey"] = new TextContainer
(
zhCN: "指定HLS解密KEY. 可以是文件, HEX或Base64",
zhTW: "指定HLS解密KEY. 可以是文件, HEX或Base64",
enUS: "Set the HLS decryption key. Can be file, HEX or Base64"
),
["cmd_customHLSIv"] = new TextContainer
(
zhCN: "指定HLS解密IV. 可以是文件, HEX或Base64",
zhTW: "指定HLS解密IV. 可以是文件, HEX或Base64",
enUS: "Set the HLS decryption iv. Can be file, HEX or Base64"
),
["cmd_liveKeepSegments"] = new TextContainer ["cmd_liveKeepSegments"] = new TextContainer
( (
zhCN: "录制直播并开启实时合并时依然保留分片", zhCN: "录制直播并开启实时合并时依然保留分片",
zhTW: "錄製直播並開啟即時合併時依然保留分片", zhTW: "錄製直播並開啟即時合併時依然保留分片",
enUS: "Keep segments when recording a live broadcast and enable liveRealTimeMerge" enUS: "Keep segments when recording a live (liveRealTimeMerge enabled)"
), ),
["cmd_liveRecordLimit"] = new TextContainer ["cmd_liveRecordLimit"] = new TextContainer
( (
@ -276,9 +300,9 @@ namespace N_m3u8DL_RE.Common.Resource
), ),
["cmd_selectVideo"] = new TextContainer ["cmd_selectVideo"] = new TextContainer
( (
zhCN: "通过正则表达式选择符合要求的视频流. 输入 \"--morehelp select-video\" 以查看详细信息.", zhCN: "通过正则表达式选择符合要求的视频流. 输入 \"--morehelp select-video\" 以查看详细信息",
zhTW: "通過正則表達式選擇符合要求的影片軌. 輸入 \"--morehelp select-video\" 以查看詳細訊息.", zhTW: "通過正則表達式選擇符合要求的影片軌. 輸入 \"--morehelp select-video\" 以查看詳細訊息",
enUS: "Select video streams by regular expressions. Use \"--morehelp select-video\" for more details." enUS: "Select video streams by regular expressions. Use \"--morehelp select-video\" for more details"
), ),
["cmd_selectVideo_more"] = new TextContainer ["cmd_selectVideo_more"] = new TextContainer
( (
@ -312,9 +336,9 @@ namespace N_m3u8DL_RE.Common.Resource
), ),
["cmd_selectAudio"] = new TextContainer ["cmd_selectAudio"] = new TextContainer
( (
zhCN: "通过正则表达式选择符合要求的音频流. 输入 \"--morehelp select-audio\" 以查看详细信息.", zhCN: "通过正则表达式选择符合要求的音频流. 输入 \"--morehelp select-audio\" 以查看详细信息",
zhTW: "通過正則表達式選擇符合要求的音軌. 輸入 \"--morehelp select-audio\" 以查看詳細訊息.", zhTW: "通過正則表達式選擇符合要求的音軌. 輸入 \"--morehelp select-audio\" 以查看詳細訊息",
enUS: "Select audio streams by regular expressions. Use \"--morehelp select-audio\" for more details." enUS: "Select audio streams by regular expressions. Use \"--morehelp select-audio\" for more details"
), ),
["cmd_selectAudio_more"] = new TextContainer ["cmd_selectAudio_more"] = new TextContainer
( (
@ -345,9 +369,9 @@ namespace N_m3u8DL_RE.Common.Resource
), ),
["cmd_selectSubtitle"] = new TextContainer ["cmd_selectSubtitle"] = new TextContainer
( (
zhCN: "通过正则表达式选择符合要求的字幕流. 输入 \"--morehelp select-subtitle\" 以查看详细信息.", zhCN: "通过正则表达式选择符合要求的字幕流. 输入 \"--morehelp select-subtitle\" 以查看详细信息",
zhTW: "通過正則表達式選擇符合要求的字幕流. 輸入 \"--morehelp select-subtitle\" 以查看詳細訊息.", zhTW: "通過正則表達式選擇符合要求的字幕流. 輸入 \"--morehelp select-subtitle\" 以查看詳細訊息",
enUS: "Select subtitle streams by regular expressions. Use \"--morehelp select-subtitle\" for more details." enUS: "Select subtitle streams by regular expressions. Use \"--morehelp select-subtitle\" for more details"
), ),
["cmd_selectSubtitle_more"] = new TextContainer ["cmd_selectSubtitle_more"] = new TextContainer
( (
@ -411,15 +435,15 @@ namespace N_m3u8DL_RE.Common.Resource
), ),
["cmd_muxAfterDone"] = new TextContainer ["cmd_muxAfterDone"] = new TextContainer
( (
zhCN: "所有工作完成时尝试混流分离的音视频. 输入 \"--morehelp mux-after-done\" 以查看详细信息.", zhCN: "所有工作完成时尝试混流分离的音视频. 输入 \"--morehelp mux-after-done\" 以查看详细信息",
zhTW: "所有工作完成時嘗試混流分離的影音. 輸入 \"--morehelp mux-after-done\" 以查看詳細訊息.", zhTW: "所有工作完成時嘗試混流分離的影音. 輸入 \"--morehelp mux-after-done\" 以查看詳細訊息",
enUS: "When all works is done, try to mux the downloaded streams. Use \"--morehelp mux-after-done\" for more details." enUS: "When all works is done, try to mux the downloaded streams. Use \"--morehelp mux-after-done\" for more details"
), ),
["cmd_muxImport"] = new TextContainer ["cmd_muxImport"] = new TextContainer
( (
zhCN: "混流时引入外部媒体文件. 输入 \"--morehelp mux-import\" 以查看详细信息.", zhCN: "混流时引入外部媒体文件. 输入 \"--morehelp mux-import\" 以查看详细信息",
zhTW: "混流時引入外部媒體檔案. 輸入 \"--morehelp mux-import\" 以查看詳細訊息.", zhTW: "混流時引入外部媒體檔案. 輸入 \"--morehelp mux-import\" 以查看詳細訊息",
enUS: "When MuxAfterDone enabled, allow to import local media files. Use \"--morehelp mux-import\" for more details." enUS: "When MuxAfterDone enabled, allow to import local media files. Use \"--morehelp mux-import\" for more details"
), ),
["cmd_muxImport_more"] = new TextContainer ["cmd_muxImport_more"] = new TextContainer
( (

View File

@ -23,13 +23,14 @@ namespace N_m3u8DL_RE.Common.Util
{ {
public class HTTPUtil public class HTTPUtil
{ {
public static readonly HttpClientHandler HttpClientHandler = new()
public static readonly HttpClient AppHttpClient = new(new HttpClientHandler
{ {
AllowAutoRedirect = false, AllowAutoRedirect = false,
AutomaticDecompression = DecompressionMethods.All, AutomaticDecompression = DecompressionMethods.All,
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
}) };
public static readonly HttpClient AppHttpClient = new(HttpClientHandler)
{ {
Timeout = TimeSpan.FromMinutes(2) Timeout = TimeSpan.FromMinutes(2)
}; };

View File

@ -13,6 +13,25 @@ namespace N_m3u8DL_RE.Common.Util
return BitConverter.ToString(data).Replace("-", split); return BitConverter.ToString(data).Replace("-", split);
} }
/// <summary>
/// 判断是不是HEX字符串
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
public static bool TryParseHexString(string input, out byte[]? bytes)
{
bytes = null;
input = input.ToUpper();
if (input.StartsWith("0X"))
input = input[2..];
if (input.Length % 2 != 0)
return false;
if (input.Any(c => !"0123456789ABCDEF".Contains(c)))
return false;
bytes = HexToBytes(input);
return true;
}
public static byte[] HexToBytes(string hex) public static byte[] HexToBytes(string hex)
{ {
hex = hex.Trim(); hex = hex.Trim();

View File

@ -318,18 +318,6 @@ namespace N_m3u8DL_RE.Parser.Extractor
//解析KEY //解析KEY
else if (line.StartsWith(HLSTags.ext_x_key)) else if (line.StartsWith(HLSTags.ext_x_key))
{ {
//自定义KEY情况 不读取当前行的KEY信息.
//对于IV没自定义且当前行有IV的话 就用
if (ParserConfig.CustomeKey != null)
{
currentEncryptInfo.Key = ParserConfig.CustomeKey;
if (ParserConfig.CustomeIV == null && line.Contains("IV=0x"))
currentEncryptInfo.IV = HexUtil.HexToBytes(ParserUtil.GetAttribute(line, "IV"));
continue;
}
var iv = ParserUtil.GetAttribute(line, "IV");
var method = ParserUtil.GetAttribute(line, "METHOD");
var uri = ParserUtil.GetAttribute(line, "URI"); var uri = ParserUtil.GetAttribute(line, "URI");
var uri_last = ParserUtil.GetAttribute(lastKeyLine, "URI"); var uri_last = ParserUtil.GetAttribute(lastKeyLine, "URI");

View File

@ -28,12 +28,21 @@ namespace N_m3u8DL_RE.Parser.Processor.HLS
Logger.Debug("METHOD:{},URI:{},IV:{}", method, uri, iv); Logger.Debug("METHOD:{},URI:{},IV:{}", method, uri, iv);
var encryptInfo = new EncryptInfo(method); var encryptInfo = new EncryptInfo(method);
//处理自定义加密方式
if (parserConfig.CustomMethod != null)
{
encryptInfo.Method = parserConfig.CustomMethod.Value;
Logger.Warn("METHOD changed to {}", method, encryptInfo.Method);
}
//IV //IV
if (!string.IsNullOrEmpty(iv)) if (!string.IsNullOrEmpty(iv))
{ {
encryptInfo.IV = HexUtil.HexToBytes(iv); encryptInfo.IV = HexUtil.HexToBytes(iv);
} }
if (parserConfig.CustomeIV != null) //自定义IV
if (parserConfig.CustomeIV != null && parserConfig.CustomeIV.Length > 0)
{ {
encryptInfo.IV = parserConfig.CustomeIV; encryptInfo.IV = parserConfig.CustomeIV;
} }
@ -41,7 +50,7 @@ namespace N_m3u8DL_RE.Parser.Processor.HLS
//KEY //KEY
try try
{ {
if (parserConfig.CustomeKey != null) if (parserConfig.CustomeKey != null && parserConfig.CustomeKey.Length > 0)
{ {
encryptInfo.Key = parserConfig.CustomeKey; encryptInfo.Key = parserConfig.CustomeKey;
} }
@ -75,7 +84,7 @@ namespace N_m3u8DL_RE.Parser.Processor.HLS
{ {
Logger.WarnMarkUp($"[grey]{_ex.Message.EscapeMarkup()} retryCount: {retryCount}[/]"); Logger.WarnMarkUp($"[grey]{_ex.Message.EscapeMarkup()} retryCount: {retryCount}[/]");
Thread.Sleep(1000); Thread.Sleep(1000);
if (retryCount > 0) goto getHttpKey; if (retryCount-- > 0) goto getHttpKey;
else throw; else throw;
} }
} }

View File

@ -1,5 +1,7 @@
using N_m3u8DL_RE.Common.Log; using N_m3u8DL_RE.Common.Enum;
using N_m3u8DL_RE.Common.Log;
using N_m3u8DL_RE.Common.Resource; using N_m3u8DL_RE.Common.Resource;
using N_m3u8DL_RE.Common.Util;
using N_m3u8DL_RE.Entity; using N_m3u8DL_RE.Entity;
using N_m3u8DL_RE.Enum; using N_m3u8DL_RE.Enum;
using N_m3u8DL_RE.Util; using N_m3u8DL_RE.Util;
@ -48,9 +50,18 @@ namespace N_m3u8DL_RE.CommandLine
private readonly static Option<string?> BaseUrl = new(new string[] { "--base-url" }, description: ResString.cmd_baseUrl); private readonly static Option<string?> BaseUrl = new(new string[] { "--base-url" }, description: ResString.cmd_baseUrl);
private readonly static Option<bool> ConcurrentDownload = new(new string[] { "-mt", "--concurrent-download" }, description: ResString.cmd_concurrentDownload, getDefaultValue: () => false); private readonly static Option<bool> ConcurrentDownload = new(new string[] { "-mt", "--concurrent-download" }, description: ResString.cmd_concurrentDownload, getDefaultValue: () => false);
//代理选项
private readonly static Option<bool> UseSystemProxy = new(new string[] { "--use-system-proxy" }, description: ResString.cmd_useSystemProxy, getDefaultValue: () => true);
//morehelp //morehelp
private readonly static Option<string?> MoreHelp = new(new string[] { "--morehelp" }, description: ResString.cmd_moreHelp) { ArgumentHelpName = "OPTION" }; private readonly static Option<string?> MoreHelp = new(new string[] { "--morehelp" }, description: ResString.cmd_moreHelp) { ArgumentHelpName = "OPTION" };
//自定义KEY等
private readonly static Option<EncryptMethod?> CustomHLSMethod = new(name: "--custom-hls-method", description: ResString.cmd_customHLSMethod) { ArgumentHelpName = "METHOD" };
private readonly static Option<byte[]?> CustomHLSKey = new(name: "--custom-hls-key", description: ResString.cmd_customHLSKey, parseArgument: ParseHLSCustomKey) { ArgumentHelpName = "FILE|HEX|BASE64" };
private readonly static Option<byte[]?> CustomHLSIv = new(name: "--custom-hls-iv", description: ResString.cmd_customHLSIv, parseArgument: ParseHLSCustomKey) { ArgumentHelpName = "FILE|HEX|BASE64" };
//直播相关 //直播相关
private readonly static Option<bool> LivePerformAsVod = new(new string[] { "--live-perform-as-vod" }, description: ResString.cmd_livePerformAsVod, getDefaultValue: () => false); private readonly static Option<bool> LivePerformAsVod = new(new string[] { "--live-perform-as-vod" }, description: ResString.cmd_livePerformAsVod, getDefaultValue: () => false);
private readonly static Option<bool> LiveRealTimeMerge = new(new string[] { "--live-real-time-merge" }, description: ResString.cmd_liveRealTimeMerge, getDefaultValue: () => false); private readonly static Option<bool> LiveRealTimeMerge = new(new string[] { "--live-real-time-merge" }, description: ResString.cmd_liveRealTimeMerge, getDefaultValue: () => false);
@ -65,6 +76,32 @@ namespace N_m3u8DL_RE.CommandLine
private readonly static Option<StreamFilter?> AudioFilter = new(new string[] { "-sa", "--select-audio" }, description: ResString.cmd_selectAudio, parseArgument: ParseStreamFilter) { ArgumentHelpName = "OPTIONS" }; private readonly static Option<StreamFilter?> AudioFilter = new(new string[] { "-sa", "--select-audio" }, description: ResString.cmd_selectAudio, parseArgument: ParseStreamFilter) { ArgumentHelpName = "OPTIONS" };
private readonly static Option<StreamFilter?> SubtitleFilter = new(new string[] { "-ss", "--select-subtitle" }, description: ResString.cmd_selectSubtitle, parseArgument: ParseStreamFilter) { ArgumentHelpName = "OPTIONS" }; private readonly static Option<StreamFilter?> SubtitleFilter = new(new string[] { "-ss", "--select-subtitle" }, description: ResString.cmd_selectSubtitle, parseArgument: ParseStreamFilter) { ArgumentHelpName = "OPTIONS" };
/// <summary>
/// 解析自定义KEY
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
private static byte[]? ParseHLSCustomKey(ArgumentResult result)
{
var input = result.Tokens.First().Value;
try
{
if (string.IsNullOrEmpty(input))
return null;
if (File.Exists(input))
return File.ReadAllBytes(input);
else if (HexUtil.TryParseHexString(input, out byte[]? bytes))
return bytes;
else
return Convert.FromBase64String(input);
}
catch (Exception)
{
result.ErrorMessage = "error in parse hls custom key: " + input;
return null;
}
}
/// <summary> /// <summary>
/// 解析录制直播时长限制 /// 解析录制直播时长限制
/// </summary> /// </summary>
@ -302,6 +339,10 @@ namespace N_m3u8DL_RE.CommandLine
LiveKeepSegments = bindingContext.ParseResult.GetValueForOption(LiveKeepSegments), LiveKeepSegments = bindingContext.ParseResult.GetValueForOption(LiveKeepSegments),
LiveRecordLimit = bindingContext.ParseResult.GetValueForOption(LiveRecordLimit), LiveRecordLimit = bindingContext.ParseResult.GetValueForOption(LiveRecordLimit),
LivePerformAsVod = bindingContext.ParseResult.GetValueForOption(LivePerformAsVod), LivePerformAsVod = bindingContext.ParseResult.GetValueForOption(LivePerformAsVod),
UseSystemProxy = bindingContext.ParseResult.GetValueForOption(UseSystemProxy),
CustomHLSMethod = bindingContext.ParseResult.GetValueForOption(CustomHLSMethod),
CustomHLSKey = bindingContext.ParseResult.GetValueForOption(CustomHLSKey),
CustomHLSIv = bindingContext.ParseResult.GetValueForOption(CustomHLSIv),
}; };
var parsedHeaders = bindingContext.ParseResult.GetValueForOption(Headers); var parsedHeaders = bindingContext.ParseResult.GetValueForOption(Headers);
@ -362,6 +403,7 @@ namespace N_m3u8DL_RE.CommandLine
FFmpegBinaryPath, FFmpegBinaryPath,
LogLevel, UILanguage, UrlProcessorArgs, Keys, KeyTextFile, DecryptionBinaryPath, UseShakaPackager, MP4RealTimeDecryption, LogLevel, UILanguage, UrlProcessorArgs, Keys, KeyTextFile, DecryptionBinaryPath, UseShakaPackager, MP4RealTimeDecryption,
MuxAfterDone, MuxAfterDone,
CustomHLSMethod, CustomHLSKey, CustomHLSIv, UseSystemProxy,
LivePerformAsVod, LiveRealTimeMerge, LiveKeepSegments, LiveRecordLimit, LivePerformAsVod, LiveRealTimeMerge, LiveKeepSegments, LiveRecordLimit,
MuxImports, VideoFilter, AudioFilter, SubtitleFilter, MoreHelp MuxImports, VideoFilter, AudioFilter, SubtitleFilter, MoreHelp
}; };

View File

@ -1,4 +1,5 @@
using N_m3u8DL_RE.Common.Log; using N_m3u8DL_RE.Common.Enum;
using N_m3u8DL_RE.Common.Log;
using N_m3u8DL_RE.Entity; using N_m3u8DL_RE.Entity;
using N_m3u8DL_RE.Enum; using N_m3u8DL_RE.Enum;
@ -123,6 +124,10 @@ namespace N_m3u8DL_RE.CommandLine
/// </summary> /// </summary>
public bool LivePerformAsVod { get; set; } public bool LivePerformAsVod { get; set; }
/// <summary> /// <summary>
/// See: <see cref="CommandInvoker.UseSystemProxy"/>.
/// </summary>
public bool UseSystemProxy { get; set; }
/// <summary>
/// See: <see cref="CommandInvoker.SubtitleFormat"/>. /// See: <see cref="CommandInvoker.SubtitleFormat"/>.
/// </summary> /// </summary>
public SubtitleFormat SubtitleFormat { get; set; } public SubtitleFormat SubtitleFormat { get; set; }
@ -174,6 +179,18 @@ namespace N_m3u8DL_RE.CommandLine
/// See: <see cref="CommandInvoker.SubtitleFilter"/>. /// See: <see cref="CommandInvoker.SubtitleFilter"/>.
/// </summary> /// </summary>
public StreamFilter? SubtitleFilter { get; set; } public StreamFilter? SubtitleFilter { get; set; }
/// <summary>
/// See: <see cref="CommandInvoker.CustomHLSMethod"/>.
/// </summary>
public EncryptMethod? CustomHLSMethod { get; set; }
/// <summary>
/// See: <see cref="CommandInvoker.CustomHLSKey"/>.
/// </summary>
public byte[]? CustomHLSKey { get; set; }
/// <summary>
/// See: <see cref="CommandInvoker.CustomHLSIv"/>.
/// </summary>
public byte[]? CustomHLSIv { get; set; }
public bool MuxKeepFiles { get; set; } public bool MuxKeepFiles { get; set; }
} }
} }

View File

@ -58,6 +58,11 @@ namespace N_m3u8DL_RE
{ {
Logger.LogLevel = option.LogLevel; Logger.LogLevel = option.LogLevel;
if (option.UseSystemProxy == false)
{
HTTPUtil.HttpClientHandler.UseProxy = false;
}
try try
{ {
//检查互斥的选项 //检查互斥的选项
@ -130,7 +135,10 @@ namespace N_m3u8DL_RE
AppendUrlParams = option.AppendUrlParams, AppendUrlParams = option.AppendUrlParams,
UrlProcessorArgs = option.UrlProcessorArgs, UrlProcessorArgs = option.UrlProcessorArgs,
BaseUrl = option.BaseUrl!, BaseUrl = option.BaseUrl!,
Headers = headers Headers = headers,
CustomMethod = option.CustomHLSMethod,
CustomeKey = option.CustomHLSKey,
CustomeIV = option.CustomHLSIv,
}; };
//demo1 //demo1

View File

@ -1,5 +1,6 @@
using N_m3u8DL_RE.Common.Log; using N_m3u8DL_RE.Common.Log;
using N_m3u8DL_RE.Common.Resource; using N_m3u8DL_RE.Common.Resource;
using N_m3u8DL_RE.Common.Util;
using N_m3u8DL_RE.Entity; using N_m3u8DL_RE.Entity;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
@ -14,15 +15,7 @@ namespace N_m3u8DL_RE.Util
{ {
internal class DownloadUtil internal class DownloadUtil
{ {
private static readonly HttpClient AppHttpClient = new(new HttpClientHandler private static readonly HttpClient AppHttpClient = HTTPUtil.AppHttpClient;
{
AllowAutoRedirect = false,
AutomaticDecompression = DecompressionMethods.All,
ServerCertificateCustomValidationCallback = (sender, cert, chain, sslPolicyErrors) => true
})
{
Timeout = TimeSpan.FromMinutes(2)
};
public static async Task<DownloadResult> DownloadToFileAsync(string url, string path, SpeedContainer speedContainer, Dictionary<string, string>? headers = null, long? fromPosition = null, long? toPosition = null) public static async Task<DownloadResult> DownloadToFileAsync(string url, string path, SpeedContainer speedContainer, Dictionary<string, string>? headers = null, long? fromPosition = null, long? toPosition = null)
{ {

View File

@ -8,9 +8,9 @@ namespace N_m3u8DL_RE.Util
{ {
internal class OtherUtil internal class OtherUtil
{ {
public static Dictionary<string,string> SplitHeaderArrayToDic(string[]? headers) public static Dictionary<string, string> SplitHeaderArrayToDic(string[]? headers)
{ {
Dictionary<string,string> dic = new(); Dictionary<string, string> dic = new();
if (headers != null) if (headers != null)
{ {