You've already forked N_m3u8DL-CLI
mirror of
https://github.com/nilaoda/N_m3u8DL-CLI
synced 2025-09-13 22:40:51 +02:00
Compare commits
7 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
4a4bfae5ab | ||
![]() |
d586dddfcd | ||
![]() |
fca6b3ff6c | ||
![]() |
5d75626a36 | ||
![]() |
a94271c244 | ||
![]() |
c51118dce7 | ||
![]() |
81b2e87bf7 |
53
N_m3u8DL-CLI/DecodeHuke88Key.cs
Normal file
53
N_m3u8DL-CLI/DecodeHuke88Key.cs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace N_m3u8DL_CLI
|
||||||
|
{
|
||||||
|
//https://js.huke88.com/assets/revision/js/plugins/tcplayer/tcplayer.v4.1.min.js?v=930
|
||||||
|
//https://js.huke88.com/assets/revision/js/plugins/tcplayer/libs/hls.min.0.13.2m.js?v=930
|
||||||
|
class DecodeHuke88Key
|
||||||
|
{
|
||||||
|
private static string[] GetOverlayInfo(string url)
|
||||||
|
{
|
||||||
|
var enc = new Regex("eyJ\\w{100,}").Match(url).Value;
|
||||||
|
var json = Encoding.UTF8.GetString(Convert.FromBase64String(enc));
|
||||||
|
JObject jObject = JObject.Parse(json);
|
||||||
|
var key = jObject["overlayKey"].ToString();
|
||||||
|
var iv = jObject["overlayIv"].ToString();
|
||||||
|
return new string[] { key, iv };
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string DecodeKey(string url, byte[] data)
|
||||||
|
{
|
||||||
|
var info = GetOverlayInfo(url);
|
||||||
|
var overlayKey = info[0];
|
||||||
|
var overlayIv = info[1];
|
||||||
|
var l = new List<byte>();
|
||||||
|
var c = new List<byte>();
|
||||||
|
for (int h = 0; h < 16; h++)
|
||||||
|
{
|
||||||
|
var f = overlayKey.Substring(2 * h, 2);
|
||||||
|
var g = overlayIv.Substring(2 * h, 2);
|
||||||
|
l.Add(Convert.ToByte(f, 16));
|
||||||
|
c.Add(Convert.ToByte(g, 16));
|
||||||
|
}
|
||||||
|
|
||||||
|
var _lastCipherblock = c.ToArray();
|
||||||
|
|
||||||
|
var t = new byte[data.Length];
|
||||||
|
var r = data;
|
||||||
|
r = Decrypter.AES128Decrypt(data, l.ToArray(), Decrypter.HexStringToBytes("00000000000000000000000000000000"), CipherMode.CBC, PaddingMode.Zeros);
|
||||||
|
|
||||||
|
for (var o = 0; o < 16; o++)
|
||||||
|
t[o] = (byte)(r[o] ^ _lastCipherblock[o]);
|
||||||
|
|
||||||
|
var key = Convert.ToBase64String(t);
|
||||||
|
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@@ -1,16 +1,12 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Security.Cryptography;
|
using System.Security.Cryptography;
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
|
|
||||||
namespace N_m3u8DL_CLI
|
namespace N_m3u8DL_CLI
|
||||||
{
|
{
|
||||||
class Decrypter
|
class Decrypter
|
||||||
{
|
{
|
||||||
public static byte[] AES128Decrypt(string filePath, byte[] keyByte, byte[] ivByte, CipherMode mode = CipherMode.CBC)
|
public static byte[] AES128Decrypt(string filePath, byte[] keyByte, byte[] ivByte, CipherMode mode = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
|
||||||
{
|
{
|
||||||
FileStream fs = new FileStream(filePath, FileMode.Open);
|
FileStream fs = new FileStream(filePath, FileMode.Open);
|
||||||
//获取文件大小
|
//获取文件大小
|
||||||
@@ -25,14 +21,14 @@ namespace N_m3u8DL_CLI
|
|||||||
dcpt.Key = keyByte;
|
dcpt.Key = keyByte;
|
||||||
dcpt.IV = ivByte;
|
dcpt.IV = ivByte;
|
||||||
dcpt.Mode = mode;
|
dcpt.Mode = mode;
|
||||||
dcpt.Padding = PaddingMode.PKCS7;
|
dcpt.Padding = padding;
|
||||||
|
|
||||||
ICryptoTransform cTransform = dcpt.CreateDecryptor();
|
ICryptoTransform cTransform = dcpt.CreateDecryptor();
|
||||||
Byte[] resultArray = cTransform.TransformFinalBlock(inBuff, 0, inBuff.Length);
|
Byte[] resultArray = cTransform.TransformFinalBlock(inBuff, 0, inBuff.Length);
|
||||||
return resultArray;
|
return resultArray;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static byte[] AES128Decrypt(byte[] encryptedBuff, byte[] keyByte, byte[] ivByte, CipherMode mode = CipherMode.CBC)
|
public static byte[] AES128Decrypt(byte[] encryptedBuff, byte[] keyByte, byte[] ivByte, CipherMode mode = CipherMode.CBC, PaddingMode padding = PaddingMode.PKCS7)
|
||||||
{
|
{
|
||||||
byte[] inBuff = encryptedBuff;
|
byte[] inBuff = encryptedBuff;
|
||||||
|
|
||||||
@@ -42,7 +38,7 @@ namespace N_m3u8DL_CLI
|
|||||||
dcpt.Key = keyByte;
|
dcpt.Key = keyByte;
|
||||||
dcpt.IV = ivByte;
|
dcpt.IV = ivByte;
|
||||||
dcpt.Mode = mode;
|
dcpt.Mode = mode;
|
||||||
dcpt.Padding = PaddingMode.PKCS7;
|
dcpt.Padding = padding;
|
||||||
|
|
||||||
ICryptoTransform cTransform = dcpt.CreateDecryptor();
|
ICryptoTransform cTransform = dcpt.CreateDecryptor();
|
||||||
Byte[] resultArray = cTransform.TransformFinalBlock(inBuff, 0, inBuff.Length);
|
Byte[] resultArray = cTransform.TransformFinalBlock(inBuff, 0, inBuff.Length);
|
||||||
@@ -56,7 +52,7 @@ namespace N_m3u8DL_CLI
|
|||||||
return new byte[0];
|
return new byte[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hexStr.StartsWith("0x") || hexStr.StartsWith("0X"))
|
if (hexStr.StartsWith("0x") || hexStr.StartsWith("0X"))
|
||||||
{
|
{
|
||||||
hexStr = hexStr.Remove(0, 2);
|
hexStr = hexStr.Remove(0, 2);
|
||||||
}
|
}
|
||||||
|
@@ -32,7 +32,7 @@ namespace N_m3u8DL_CLI
|
|||||||
/*===============================================================================*/
|
/*===============================================================================*/
|
||||||
static Version ver = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
|
static Version ver = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
|
||||||
static string nowVer = $"{ver.Major}.{ver.Minor}.{ver.Build}";
|
static string nowVer = $"{ver.Major}.{ver.Minor}.{ver.Build}";
|
||||||
static string nowDate = "20201206";
|
static string nowDate = "20210118";
|
||||||
public static void WriteInit()
|
public static void WriteInit()
|
||||||
{
|
{
|
||||||
Console.Clear();
|
Console.Clear();
|
||||||
|
@@ -61,14 +61,18 @@ namespace N_m3u8DL_CLI
|
|||||||
|
|
||||||
void ExtractInitialization(XmlNode source)
|
void ExtractInitialization(XmlNode source)
|
||||||
{
|
{
|
||||||
var initialization = source.SelectSingleNode("//ns:Initialization", nsMgr);
|
var initialization = source.SelectSingleNode("ns:Initialization", nsMgr);
|
||||||
if (initialization != null)
|
if (initialization != null)
|
||||||
{
|
{
|
||||||
MultisegmentInfo["InitializationUrl"] = ((XmlElement)initialization).GetAttribute("sourceURL");
|
MultisegmentInfo["InitializationUrl"] = ((XmlElement)initialization).GetAttribute("sourceURL");
|
||||||
|
if (((XmlElement)initialization).HasAttribute("range"))
|
||||||
|
{
|
||||||
|
MultisegmentInfo["InitializationUrl"] += "$$Range=" + ((XmlElement)initialization).GetAttribute("range");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var segmentList = Period.SelectSingleNode("//ns:SegmentList", nsMgr);
|
var segmentList = Period.SelectSingleNode("ns:SegmentList", nsMgr);
|
||||||
if (segmentList != null)
|
if (segmentList != null)
|
||||||
{
|
{
|
||||||
ExtractCommon(segmentList);
|
ExtractCommon(segmentList);
|
||||||
@@ -77,7 +81,14 @@ namespace N_m3u8DL_CLI
|
|||||||
MultisegmentInfo["SegmentUrls"] = new List<string>();
|
MultisegmentInfo["SegmentUrls"] = new List<string>();
|
||||||
foreach (XmlElement segment in segmentUrlsE)
|
foreach (XmlElement segment in segmentUrlsE)
|
||||||
{
|
{
|
||||||
MultisegmentInfo["SegmentUrls"].Add(segment.GetAttribute("media"));
|
if (segment.HasAttribute("mediaRange"))
|
||||||
|
{
|
||||||
|
MultisegmentInfo["SegmentUrls"].Add("$$Range=" + segment.GetAttribute("mediaRange"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MultisegmentInfo["SegmentUrls"].Add(segment.GetAttribute("media"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -116,6 +127,10 @@ namespace N_m3u8DL_CLI
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string Parse(string downDir, string mpdUrl, string mpdContent, string defaultBase = "")
|
public static string Parse(string downDir, string mpdUrl, string mpdContent, string defaultBase = "")
|
||||||
{
|
{
|
||||||
|
//XiGua
|
||||||
|
if (mpdContent.Contains("<mas:") && !mpdContent.Contains("xmlns:mas"))
|
||||||
|
mpdContent = mpdContent.Replace("<MPD ", "<MPD xmlns:mas=\"urn:marlin:mas:1-0:services:schemas:mpd\" ");
|
||||||
|
|
||||||
XmlDocument mpdDoc = new XmlDocument();
|
XmlDocument mpdDoc = new XmlDocument();
|
||||||
mpdDoc.LoadXml(mpdContent);
|
mpdDoc.LoadXml(mpdContent);
|
||||||
|
|
||||||
@@ -208,6 +223,7 @@ namespace N_m3u8DL_CLI
|
|||||||
var bandwidth = IntOrNull(GetAttribute("bandwidth"));
|
var bandwidth = IntOrNull(GetAttribute("bandwidth"));
|
||||||
var f = new Dictionary<string, dynamic>
|
var f = new Dictionary<string, dynamic>
|
||||||
{
|
{
|
||||||
|
["ContentType"] = contentType,
|
||||||
["FormatId"] = representationId,
|
["FormatId"] = representationId,
|
||||||
["ManifestUrl"] = mpdUrl,
|
["ManifestUrl"] = mpdUrl,
|
||||||
["Width"] = IntOrNull(GetAttribute("width")),
|
["Width"] = IntOrNull(GetAttribute("width")),
|
||||||
@@ -432,6 +448,10 @@ namespace N_m3u8DL_CLI
|
|||||||
if (representationMsInfo.ContainsKey("InitializationUrl"))
|
if (representationMsInfo.ContainsKey("InitializationUrl"))
|
||||||
{
|
{
|
||||||
f["InitializationUrl"] = representationMsInfo["InitializationUrl"];
|
f["InitializationUrl"] = representationMsInfo["InitializationUrl"];
|
||||||
|
if (f["InitializationUrl"].StartsWith("$$Range"))
|
||||||
|
{
|
||||||
|
f["InitializationUrl"] = CombineURL(baseUrl, f["InitializationUrl"]);
|
||||||
|
}
|
||||||
f["Fragments"] = representationMsInfo["Fragments"];
|
f["Fragments"] = representationMsInfo["Fragments"];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -447,7 +467,23 @@ namespace N_m3u8DL_CLI
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
formatList.Add(f);
|
//处理同一ID分散在不同Period的情况
|
||||||
|
if (formatList.Any(_f => _f["FormatId"] == f["FormatId"] && _f["Width"] == f["Width"] && _f["ContentType"] == f["ContentType"]))
|
||||||
|
{
|
||||||
|
for (int i = 0; i < formatList.Count; i++)
|
||||||
|
{
|
||||||
|
if (formatList[i]["FormatId"] == f["FormatId"] && formatList[i]["Width"] == f["Width"] && formatList[i]["ContentType"] == f["ContentType"])
|
||||||
|
{
|
||||||
|
formatList[i]["Fragments"].AddRange(f["Fragments"]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
formatList.Add(f);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -466,14 +502,14 @@ namespace N_m3u8DL_CLI
|
|||||||
var audioLangList = new List<string>();
|
var audioLangList = new List<string>();
|
||||||
formatList.ForEach(f =>
|
formatList.ForEach(f =>
|
||||||
{
|
{
|
||||||
if (f["Width"] == -1 && !audioLangList.Contains(f["Language"])) audioLangList.Add(f["Language"]);
|
if (f["ContentType"] == "audio" && !audioLangList.Contains(f["Language"])) audioLangList.Add(f["Language"]);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (audioLangList.Count > 1)
|
if (audioLangList.Count > 1)
|
||||||
{
|
{
|
||||||
string Stringify(Dictionary<string, dynamic> f)
|
string Stringify(Dictionary<string, dynamic> f)
|
||||||
{
|
{
|
||||||
var type = f["Width"] == -1 && f["Height"] == -1 ? "Audio" : "Video";
|
var type = f["ContentType"] == "aduio" ? "Audio" : "Video";
|
||||||
var res = type == "Video" ? $"[{f["Width"]}x{f["Height"]}]" : "";
|
var res = type == "Video" ? $"[{f["Width"]}x{f["Height"]}]" : "";
|
||||||
var id = $"[{f["FormatId"]}] ";
|
var id = $"[{f["FormatId"]}] ";
|
||||||
var tbr = $"[{((int)f["Tbr"]).ToString().PadLeft(4)} Kbps] ";
|
var tbr = $"[{((int)f["Tbr"]).ToString().PadLeft(4)} Kbps] ";
|
||||||
@@ -503,7 +539,7 @@ namespace N_m3u8DL_CLI
|
|||||||
{
|
{
|
||||||
var n = 0;
|
var n = 0;
|
||||||
int.TryParse(index, out n);
|
int.TryParse(index, out n);
|
||||||
if (formatList[n]["Width"] == -1)
|
if (formatList[n]["ContentType"] == "audio")
|
||||||
{
|
{
|
||||||
bestAudio = formatList[n];
|
bestAudio = formatList[n];
|
||||||
}
|
}
|
||||||
@@ -605,7 +641,7 @@ namespace N_m3u8DL_CLI
|
|||||||
sb.AppendLine("#CREATED-BY:N_m3u8DL-CLI");
|
sb.AppendLine("#CREATED-BY:N_m3u8DL-CLI");
|
||||||
|
|
||||||
//Video
|
//Video
|
||||||
if (f["Width"] != -1 && f["Height"] != -1)
|
if (f["ContentType"] != "audio")
|
||||||
{
|
{
|
||||||
sb.AppendLine($"#EXT-VIDEO-WIDTH:{f["Width"]}");
|
sb.AppendLine($"#EXT-VIDEO-WIDTH:{f["Width"]}");
|
||||||
sb.AppendLine($"#EXT-VIDEO-HEIGHT:{f["Height"]}");
|
sb.AppendLine($"#EXT-VIDEO-HEIGHT:{f["Height"]}");
|
||||||
@@ -615,7 +651,19 @@ namespace N_m3u8DL_CLI
|
|||||||
sb.AppendLine($"#EXT-TBR:{f["Tbr"]}");
|
sb.AppendLine($"#EXT-TBR:{f["Tbr"]}");
|
||||||
if (f.ContainsKey("InitializationUrl"))
|
if (f.ContainsKey("InitializationUrl"))
|
||||||
{
|
{
|
||||||
sb.AppendLine($"#EXT-X-MAP:URI=\"{f["InitializationUrl"]}\"");
|
string initUrl = f["InitializationUrl"];
|
||||||
|
if (Regex.IsMatch(initUrl, "\\$\\$Range=(\\d+)-(\\d+)"))
|
||||||
|
{
|
||||||
|
var match = Regex.Match(initUrl, "\\$\\$Range=(\\d+)-(\\d+)");
|
||||||
|
string rangeStr = match.Value;
|
||||||
|
long start = Convert.ToInt64(match.Groups[1].Value);
|
||||||
|
long end = Convert.ToInt64(match.Groups[2].Value);
|
||||||
|
sb.AppendLine($"#EXT-X-MAP:URI=\"{initUrl.Replace(rangeStr, "")}\",BYTERANGE=\"{end}@{start}\"");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.AppendLine($"#EXT-X-MAP:URI=\"{initUrl}\"");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
sb.AppendLine("#EXT-X-KEY:METHOD=PLZ-KEEP-RAW,URI=\"None\""); //使下载器使用二进制合并
|
sb.AppendLine("#EXT-X-KEY:METHOD=PLZ-KEEP-RAW,URI=\"None\""); //使下载器使用二进制合并
|
||||||
|
|
||||||
@@ -625,7 +673,19 @@ namespace N_m3u8DL_CLI
|
|||||||
var dur = seg.ContainsKey("duration") ? seg["duration"] : 0.0;
|
var dur = seg.ContainsKey("duration") ? seg["duration"] : 0.0;
|
||||||
var url = seg.ContainsKey("url") ? seg["url"] : seg["path"];
|
var url = seg.ContainsKey("url") ? seg["url"] : seg["path"];
|
||||||
sb.AppendLine($"#EXTINF:{dur.ToString("0.00")}");
|
sb.AppendLine($"#EXTINF:{dur.ToString("0.00")}");
|
||||||
sb.AppendLine(url);
|
if (Regex.IsMatch(url, "\\$\\$Range=(\\d+)-(\\d+)"))
|
||||||
|
{
|
||||||
|
var match = Regex.Match(url, "\\$\\$Range=(\\d+)-(\\d+)");
|
||||||
|
string rangeStr = match.Value;
|
||||||
|
long start = Convert.ToInt64(match.Groups[1].Value);
|
||||||
|
long end = Convert.ToInt64(match.Groups[2].Value);
|
||||||
|
sb.AppendLine($"#EXT-X-BYTERANGE:{end + 1 - start}@{start}");
|
||||||
|
sb.AppendLine(url.Replace(rangeStr, ""));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
sb.AppendLine(url);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.AppendLine("#EXT-X-ENDLIST");
|
sb.AppendLine("#EXT-X-ENDLIST");
|
||||||
@@ -637,17 +697,19 @@ namespace N_m3u8DL_CLI
|
|||||||
{
|
{
|
||||||
var best = new Dictionary<string, dynamic>() { ["Tbr"] = 0 };
|
var best = new Dictionary<string, dynamic>() { ["Tbr"] = 0 };
|
||||||
var bandwidth = best["Tbr"];
|
var bandwidth = best["Tbr"];
|
||||||
|
var width = 0;
|
||||||
|
|
||||||
foreach (var f in fs)
|
foreach (var f in fs)
|
||||||
{
|
{
|
||||||
var w = f["Width"];
|
var w = f["Width"];
|
||||||
var h = f["Height"];
|
var h = f["Height"];
|
||||||
if (w != -1 && h != -1)
|
if (f["ContentType"] == "video")
|
||||||
{
|
{
|
||||||
if (f["Tbr"] > bandwidth)
|
if (f["Tbr"] > bandwidth && w > width)
|
||||||
{
|
{
|
||||||
best = f;
|
best = f;
|
||||||
bandwidth = f["Tbr"];
|
bandwidth = f["Tbr"];
|
||||||
|
width = w;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -662,9 +724,7 @@ namespace N_m3u8DL_CLI
|
|||||||
|
|
||||||
foreach (var f in fs)
|
foreach (var f in fs)
|
||||||
{
|
{
|
||||||
var w = f["Width"];
|
if (f["ContentType"] == "audio")
|
||||||
var h = f["Height"];
|
|
||||||
if (w == -1 && h == -1)
|
|
||||||
{
|
{
|
||||||
if (f["Tbr"] > bandwidth)
|
if (f["Tbr"] > bandwidth)
|
||||||
{
|
{
|
||||||
@@ -709,6 +769,10 @@ namespace N_m3u8DL_CLI
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
static string CombineURL(string baseurl, string url)
|
static string CombineURL(string baseurl, string url)
|
||||||
{
|
{
|
||||||
|
if (url.StartsWith("$$Range"))
|
||||||
|
{
|
||||||
|
return baseurl + url;
|
||||||
|
}
|
||||||
Uri uri1 = new Uri(baseurl);
|
Uri uri1 = new Uri(baseurl);
|
||||||
Uri uri2 = new Uri(uri1, url);
|
Uri uri2 = new Uri(uri1, url);
|
||||||
url = uri2.ToString();
|
url = uri2.ToString();
|
||||||
|
@@ -70,6 +70,7 @@
|
|||||||
<Compile Include="CommandLineArgumentParser.cs" />
|
<Compile Include="CommandLineArgumentParser.cs" />
|
||||||
<Compile Include="Decode51CtoKey.cs" />
|
<Compile Include="Decode51CtoKey.cs" />
|
||||||
<Compile Include="DecodeDdyun.cs" />
|
<Compile Include="DecodeDdyun.cs" />
|
||||||
|
<Compile Include="DecodeHuke88Key.cs" />
|
||||||
<Compile Include="DecodeImooc.cs" />
|
<Compile Include="DecodeImooc.cs" />
|
||||||
<Compile Include="DecodeNfmovies.cs" />
|
<Compile Include="DecodeNfmovies.cs" />
|
||||||
<Compile Include="Decrypter.cs" />
|
<Compile Include="Decrypter.cs" />
|
||||||
|
@@ -748,6 +748,22 @@ namespace N_m3u8DL_CLI
|
|||||||
{
|
{
|
||||||
key[1] = DecodeImooc.DecodeKey(Global.GetWebSource(key[1], Headers));
|
key[1] = DecodeImooc.DecodeKey(Global.GetWebSource(key[1], Headers));
|
||||||
}
|
}
|
||||||
|
else if (key[1] == "https://hls.ventunotech.com/m3u8/pc_videosecurevtnkey.key")
|
||||||
|
{
|
||||||
|
string temp = Global.GetWebSource(keyUrl, Headers);
|
||||||
|
LOGGER.PrintLine(temp);
|
||||||
|
byte[] tempKey = new byte[16];
|
||||||
|
for (int d = 0; d < 16; d++)
|
||||||
|
{
|
||||||
|
tempKey[d] = Convert.ToByte(temp.Substring(2 * d, 2), 16);
|
||||||
|
}
|
||||||
|
key[1] = Convert.ToBase64String(tempKey);
|
||||||
|
}
|
||||||
|
else if (key[1].Contains("drm.vod2.myqcloud.com/getlicense"))
|
||||||
|
{
|
||||||
|
var temp = Global.HttpDownloadFileToBytes(keyUrl, Headers);
|
||||||
|
key[1] = DecodeHuke88Key.DecodeKey(key[1], temp);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (keyUrl.Contains("https://keydeliver.linetv.tw/jurassicPark")) //linetv
|
if (keyUrl.Contains("https://keydeliver.linetv.tw/jurassicPark")) //linetv
|
||||||
|
@@ -301,4 +301,11 @@
|
|||||||
2020年12月2日
|
2020年12月2日
|
||||||
- FIX Language Bug
|
- FIX Language Bug
|
||||||
2020年12月6日
|
2020年12月6日
|
||||||
- 使用手机UA请求气球云密钥服务器
|
- 使用手机UA请求气球云密钥服务器
|
||||||
|
2020年12月12日
|
||||||
|
- 修复MPD下同一个ID分散在不同Period导致下载不完全问题
|
||||||
|
2020年12月20日
|
||||||
|
- 支持解密虎课网
|
||||||
|
2021年1月18日
|
||||||
|
- 完善MPD下载相关
|
||||||
|
- 重新打包多语言资源
|
Reference in New Issue
Block a user