1
mirror of https://github.com/nilaoda/N_m3u8DL-CLI synced 2025-09-17 08:40:50 +02:00

Compare commits

..

7 Commits
3.0.1 ... 3.0.2

Author SHA1 Message Date
nilaoda
f5a9ed08a1 update version 2022-07-12 00:21:39 +08:00
nilaoda
6b8bfde19f update docs 2022-07-12 00:10:53 +08:00
nilaoda
ff738f2849 Merge pull request #698 from xifangczy/master
fix: 修正m3u8dl协议 转义符问题
2022-07-11 23:44:31 +08:00
O2bmm
3d35c24a2e fix: 修正m3u8dl协议 转义符问题 2022-07-11 01:32:30 +08:00
nilaoda
41d7151e7e Update HLSLiveDownloader.cs 2022-06-22 11:43:36 +08:00
nilaoda
94246ef163 支持ChaCha20解密 2022-06-20 23:18:27 +08:00
nilaoda
9c118631cf 优化对#EXT-X-BYTERANGE的处理 2022-06-05 02:15:24 +08:00
19 changed files with 755 additions and 15 deletions

661
N_m3u8DL-CLI/CSChaCha20.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,7 @@
using System;
using CSChaCha20;
using System;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
namespace N_m3u8DL_CLI
@@ -45,6 +47,40 @@ namespace N_m3u8DL_CLI
return resultArray;
}
public static byte[] CHACHA20Decrypt(byte[] encryptedBuff, byte[] keyBytes, byte[] nonceBytes)
{
if (keyBytes.Length != 32)
throw new Exception("Key must be 32 bytes!");
if (nonceBytes.Length != 12 && nonceBytes.Length != 8)
throw new Exception("Key must be 12 or 8 bytes!");
if (nonceBytes.Length == 8)
nonceBytes = (new byte[4] { 0, 0, 0, 0 }).Concat(nonceBytes).ToArray();
var decStream = new MemoryStream();
using (BinaryReader reader = new BinaryReader(new MemoryStream(encryptedBuff)))
{
using (BinaryWriter writer = new BinaryWriter(decStream))
{
while (true)
{
var buffer = reader.ReadBytes(1024);
byte[] dec = new byte[buffer.Length];
if (buffer.Length > 0)
{
ChaCha20 forDecrypting = new ChaCha20(keyBytes, nonceBytes, 0);
forDecrypting.DecryptBytes(dec, buffer);
writer.Write(dec, 0, dec.Length);
}
else
{
break;
}
}
}
}
return decStream.ToArray();
}
public static byte[] HexStringToBytes(string hexStr)
{
if (string.IsNullOrEmpty(hexStr))

View File

@@ -47,6 +47,10 @@ namespace N_m3u8DL_CLI
public long ExpectByte { get => expectByte; set => expectByte = value; }
public long StartByte { get => startByte; set => startByte = value; }
public double SegDur { get => segDur; set => segDur = value; }
public static bool EnableChaCha20 { get; set; } = false;
public static string ChaCha20KeyBase64 { get; set; }
public static string ChaCha20NonceBase64 { get; set; }
//重写WebClinet
//private class WebClient : System.Net.WebClient
@@ -179,9 +183,18 @@ namespace N_m3u8DL_CLI
if (File.Exists(savePath) && Global.ShouldStop == false)
{
FileInfo fi = new FileInfo(savePath);
if (Method == "NONE" || method.Contains("NOTSUPPORTED"))
if (File.Exists(fi.FullName) && EnableChaCha20)
{
fi.MoveTo(Path.GetDirectoryName(savePath) + "\\" + Path.GetFileNameWithoutExtension(savePath) + ".ts");
byte[] decryptBuff = Decrypter.CHACHA20Decrypt(File.ReadAllBytes(fi.FullName), Convert.FromBase64String(ChaCha20KeyBase64), Convert.FromBase64String(ChaCha20NonceBase64));
FileStream fs = new FileStream(Path.GetDirectoryName(SavePath) + "\\" + Path.GetFileNameWithoutExtension(SavePath) + ".ts", FileMode.Create);
fs.Write(decryptBuff, 0, decryptBuff.Length);
fs.Close();
DownloadManager.DownloadedSize += fi.Length;
fi.Delete();
}
else if (Method == "NONE" || Method.Contains("NOTSUPPORTED"))
{
fi.MoveTo(Path.GetDirectoryName(SavePath) + "\\" + Path.GetFileNameWithoutExtension(SavePath) + ".ts");
DownloadManager.DownloadedSize += fi.Length;
//Console.WriteLine(Path.GetFileNameWithoutExtension(savePath) + " Completed.");
}
@@ -249,4 +262,4 @@ namespace N_m3u8DL_CLI
}
}
}
}
}

View File

@@ -35,7 +35,7 @@ namespace N_m3u8DL_CLI
/*===============================================================================*/
static Version ver = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
static string nowVer = $"{ver.Major}.{ver.Minor}.{ver.Build}";
static string nowDate = "20220526";
static string nowDate = "20220711";
public static void WriteInit()
{
Console.WriteLine($"N_m3u8DL-CLI version {nowVer} 2018-2022");

View File

@@ -128,6 +128,7 @@ namespace N_m3u8DL_CLI
sd.Iv = info["iv"].Value<string>();
}
sd.TimeOut = (int)timer.Interval - 1000;//超时时间不超过下次执行时间
if (sd.TimeOut <= 0) sd.TimeOut = (int)timer.Interval;
sd.SegIndex = index;
sd.Headers = Headers;
sd.SegDur = info["duration"].Value<double>();

View File

@@ -97,5 +97,14 @@ namespace N_m3u8DL_CLI
[Option("unregisterUrlProtocol", HelpText = "Help_unregisterUrlProtocol", ResourceType = typeof(strings))]
public bool UnregisterUrlProtocol { get; set; }
[Option("enableChaCha20", HelpText = "enableChaCha20")]
public bool EnableChaCha20 { get; set; }
[Option("chaCha20KeyBase64", HelpText = "ChaCha20KeyBase64")]
public string ChaCha20KeyBase64 { get; set; }
[Option("chaCha20NonceBase64", HelpText = "ChaCha20NonceBase64")]
public string ChaCha20NonceBase64 { get; set; }
}
}

View File

@@ -90,6 +90,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="CSChaCha20.cs" />
<Compile Include="Decode51CtoKey.cs" />
<Compile Include="DecodeCdeledu.cs" />
<Compile Include="DecodeDdyun.cs" />

View File

@@ -271,6 +271,7 @@ namespace N_m3u8DL_CLI
{
expectByte = Convert.ToInt64(t[0]);
segInfo.Add("expectByte", expectByte);
segInfo.Add("startByte", segments.Last["startByte"].Value<long>() + segments.Last["expectByte"].Value<long>());
}
if (t.Length == 2)
{

View File

@@ -81,6 +81,8 @@ namespace N_m3u8DL_CLI.NetCore
var cmd = "";
try { cmd = Encoding.UTF8.GetString(Convert.FromBase64String(base64)); }
catch (FormatException) { cmd = Encoding.UTF8.GetString(Convert.FromBase64String(base64.TrimEnd('/'))); }
//修正参数转义符
cmd = cmd.Replace("\\\"", "\"");
//修正工作目录
Environment.CurrentDirectory = Path.GetDirectoryName(Process.GetCurrentProcess().MainModule.FileName);
args = Global.ParseArguments(cmd).ToArray(); //解析命令行
@@ -225,6 +227,13 @@ namespace N_m3u8DL_CLI.NetCore
workDir = Environment.ExpandEnvironmentVariables(o.WorkDir);
DownloadManager.HasSetDir = true;
}
//CHACHA20
if (o.EnableChaCha20 && !string.IsNullOrEmpty(o.ChaCha20KeyBase64) && !string.IsNullOrEmpty(o.ChaCha20NonceBase64))
{
Downloader.EnableChaCha20 = true;
Downloader.ChaCha20KeyBase64 = o.ChaCha20KeyBase64;
Downloader.ChaCha20NonceBase64 = o.ChaCha20NonceBase64;
}
//Proxy
if (!string.IsNullOrEmpty(o.ProxyAddress))

View File

@@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("3.0.1.0")]
[assembly: AssemblyFileVersion("3.0.1.0")]
[assembly: AssemblyVersion("3.0.2.0")]
[assembly: AssemblyFileVersion("3.0.2.0")]

View File

@@ -89,6 +89,9 @@ OPTIONS:
--noProxy 不自动使用系统代理
--registerUrlProtocol 注册m3u8dl链接协议
--unregisterUrlProtocol 取消注册m3u8dl链接协议
--enableChaCha20 enableChaCha20
--chaCha20KeyBase64 ChaCha20KeyBase64
--chaCha20NonceBase64 ChaCha20NonceBase64
--help Display this help screen.
--version Display version information.
```

View File

@@ -68,6 +68,9 @@ OPTIONS:
--noProxy Disable use system proxy
--registerUrlProtocol Register m3u8dl URL protocol
--unregisterUrlProtocol Unregister m3u8dl URL protocol
--enableChaCha20 enableChaCha20
--chaCha20KeyBase64 ChaCha20KeyBase64
--chaCha20NonceBase64 ChaCha20NonceBase64
--help Display this help screen.
--version Display version information.
```

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long