修复多DRM文件KID读取异常问题 (#422)
* [Fix] fix reading the kid in a multi-DRM file * [Fix] fix decrypting multi-drm files * [Fix] fix glibc error in building * [Feat] 删除ReadInit方法 * [Fix] 修复ReadMe和more-help中显示参数不准确的问题
This commit is contained in:
parent
00bce19aea
commit
508f39b649
|
@ -20,6 +20,7 @@ on:
|
||||||
|
|
||||||
env:
|
env:
|
||||||
DOTNET_SDK_VERSION: "8.0.*"
|
DOTNET_SDK_VERSION: "8.0.*"
|
||||||
|
ACTIONS_ALLOW_USE_UNSECURE_NODE_VERSION: true
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build-win-x64-arm64:
|
build-win-x64-arm64:
|
||||||
|
|
|
@ -141,7 +141,7 @@ More Help:
|
||||||
|
|
||||||
通过正则表达式选择符合要求的视频流. 你能够以:分隔形式指定如下参数:
|
通过正则表达式选择符合要求的视频流. 你能够以:分隔形式指定如下参数:
|
||||||
|
|
||||||
id=REGEX:lang=REGEX:name=REGEX:codec=REGEX:res=REGEX:frame=REGEX
|
id=REGEX:lang=REGEX:name=REGEX:codecs=REGEX:res=REGEX:frame=REGEX
|
||||||
segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX
|
segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX
|
||||||
plistDurMin=hms:plistDurMax=hms:for=FOR
|
plistDurMin=hms:plistDurMax=hms:for=FOR
|
||||||
|
|
||||||
|
@ -151,7 +151,7 @@ plistDurMin=hms:plistDurMax=hms:for=FOR
|
||||||
# 选择最佳视频
|
# 选择最佳视频
|
||||||
-sv best
|
-sv best
|
||||||
# 选择4K+HEVC视频
|
# 选择4K+HEVC视频
|
||||||
-sv res="3840*":codec=hvc1:for=best
|
-sv res="3840*":codecs=hvc1:for=best
|
||||||
# 选择长度大于1小时20分钟30秒的视频
|
# 选择长度大于1小时20分钟30秒的视频
|
||||||
-sv plistDurMin="1h20m30s":for=best
|
-sv plistDurMin="1h20m30s":for=best
|
||||||
```
|
```
|
||||||
|
|
|
@ -475,7 +475,7 @@ namespace N_m3u8DL_RE.Common.Resource
|
||||||
["cmd_selectVideo_more"] = new TextContainer
|
["cmd_selectVideo_more"] = new TextContainer
|
||||||
(
|
(
|
||||||
zhCN: "通过正则表达式选择符合要求的视频流. 你能够以:分隔形式指定如下参数:\r\n\r\n" +
|
zhCN: "通过正则表达式选择符合要求的视频流. 你能够以:分隔形式指定如下参数:\r\n\r\n" +
|
||||||
"id=REGEX:lang=REGEX:name=REGEX:codec=REGEX:res=REGEX:frame=REGEX\r\n" +
|
"id=REGEX:lang=REGEX:name=REGEX:codecs=REGEX:res=REGEX:frame=REGEX\r\n" +
|
||||||
"segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX\r\n" +
|
"segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX\r\n" +
|
||||||
"plistDurMin=hms:plistDurMax=hms:role=string:for=FOR\r\n\r\n" +
|
"plistDurMin=hms:plistDurMax=hms:role=string:for=FOR\r\n\r\n" +
|
||||||
"* for=FOR: 选择方式. best[number], worst[number], all (默认: best)\r\n\r\n" +
|
"* for=FOR: 选择方式. best[number], worst[number], all (默认: best)\r\n\r\n" +
|
||||||
|
@ -483,12 +483,12 @@ namespace N_m3u8DL_RE.Common.Resource
|
||||||
"# 选择最佳视频\r\n" +
|
"# 选择最佳视频\r\n" +
|
||||||
"-sv best\r\n" +
|
"-sv best\r\n" +
|
||||||
"# 选择4K+HEVC视频\r\n" +
|
"# 选择4K+HEVC视频\r\n" +
|
||||||
"-sv res=\"3840*\":codec=hvc1:for=best\r\n" +
|
"-sv res=\"3840*\":codecs=hvc1:for=best\r\n" +
|
||||||
"# 选择长度大于1小时20分钟30秒的视频\r\n" +
|
"# 选择长度大于1小时20分钟30秒的视频\r\n" +
|
||||||
"-sv plistDurMin=\"1h20m30s\":for=best\r\n" +
|
"-sv plistDurMin=\"1h20m30s\":for=best\r\n" +
|
||||||
"-sv role=\"main\":for:best\r\n",
|
"-sv role=\"main\":for:best\r\n",
|
||||||
zhTW: "通過正則表達式選擇符合要求的影片軌. 你能夠以:分隔形式指定如下參數:\r\n\r\n" +
|
zhTW: "通過正則表達式選擇符合要求的影片軌. 你能夠以:分隔形式指定如下參數:\r\n\r\n" +
|
||||||
"id=REGEX:lang=REGEX:name=REGEX:codec=REGEX:res=REGEX:frame=REGEX\r\n" +
|
"id=REGEX:lang=REGEX:name=REGEX:codecs=REGEX:res=REGEX:frame=REGEX\r\n" +
|
||||||
"segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX\r\n" +
|
"segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX\r\n" +
|
||||||
"plistDurMin=hms:plistDurMax=hms:role=string:for=FOR\r\n\r\n" +
|
"plistDurMin=hms:plistDurMax=hms:role=string:for=FOR\r\n\r\n" +
|
||||||
"* for=FOR: 選擇方式. best[number], worst[number], all (默認: best)\r\n\r\n" +
|
"* for=FOR: 選擇方式. best[number], worst[number], all (默認: best)\r\n\r\n" +
|
||||||
|
@ -496,12 +496,12 @@ namespace N_m3u8DL_RE.Common.Resource
|
||||||
"# 選擇最佳影片\r\n" +
|
"# 選擇最佳影片\r\n" +
|
||||||
"-sv best\r\n" +
|
"-sv best\r\n" +
|
||||||
"# 選擇4K+HEVC影片\r\n" +
|
"# 選擇4K+HEVC影片\r\n" +
|
||||||
"-sv res=\"3840*\":codec=hvc1:for=best\r\n" +
|
"-sv res=\"3840*\":codecs=hvc1:for=best\r\n" +
|
||||||
"# 選擇長度大於1小時20分鐘30秒的影片\r\n" +
|
"# 選擇長度大於1小時20分鐘30秒的影片\r\n" +
|
||||||
"-sv plistDurMin=\"1h20m30s\":for=best\r\n" +
|
"-sv plistDurMin=\"1h20m30s\":for=best\r\n" +
|
||||||
"-sv role=\"main\":for:best\r\n",
|
"-sv role=\"main\":for:best\r\n",
|
||||||
enUS: "Select video streams by regular expressions. OPTIONS is a colon separated list of:\r\n\r\n" +
|
enUS: "Select video streams by regular expressions. OPTIONS is a colon separated list of:\r\n\r\n" +
|
||||||
"id=REGEX:lang=REGEX:name=REGEX:codec=REGEX:res=REGEX:frame=REGEX\r\n" +
|
"id=REGEX:lang=REGEX:name=REGEX:codecs=REGEX:res=REGEX:frame=REGEX\r\n" +
|
||||||
"segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX\r\n" +
|
"segsMin=number:segsMax=number:ch=REGEX:range=REGEX:url=REGEX\r\n" +
|
||||||
"plistDurMin=hms:plistDurMax=hms:role=string:for=FOR\r\n\r\n" +
|
"plistDurMin=hms:plistDurMax=hms:role=string:for=FOR\r\n\r\n" +
|
||||||
"* for=FOR: Select type. best[number], worst[number], all (Default: best)\r\n\r\n" +
|
"* for=FOR: Select type. best[number], worst[number], all (Default: best)\r\n\r\n" +
|
||||||
|
@ -509,7 +509,7 @@ namespace N_m3u8DL_RE.Common.Resource
|
||||||
"# select best video\r\n" +
|
"# select best video\r\n" +
|
||||||
"-sv best\r\n" +
|
"-sv best\r\n" +
|
||||||
"# select 4K+HEVC video\r\n" +
|
"# select 4K+HEVC video\r\n" +
|
||||||
"-sv res=\"3840*\":codec=hvc1:for=best\r\n" +
|
"-sv res=\"3840*\":codecs=hvc1:for=best\r\n" +
|
||||||
"# Select best video with duration longer than 1 hour 20 minutes 30 seconds\r\n" +
|
"# Select best video with duration longer than 1 hour 20 minutes 30 seconds\r\n" +
|
||||||
"-sv plistDurMin=\"1h20m30s\":for=best\r\n" +
|
"-sv plistDurMin=\"1h20m30s\":for=best\r\n" +
|
||||||
"-sv role=\"main\":for:best\r\n"
|
"-sv role=\"main\":for:best\r\n"
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace Mp4SubtitleParser
|
||||||
public string? PSSH;
|
public string? PSSH;
|
||||||
public string? KID;
|
public string? KID;
|
||||||
public string? Scheme;
|
public string? Scheme;
|
||||||
|
public bool isMultiDRM;
|
||||||
}
|
}
|
||||||
|
|
||||||
public class MP4InitUtil
|
public class MP4InitUtil
|
||||||
|
@ -19,7 +20,6 @@ namespace Mp4SubtitleParser
|
||||||
{
|
{
|
||||||
var info = new ParsedMP4Info();
|
var info = new ParsedMP4Info();
|
||||||
|
|
||||||
|
|
||||||
//parse init
|
//parse init
|
||||||
new MP4Parser()
|
new MP4Parser()
|
||||||
.Box("moov", MP4Parser.Children)
|
.Box("moov", MP4Parser.Children)
|
||||||
|
@ -36,7 +36,13 @@ namespace Mp4SubtitleParser
|
||||||
if (SYSTEM_ID_WIDEVINE.SequenceEqual(systemId))
|
if (SYSTEM_ID_WIDEVINE.SequenceEqual(systemId))
|
||||||
{
|
{
|
||||||
var dataSize = box.Reader.ReadUInt32();
|
var dataSize = box.Reader.ReadUInt32();
|
||||||
info.PSSH = Convert.ToBase64String(box.Reader.ReadBytes((int)dataSize));
|
var psshData = box.Reader.ReadBytes((int)dataSize);
|
||||||
|
info.PSSH = Convert.ToBase64String(psshData);
|
||||||
|
if (info.KID == "00000000000000000000000000000000")
|
||||||
|
{
|
||||||
|
info.KID = HexUtil.BytesToHex(psshData[2..18]).ToLower();
|
||||||
|
info.isMultiDRM = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.FullBox("encv", MP4Parser.AllData(data => ReadBox(data, info)))
|
.FullBox("encv", MP4Parser.AllData(data => ReadBox(data, info)))
|
||||||
|
|
|
@ -76,7 +76,6 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async Task<bool> DownloadStreamAsync(StreamSpec streamSpec, ProgressTask task, SpeedContainer speedContainer)
|
private async Task<bool> DownloadStreamAsync(StreamSpec streamSpec, ProgressTask task, SpeedContainer speedContainer)
|
||||||
{
|
{
|
||||||
speedContainer.ResetVars();
|
speedContainer.ResetVars();
|
||||||
|
@ -115,6 +114,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
var mp4InitFile = "";
|
var mp4InitFile = "";
|
||||||
var currentKID = "";
|
var currentKID = "";
|
||||||
var readInfo = false; //是否读取过
|
var readInfo = false; //是否读取过
|
||||||
|
var mp4Info = new ParsedMP4Info();
|
||||||
|
|
||||||
//用户自定义范围导致被跳过的时长 计算字幕偏移使用
|
//用户自定义范围导致被跳过的时长 计算字幕偏移使用
|
||||||
var skippedDur = streamSpec.SkippedDuration ?? 0d;
|
var skippedDur = streamSpec.SkippedDuration ?? 0d;
|
||||||
|
@ -167,7 +167,8 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
//读取mp4信息
|
//读取mp4信息
|
||||||
if (result != null && result.Success)
|
if (result != null && result.Success)
|
||||||
{
|
{
|
||||||
currentKID = MP4DecryptUtil.ReadInit(result.ActualFilePath);
|
mp4Info = MP4DecryptUtil.GetMP4Info(result.ActualFilePath);
|
||||||
|
currentKID = mp4Info.KID;
|
||||||
// try shaka packager, which can handle WebM
|
// try shaka packager, which can handle WebM
|
||||||
if (string.IsNullOrEmpty(currentKID) && DownloaderConfig.MyOptions.UseShakaPackager) {
|
if (string.IsNullOrEmpty(currentKID) && DownloaderConfig.MyOptions.UseShakaPackager) {
|
||||||
currentKID = MP4DecryptUtil.ReadInitShaka(result.ActualFilePath, mp4decrypt);
|
currentKID = MP4DecryptUtil.ReadInitShaka(result.ActualFilePath, mp4decrypt);
|
||||||
|
@ -179,7 +180,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
{
|
{
|
||||||
var enc = result.ActualFilePath;
|
var enc = result.ActualFilePath;
|
||||||
var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec" + Path.GetExtension(enc));
|
var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec" + Path.GetExtension(enc));
|
||||||
var dResult = await MP4DecryptUtil.DecryptAsync(DownloaderConfig.MyOptions.UseShakaPackager, mp4decrypt, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID);
|
var dResult = await MP4DecryptUtil.DecryptAsync(DownloaderConfig.MyOptions.UseShakaPackager, mp4decrypt, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID, isMultiDRM: mp4Info.isMultiDRM);
|
||||||
if (dResult)
|
if (dResult)
|
||||||
{
|
{
|
||||||
FileDic[streamSpec.Playlist.MediaInit]!.ActualFilePath = dec;
|
FileDic[streamSpec.Playlist.MediaInit]!.ActualFilePath = dec;
|
||||||
|
@ -238,7 +239,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
//读取init信息
|
//读取init信息
|
||||||
if (string.IsNullOrEmpty(currentKID))
|
if (string.IsNullOrEmpty(currentKID))
|
||||||
{
|
{
|
||||||
currentKID = MP4DecryptUtil.ReadInit(result.ActualFilePath);
|
currentKID = MP4DecryptUtil.GetMP4Info(result.ActualFilePath).KID;
|
||||||
}
|
}
|
||||||
// try shaka packager, which can handle WebM
|
// try shaka packager, which can handle WebM
|
||||||
if (string.IsNullOrEmpty(currentKID) && DownloaderConfig.MyOptions.UseShakaPackager) {
|
if (string.IsNullOrEmpty(currentKID) && DownloaderConfig.MyOptions.UseShakaPackager) {
|
||||||
|
@ -251,7 +252,8 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
{
|
{
|
||||||
var enc = result.ActualFilePath;
|
var enc = result.ActualFilePath;
|
||||||
var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec" + Path.GetExtension(enc));
|
var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec" + Path.GetExtension(enc));
|
||||||
var dResult = await MP4DecryptUtil.DecryptAsync(DownloaderConfig.MyOptions.UseShakaPackager, mp4decrypt, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID, mp4InitFile);
|
mp4Info = MP4DecryptUtil.GetMP4Info(enc);
|
||||||
|
var dResult = await MP4DecryptUtil.DecryptAsync(DownloaderConfig.MyOptions.UseShakaPackager, mp4decrypt, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID, mp4InitFile, isMultiDRM: mp4Info.isMultiDRM);
|
||||||
if (dResult)
|
if (dResult)
|
||||||
{
|
{
|
||||||
File.Delete(enc);
|
File.Delete(enc);
|
||||||
|
@ -288,7 +290,8 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
{
|
{
|
||||||
var enc = result.ActualFilePath;
|
var enc = result.ActualFilePath;
|
||||||
var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec" + Path.GetExtension(enc));
|
var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec" + Path.GetExtension(enc));
|
||||||
var dResult = await MP4DecryptUtil.DecryptAsync(DownloaderConfig.MyOptions.UseShakaPackager, mp4decrypt, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID, mp4InitFile);
|
mp4Info = MP4DecryptUtil.GetMP4Info(enc);
|
||||||
|
var dResult = await MP4DecryptUtil.DecryptAsync(DownloaderConfig.MyOptions.UseShakaPackager, mp4decrypt, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID, mp4InitFile, isMultiDRM: mp4Info.isMultiDRM);
|
||||||
if (dResult)
|
if (dResult)
|
||||||
{
|
{
|
||||||
File.Delete(enc);
|
File.Delete(enc);
|
||||||
|
@ -584,7 +587,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
//重新读取init信息
|
//重新读取init信息
|
||||||
if (mergeSuccess && totalCount >= 1 && string.IsNullOrEmpty(currentKID) && streamSpec.Playlist!.MediaParts.First().MediaSegments.First().EncryptInfo.Method != Common.Enum.EncryptMethod.NONE)
|
if (mergeSuccess && totalCount >= 1 && string.IsNullOrEmpty(currentKID) && streamSpec.Playlist!.MediaParts.First().MediaSegments.First().EncryptInfo.Method != Common.Enum.EncryptMethod.NONE)
|
||||||
{
|
{
|
||||||
currentKID = MP4DecryptUtil.ReadInit(output);
|
currentKID = MP4DecryptUtil.GetMP4Info(output).KID;
|
||||||
// try shaka packager, which can handle WebM
|
// try shaka packager, which can handle WebM
|
||||||
if (string.IsNullOrEmpty(currentKID) && DownloaderConfig.MyOptions.UseShakaPackager) {
|
if (string.IsNullOrEmpty(currentKID) && DownloaderConfig.MyOptions.UseShakaPackager) {
|
||||||
currentKID = MP4DecryptUtil.ReadInitShaka(output, mp4decrypt);
|
currentKID = MP4DecryptUtil.ReadInitShaka(output, mp4decrypt);
|
||||||
|
@ -594,12 +597,13 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
}
|
}
|
||||||
|
|
||||||
//调用mp4decrypt解密
|
//调用mp4decrypt解密
|
||||||
if (mergeSuccess && File.Exists(output) && !string.IsNullOrEmpty(currentKID) && !DownloaderConfig.MyOptions.MP4RealTimeDecryption && DownloaderConfig.MyOptions.Keys != null && DownloaderConfig.MyOptions.Keys.Length > 0)
|
if (mergeSuccess && File.Exists(output) && !string.IsNullOrEmpty(currentKID) && !DownloaderConfig.MyOptions.MP4RealTimeDecryption && DownloaderConfig.MyOptions.Keys != null && DownloaderConfig.MyOptions.Keys.Length > 0)
|
||||||
{
|
{
|
||||||
var enc = output;
|
var enc = output;
|
||||||
var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec" + Path.GetExtension(enc));
|
var dec = Path.Combine(Path.GetDirectoryName(enc)!, Path.GetFileNameWithoutExtension(enc) + "_dec" + Path.GetExtension(enc));
|
||||||
|
mp4Info = MP4DecryptUtil.GetMP4Info(enc);
|
||||||
Logger.InfoMarkUp($"[grey]Decrypting...[/]");
|
Logger.InfoMarkUp($"[grey]Decrypting...[/]");
|
||||||
var result = await MP4DecryptUtil.DecryptAsync(DownloaderConfig.MyOptions.UseShakaPackager, mp4decrypt, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID);
|
var result = await MP4DecryptUtil.DecryptAsync(DownloaderConfig.MyOptions.UseShakaPackager, mp4decrypt, DownloaderConfig.MyOptions.Keys, enc, dec, currentKID, isMultiDRM: mp4Info.isMultiDRM);
|
||||||
if (result)
|
if (result)
|
||||||
{
|
{
|
||||||
File.Delete(enc);
|
File.Delete(enc);
|
||||||
|
|
|
@ -212,7 +212,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
//读取mp4信息
|
//读取mp4信息
|
||||||
if (result != null && result.Success)
|
if (result != null && result.Success)
|
||||||
{
|
{
|
||||||
currentKID = MP4DecryptUtil.ReadInit(result.ActualFilePath);
|
currentKID = MP4DecryptUtil.GetMP4Info(result.ActualFilePath).KID;
|
||||||
//从文件读取KEY
|
//从文件读取KEY
|
||||||
await SearchKeyAsync(currentKID);
|
await SearchKeyAsync(currentKID);
|
||||||
//实时解密
|
//实时解密
|
||||||
|
@ -290,7 +290,7 @@ namespace N_m3u8DL_RE.DownloadManager
|
||||||
//读取init信息
|
//读取init信息
|
||||||
if (string.IsNullOrEmpty(currentKID))
|
if (string.IsNullOrEmpty(currentKID))
|
||||||
{
|
{
|
||||||
currentKID = MP4DecryptUtil.ReadInit(result.ActualFilePath);
|
currentKID = MP4DecryptUtil.GetMP4Info(result.ActualFilePath).KID;
|
||||||
}
|
}
|
||||||
//从文件读取KEY
|
//从文件读取KEY
|
||||||
await SearchKeyAsync(currentKID);
|
await SearchKeyAsync(currentKID);
|
||||||
|
|
|
@ -10,12 +10,18 @@ namespace N_m3u8DL_RE.Util
|
||||||
internal class MP4DecryptUtil
|
internal class MP4DecryptUtil
|
||||||
{
|
{
|
||||||
private static string ZeroKid = "00000000000000000000000000000000";
|
private static string ZeroKid = "00000000000000000000000000000000";
|
||||||
public static async Task<bool> DecryptAsync(bool shakaPackager, string bin, string[]? keys, string source, string dest, string? kid, string init = "")
|
public static async Task<bool> DecryptAsync(bool shakaPackager, string bin, string[]? keys, string source, string dest, string? kid, string init = "", bool isMultiDRM=false)
|
||||||
{
|
{
|
||||||
if (keys == null || keys.Length == 0) return false;
|
if (keys == null || keys.Length == 0) return false;
|
||||||
|
|
||||||
string? keyPair = null;
|
string? keyPair = null;
|
||||||
string? trackId = null;
|
string? trackId = null;
|
||||||
|
|
||||||
|
if (isMultiDRM)
|
||||||
|
{
|
||||||
|
trackId = "1";
|
||||||
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(kid))
|
if (!string.IsNullOrEmpty(kid))
|
||||||
{
|
{
|
||||||
var test = keys.Where(k => k.StartsWith(kid));
|
var test = keys.Where(k => k.StartsWith(kid));
|
||||||
|
@ -127,22 +133,22 @@ namespace N_m3u8DL_RE.Util
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string? ReadInit(byte[] data)
|
public static ParsedMP4Info GetMP4Info(byte[] data)
|
||||||
{
|
{
|
||||||
var info = MP4InitUtil.ReadInit(data);
|
var info = MP4InitUtil.ReadInit(data);
|
||||||
if (info.Scheme != null) Logger.WarnMarkUp($"[grey]Type: {info.Scheme}[/]");
|
if (info.Scheme != null) Logger.WarnMarkUp($"[grey]Type: {info.Scheme}[/]");
|
||||||
if (info.PSSH != null) Logger.WarnMarkUp($"[grey]PSSH(WV): {info.PSSH}[/]");
|
if (info.PSSH != null) Logger.WarnMarkUp($"[grey]PSSH(WV): {info.PSSH}[/]");
|
||||||
if (info.KID != null) Logger.WarnMarkUp($"[grey]KID: {info.KID}[/]");
|
if (info.KID != null) Logger.WarnMarkUp($"[grey]KID: {info.KID}[/]");
|
||||||
return info.KID;
|
return info;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string? ReadInit(string output)
|
public static ParsedMP4Info GetMP4Info(string output)
|
||||||
{
|
{
|
||||||
using (var fs = File.OpenRead(output))
|
using (var fs = File.OpenRead(output))
|
||||||
{
|
{
|
||||||
var header = new byte[1 * 1024 * 1024]; //1MB
|
var header = new byte[1 * 1024 * 1024]; //1MB
|
||||||
fs.Read(header);
|
fs.Read(header);
|
||||||
return ReadInit(header);
|
return GetMP4Info(header);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue