1
mirror of https://github.com/nilaoda/N_m3u8DL-CLI synced 2025-09-07 02:45:59 +02:00

Compare commits

...

80 Commits
2.6.3 ... 2.9.2

Author SHA1 Message Date
nilaoda
4a4bfae5ab 优化MPD下载行为 2021-01-18 02:00:19 +08:00
nilaoda
d586dddfcd Update changelog.txt 2021-01-18 01:59:31 +08:00
nilaoda
fca6b3ff6c Update changelog.txt 2020-12-29 23:19:39 +08:00
nilaoda
5d75626a36 Update Global.cs 2020-12-29 23:18:16 +08:00
nilaoda
a94271c244 mpd - xigua 2020-12-20 18:53:40 +08:00
nilaoda
c51118dce7 解密huke88 2020-12-20 18:53:02 +08:00
nilaoda
81b2e87bf7 处理同一ID分散在不同Period的情况 2020-12-12 02:07:41 +08:00
nilaoda
71a9878aaa Update changelog.txt 2020-12-06 21:32:48 +08:00
nilaoda
769fe4e926 Update Global.cs 2020-12-06 21:32:38 +08:00
nilaoda
1f57ba7c09 Update Parser.cs 2020-12-06 21:32:29 +08:00
nilaoda
71282bda30 Update N_m3u8DL-CLI.csproj 2020-12-02 20:35:44 +08:00
nilaoda
41ee8aebdf update project 2020-12-02 20:31:44 +08:00
nilaoda
a4537bc093 del xml 2020-12-02 20:23:50 +08:00
nilaoda
b8a60b3917 Update packages.config 2020-12-02 20:23:36 +08:00
nilaoda
8091dd290f Update N_m3u8DL-CLI.csproj 2020-12-02 20:15:29 +08:00
nilaoda
d48e84e611 Update FodyWeavers.xml 2020-12-02 20:10:29 +08:00
nilaoda
9f5423a437 Costura.Fody 2020-12-02 19:56:20 +08:00
nilaoda
ce7e38770a Update N_m3u8DL-CLI.csproj 2020-12-02 19:51:29 +08:00
nilaoda
8fdb2e918e Update packages.config 2020-12-02 19:49:10 +08:00
nilaoda
d4b7d240c1 修正多语言识别问题 2020-12-02 11:56:46 +08:00
nilaoda
484d2941ed Update Global.cs 2020-12-02 11:56:17 +08:00
nilaoda
a0f2b66575 Update changelog.txt 2020-12-02 11:56:04 +08:00
nilaoda
65cc0681e2 Update changelog.txt 2020-11-26 21:02:04 +08:00
nilaoda
7d980ec9a2 Update Global.cs 2020-11-26 21:01:57 +08:00
nilaoda
ec5892c05a 修复可能存在的溢出问题 2020-11-26 21:01:48 +08:00
nilaoda
9aed50fbf9 优化MPD识别 2020-11-26 21:01:03 +08:00
nilaoda
d657b455cd BUG FIX 2020-11-25 21:16:41 +08:00
nilaoda
cda6575605 BUG FIX 2020-11-25 21:16:18 +08:00
nilaoda
0d6377d41b Update changelog.txt 2020-11-25 17:34:53 +08:00
nilaoda
9c76bdcbce 支持选择音轨 2020-11-25 17:34:12 +08:00
nilaoda
83915ff606 Update Global.cs 2020-11-25 14:12:46 +08:00
nilaoda
9cd4746f33 Update changelog.txt 2020-11-25 14:11:31 +08:00
nilaoda
33a5b917ac 修正MPD判断最高清晰度的逻辑 2020-11-25 14:08:40 +08:00
nilaoda
f69978bd82 修改芒果TV请求头 2020-11-23 21:53:41 +08:00
nilaoda
d9fd526886 Update changelog.txt 2020-11-23 21:53:26 +08:00
nilaoda
1cc8ecfaaf Update Global.cs 2020-11-23 21:30:12 +08:00
nilaoda
2bc2dde2ad 修改默认UA 2020-11-23 21:29:48 +08:00
nilaoda
c3ddcf9e0e Update Program.cs 2020-11-23 21:29:31 +08:00
nilaoda
ba5d20dd02 Update Parser.cs 2020-11-23 21:29:03 +08:00
nilaoda
16f705fe66 Update Global.cs 2020-11-22 23:13:59 +08:00
nilaoda
d141cabc4a Update changelog.txt 2020-11-22 23:08:51 +08:00
nilaoda
adcf884a93 新的任务监控逻辑 2020-11-22 23:08:33 +08:00
nilaoda
9d903a025f Update DownloadManager.cs 2020-11-22 22:36:21 +08:00
nilaoda
0bd23ab641 更新版本号 2020-11-22 18:48:54 +08:00
nilaoda
a38f27ccd7 手动处理重定向
解决HTTPS协议自动重定向后,Referer丢失问题
2020-11-22 18:29:40 +08:00
nilaoda
3acec5efd3 Update Global.cs 2020-11-22 15:40:47 +08:00
nilaoda
90874e4bfe Update Parser.cs 2020-11-22 14:30:41 +08:00
nilaoda
b94768e3e8 修复自定义MPD的BaseURL 2020-11-22 00:40:17 +08:00
nilaoda
311f3b882e 更新版本号 2020-11-21 19:36:04 +08:00
nilaoda
4b4f537984 BUG FIX 2020-11-21 19:34:47 +08:00
nilaoda
8032d50b42 传递MPD_URL时处理302 2020-11-21 19:34:27 +08:00
nilaoda
f615764e55 Update build_latest.yml 2020-11-21 13:48:20 +08:00
nilaoda
ccaa200ef8 Update build_latest.yml 2020-11-21 13:45:56 +08:00
nilaoda
6058d878eb Update N_m3u8DL-CLI.csproj 2020-11-21 13:40:15 +08:00
nilaoda
c712c6dee0 Create changelog.txt 2020-11-21 13:30:56 +08:00
nilaoda
bb24bb998f Update Global.cs 2020-11-21 13:11:15 +08:00
nilaoda
e9d951efa5 检测GIF HEADER 2020-11-21 12:25:01 +08:00
nilaoda
6f88a805ef 修复PNG检测逻辑
多写了一个分号……
2020-11-21 12:08:28 +08:00
nilaoda
6aa6d63a8d Convert MPD to M3U8
通过将MPD转换为m3u8进行下载
2020-11-20 23:34:35 +08:00
nilaoda
147246caba Update Parser.cs 2020-11-18 16:05:18 +08:00
nilaoda
35c1ee4777 Update Parser.cs 2020-11-18 15:52:36 +08:00
nilaoda
8b32081b85 识别m3u8文件中的EXT-X-PROGRAM-DATE-TIME 2020-11-18 15:33:39 +08:00
nilaoda
c00de328d1 修改默认UA 修改音轨判断逻辑
修改UA为Mozilla/5.0 (Linux; U; Android 7.0; zh-cn; 15 Plus Build/NRD90M) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.126 MQQBrowser/9.4 Mobile Safari/537.36

修改AAC滤镜的使用逻辑

当m3u8文本大小大于50MB时应当放弃
2020-11-18 15:03:21 +08:00
nilaoda
d5193c1645 fix bug 2020-11-06 22:11:21 +08:00
nilaoda
c06fbf5820 update docs 2020-11-03 11:38:24 +08:00
nilaoda
e700edba56 Update Program.cs
修正处理文件名过长的逻辑
2020-10-14 22:18:56 +08:00
nilaoda
aad948da7c v2.7.5 2020-10-14 22:01:03 +08:00
nilaoda
14f7b20176 Merge pull request #246 from Suwmlee/master
Fix build error
2020-09-22 10:19:45 +08:00
Mathhew
a66a9a4096 Fix build error 2020-09-22 09:49:58 +08:00
nilaoda
c862f23a9c v2.7.4
支持ddyun m3u8解密
2020-09-20 13:41:49 +08:00
nilaoda
1a722e80de Delete DecryptNfmovies.cs 2020-09-20 13:41:02 +08:00
nilaoda
eff43e8ac3 Merge pull request #240 from Suwmlee/master
Add github action
2020-09-17 18:58:30 +08:00
Mathhew
7648f8f8dc Add github action 2020-09-17 10:05:35 +08:00
nilaoda
1edc1a43fe v2.7.3 2020-09-14 21:53:51 +08:00
nilaoda
01e7735018 v2.7.2 2020-08-09 20:59:38 +08:00
nilaoda
a0c41d6116 v2.7.2 2020-08-09 20:34:32 +08:00
nilaoda
c3c25774de v2.7.2 2020-08-09 20:33:15 +08:00
nilaoda
ba40641a21 v2.7.1 2020-07-19 09:24:24 +08:00
nilaoda
5d76418780 v2.7.0
优酷杜比视界下载逻辑优化;支持IMOCO m3u8/key解密;从当前路径和exe路径同时寻找ffmpeg;支持多语言本地化(简繁英)
2020-07-18 17:20:28 +08:00
nilaoda
fd48b766b5 v2.6.3 2020-04-17 22:54:57 +08:00
37 changed files with 4232 additions and 634 deletions

34
.github/workflows/build_latest.yml vendored Normal file
View File

@@ -0,0 +1,34 @@
name: Build_Latest
on: [push]
jobs:
build:
runs-on: windows-latest
steps:
- uses: actions/checkout@v1
name: Checkout Code
- name: Setup MSBuild Path
uses: warrenbuckley/Setup-MSBuild@v1
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true'
- name: Setup NuGet
uses: NuGet/setup-nuget@v1.0.2
env:
ACTIONS_ALLOW_UNSECURE_COMMANDS: 'true'
- name: Restore NuGet Packages
run: nuget restore N_m3u8DL-CLI.sln
- name: Build
run: msbuild N_m3u8DL-CLI.sln /p:Configuration=Release /p:DebugSymbols=false /p:DebugType=None
- name: Upload Artifact
uses: actions/upload-artifact@v1.0.0
with:
name: N_m3u8DL-CLI_latest
path: N_m3u8DL-CLI\bin\Release\

View File

@@ -2,6 +2,9 @@
namespace N_m3u8DL_CLI
{
/**
* https://www.cnblogs.com/linxuanchen/p/c-sharp-command-line-argument-parser.html
*/
public class CommandLineArgument
{
List<CommandLineArgument> _arguments;

View File

@@ -1,6 +1,8 @@
using NiL.JS.BaseLibrary;
using NiL.JS.Core;
using NiL.JS.Extensions;
using System.Security.Cryptography;
using System.Text;
namespace N_m3u8DL_CLI
{
@@ -285,6 +287,19 @@ function getKey(text, lid) {
return btoa(dec(text, lid));
}";
private static string MD5Encoding(string rawPass)
{
MD5 md5 = MD5.Create();
byte[] bs = Encoding.UTF8.GetBytes(rawPass);
byte[] hs = md5.ComputeHash(bs);
StringBuilder sb = new StringBuilder();
foreach (byte b in hs)
{
sb.Append(b.ToString("x2"));
}
return sb.ToString();
}
public static string GetDecodeKey(string encodeKey, string lid)
{
var context = new Context();
@@ -293,5 +308,11 @@ function getKey(text, lid) {
string key = concatFunction.Call(new Arguments { encodeKey, lid }).ToString();
return key;
}
public static string GetSign(string lid)
{
var data = lid + "eDu_51Cto_siyuanTlw";
return MD5Encoding(data);
}
}
}

View File

@@ -0,0 +1,41 @@
using System.Security.Cryptography;
using System.Text;
using System.Text.RegularExpressions;
namespace N_m3u8DL_CLI
{
class DecodeDdyun
{
public static string DecryptM3u8(byte[] byteArray)
{
string tmp = DecodeNfmovies.DecryptM3u8(byteArray);
if (tmp.StartsWith("duoduo.key"))
{
tmp = Regex.Replace(tmp, @"#EXT-X-BYTERANGE:.*\s", "");
tmp = tmp.Replace("https:", "jump/https:")
.Replace("inews.gtimg.com", "puui.qpic.cn");
}
return tmp;
}
//https://player.ddyunp.com/jQuery.min.js?v1.5
public static string GetVaildM3u8Url(string url)
{
//url: https://hls.ddyunp.com/ddyun/id/1/key/playlist.m3u8
string id = Regex.Match(url, @"\w{20,}").Value;
string tm = Global.GetTimeStamp(false);
string t = ((long.Parse(tm) / 0x186a0) * 0x64).ToString();
string tmp = id + "duoduo" + "1" + t;
MD5 md5 = MD5.Create();
byte[] bs = Encoding.UTF8.GetBytes(tmp);
byte[] hs = md5.ComputeHash(bs);
StringBuilder sb = new StringBuilder();
foreach (byte b in hs)
{
sb.Append(b.ToString("x2"));
}
string key = sb.ToString();
return Regex.Replace(url, @"1/\w{20,}", "1/" + key);
}
}
}

View 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;
}
}
}

203
N_m3u8DL-CLI/DecodeImooc.cs Normal file
View File

@@ -0,0 +1,203 @@
using NiL.JS.BaseLibrary;
using NiL.JS.Core;
using NiL.JS.Extensions;
using System;
using Array = System.Array;
namespace N_m3u8DL_CLI
{
/*
* js代码来自https://www.imooc.com/static/moco/player/3.0.6.3/mocoplayer.js?v=202006122046
*
*/
class DecodeImooc
{
private static string JS = @"
function n(t, e) {
function r(t, e) {
var r = '';
if ('object' == typeof t)
for (var n = 0; n < t.length; n++)
r += String.fromCharCode(t[n]);
t = r || t;
for (var i, o, a = new Uint8Array(t.length), s = e.length, n = 0; n < t.length; n++)
o = n % s,
i = t[n],
i = i.toString().charCodeAt(0),
a[n] = i ^ e.charCodeAt(o);
return a
}
function n(t) {
var e = '';
if ('object' == typeof t)
for (var r = 0; r < t.length; r++)
e += String.fromCharCode(t[r]);
t = e || t;
var n = new Uint8Array(t.length);
for (r = 0; r < t.length; r++)
n[r] = t[r].toString().charCodeAt(0);
var i, o, r = 0;
for (r = 0; r < n.length; r++)
0 != (i = n[r] % 3) && r + i < n.length && (o = n[r + 1],
n[r + 1] = n[r + i],
n[r + i] = o,
r = r + i + 1);
return n
}
function i(t) {
var e = '';
if ('object' == typeof t)
for (var r = 0; r < t.length; r++)
e += String.fromCharCode(t[r]);
t = e || t;
var n = new Uint8Array(t.length);
for (r = 0; r < t.length; r++)
n[r] = t[r].toString().charCodeAt(0);
var r = 0
, i = 0
, o = 0
, a = 0;
for (r = 0; r < n.length; r++)
o = n[r] % 2,
o && r++,
a++;
var s = new Uint8Array(a);
for (r = 0; r < n.length; r++)
o = n[r] % 2,
s[i++] = o ? n[r++] : n[r];
return s
}
function o(t, e) {
var r = 0
, n = 0
, i = 0
, o = 0
, a = '';
if ('object' == typeof t)
for (var r = 0; r < t.length; r++)
a += String.fromCharCode(t[r]);
t = a || t;
var s = new Uint8Array(t.length);
for (r = 0; r < t.length; r++)
s[r] = t[r].toString().charCodeAt(0);
for (r = 0; r < t.length; r++)
if (0 != (o = s[r] % 5) && 1 != o && r + o < s.length && (i = s[r + 1],
n = r + 2,
s[r + 1] = s[r + o],
s[o + r] = i,
(r = r + o + 1) - 2 > n))
for (; n < r - 2; n++)
s[n] = s[n] ^ e.charCodeAt(n % e.length);
for (r = 0; r < t.length; r++)
s[r] = s[r] ^ e.charCodeAt(r % e.length);
return s
}
for (var a = {
data: {
info: t
}
}, s = {
q: r,
h: n,
m: i,
k: o
}, l = a.data.info, u = l.substring(l.length - 4).split(''), c = 0; c < u.length; c++)
u[c] = u[c].toString().charCodeAt(0) % 4;
u.reverse();
for (var d = [], c = 0; c < u.length; c++)
d.push(l.substring(u[c] + 1, u[c] + 2)),
l = l.substring(0, u[c] + 1) + l.substring(u[c] + 2);
a.data.encrypt_table = d,
a.data.key_table = [];
for (var c in a.data.encrypt_table)
'q' != a.data.encrypt_table[c] && 'k' != a.data.encrypt_table[c] || (a.data.key_table.push(l.substring(l.length - 12)),
l = l.substring(0, l.length - 12));
a.data.key_table.reverse(),
a.data.info = l;
var f = new Array(-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63,52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1,-1,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1,-1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1);
a.data.info = function(t) {
var e, r, n, i, o, a, s;
for (a = t.length,
o = 0,
s = ''; o < a; ) {
do {
e = f[255 & t.charCodeAt(o++)]
} while (o < a && -1 == e);if (-1 == e)
break;
do {
r = f[255 & t.charCodeAt(o++)]
} while (o < a && -1 == r);if (-1 == r)
break;
s += String.fromCharCode(e << 2 | (48 & r) >> 4);
do {
if (61 == (n = 255 & t.charCodeAt(o++)))
return s;
n = f[n]
} while (o < a && -1 == n);if (-1 == n)
break;
s += String.fromCharCode((15 & r) << 4 | (60 & n) >> 2);
do {
if (61 == (i = 255 & t.charCodeAt(o++)))
return s;
i = f[i]
} while (o < a && -1 == i);if (-1 == i)
break;
s += String.fromCharCode((3 & n) << 6 | i)
}
return s
}(a.data.info);
for (var c in a.data.encrypt_table) {
var h = a.data.encrypt_table[c];
if ('q' == h || 'k' == h) {
var p = a.data.key_table.pop();
a.data.info = s[a.data.encrypt_table[c]](a.data.info, p)
} else
a.data.info = s[a.data.encrypt_table[c]](a.data.info)
}
if (e)
return a.data.info;
var g = '';
for (c = 0; c < a.data.info.length; c++)
g += String.fromCharCode(a.data.info[c]);
return g
}
function Uint8ArrayToString(fileData){
var dataString = '';
for (var i = 0; i < fileData.length; i++) {
dataString += Number(fileData[i]) + ',';
}
return dataString;
}
function decodeKey(resp){
var string = eval('('+resp+')');
//return btoa(String.fromCharCode.apply(null, new Uint8Array(n(string.data.info, 1))));
return Uint8ArrayToString(new Uint8Array(n(string.data.info, 1)));
}
function decodeM3u8(resp){
var string = eval('('+resp+')');
return n(string.data.info);
}
";
public static string DecodeM3u8(string resp)
{
var context = new Context();
context.Eval(JS);
var concatFunction = context.GetVariable("decodeM3u8").As<Function>();
string m3u8 = concatFunction.Call(new Arguments { resp }).ToString();
return m3u8;
}
public static string DecodeKey(string resp)
{
var context = new Context();
context.Eval(JS);
var concatFunction = context.GetVariable("decodeKey").As<Function>();
string key = concatFunction.Call(new Arguments { resp }).ToString();
byte[] v = Array.ConvertAll(key.Trim(',').Split(','), s => (byte)int.Parse(s));
string realKey = Convert.ToBase64String(v);
return realKey;
}
}
}

View File

@@ -0,0 +1,36 @@
using System;
using System.IO;
using System.Linq;
using System.Text;
namespace N_m3u8DL_CLI
{
class DecodeNfmovies
{
//https://jx.nfmovies.com/hls.min.js
public static string DecryptM3u8(byte[] byteArray)
{
var t = byteArray;
var decrypt = "";
if (137 == t[0] && 80 == t[1] && 130 == t[354] && 96 == t[353]) t = t.Skip(355).ToArray();
else
{
if (137 != t[0] || 80 != t[1] || 130 != t[394] || 96 != t[393])
{
for (var i = 0; i < t.Length; i++) decrypt += Convert.ToChar(t[i]);
return decrypt;
}
t = t.Skip(395).ToArray();
}
using (var zipStream =
new System.IO.Compression.GZipStream(new MemoryStream(t), System.IO.Compression.CompressionMode.Decompress))
{
using (StreamReader sr = new StreamReader(zipStream, Encoding.UTF8))
{
decrypt = sr.ReadToEnd();
}
}
return decrypt;
}
}
}

View File

@@ -1,16 +1,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace N_m3u8DL_CLI
{
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);
//获取文件大小
@@ -19,30 +15,30 @@ namespace N_m3u8DL_CLI
fs.Read(inBuff, 0, inBuff.Length);
fs.Close();
Aes dcpt = Aes.Create("AES");
Aes dcpt = Aes.Create();
dcpt.BlockSize = 128;
dcpt.KeySize = 128;
dcpt.Key = keyByte;
dcpt.IV = ivByte;
dcpt.Mode = mode;
dcpt.Padding = PaddingMode.PKCS7;
dcpt.Padding = padding;
ICryptoTransform cTransform = dcpt.CreateDecryptor();
Byte[] resultArray = cTransform.TransformFinalBlock(inBuff, 0, inBuff.Length);
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;
Aes dcpt = Aes.Create("AES");
Aes dcpt = Aes.Create();
dcpt.BlockSize = 128;
dcpt.KeySize = 128;
dcpt.Key = keyByte;
dcpt.IV = ivByte;
dcpt.Mode = mode;
dcpt.Padding = PaddingMode.PKCS7;
dcpt.Padding = padding;
ICryptoTransform cTransform = dcpt.CreateDecryptor();
Byte[] resultArray = cTransform.TransformFinalBlock(inBuff, 0, inBuff.Length);
@@ -56,7 +52,7 @@ namespace N_m3u8DL_CLI
return new byte[0];
}
if (hexStr.StartsWith("0x") || hexStr.StartsWith("0X"))
if (hexStr.StartsWith("0x") || hexStr.StartsWith("0X"))
{
hexStr = hexStr.Remove(0, 2);
}

File diff suppressed because it is too large Load Diff

View File

@@ -118,8 +118,8 @@ namespace N_m3u8DL_CLI
HLSLiveDownloader.REC_DUR += SegDur;
if (HLSLiveDownloader.REC_DUR_LIMIT != -1 && HLSLiveDownloader.REC_DUR >= HLSLiveDownloader.REC_DUR_LIMIT)
{
LOGGER.PrintLine("录制已到达限定长度", LOGGER.Warning);
LOGGER.WriteLine("录制已到达限定长度");
LOGGER.PrintLine(strings.recordLimitReached, LOGGER.Warning);
LOGGER.WriteLine(strings.recordLimitReached);
Environment.Exit(0); //正常退出
}
return;
@@ -226,8 +226,8 @@ namespace N_m3u8DL_CLI
}
else
{
LOGGER.WriteLineError("Something was wrong!");
LOGGER.PrintLine("遇到了某些错误!", LOGGER.Error);
LOGGER.WriteLineError(strings.SomethingWasWrong);
LOGGER.PrintLine(strings.SomethingWasWrong, LOGGER.Error);
return;
}
return;

View File

@@ -10,19 +10,20 @@ namespace N_m3u8DL_CLI
{
class FFmpeg
{
private static string outPutPath = string.Empty;
private static string reportFile = string.Empty;
private static bool useAACFilter = false; //是否启用滤镜
private static bool writeDate = true; //是否写入录制日期
public static string OutPutPath { get => outPutPath; set => outPutPath = value; }
public static string ReportFile { get => reportFile; set => reportFile = value; }
public static bool UseAACFilter { get => useAACFilter; set => useAACFilter = value; }
public static bool WriteDate { get => writeDate; set => writeDate = value; }
public static string FFMPEG_PATH = "ffmpeg";
public static string REC_TIME = ""; //录制日期
public static string OutPutPath { get; set; } = string.Empty;
public static string ReportFile { get; set; } = string.Empty;
public static bool UseAACFilter { get; set; } = false; //是否启用滤镜
public static bool WriteDate { get; set; } = true; //是否写入录制日期
public static void Merge(string[] files, string muxFormat, bool fastStart,
string poster = "", string audioName = "", string title = "",
string copyright = "", string comment = "", string encodingTool = "")
{
string dateString = string.IsNullOrEmpty(REC_TIME) ? DateTime.Now.ToString("o") : REC_TIME;
//同名文件已存在的共存策略
if (File.Exists($"{OutPutPath}.{muxFormat.ToLower()}"))
{
@@ -50,7 +51,7 @@ namespace N_m3u8DL_CLI
command += " " + (string.IsNullOrEmpty(ddpAudio) ? "" : "-i \"" + ddpAudio + "\"");
command +=
$" -map 0:v? {(string.IsNullOrEmpty(ddpAudio) ? "-map 0:a?" : $"-map {(string.IsNullOrEmpty(poster) ? "1" : "2")}:a -map 0:a?")} -map 0:s? " + (string.IsNullOrEmpty(poster) ? "" : addPoster)
+ (writeDate ? " -metadata date=\"" + DateTime.Now.ToString("o") + "\"" : "") +
+ (WriteDate ? " -metadata date=\"" + dateString + "\"" : "") +
" -metadata encoding_tool=\"" + encodingTool + "\" -metadata title=\"" + title +
"\" -metadata copyright=\"" + copyright + "\" -metadata comment=\"" + comment +
$"\" -metadata:s:a:{(string.IsNullOrEmpty(ddpAudio) ? "0" : "1")} handler_name=\"" + audioName + $"\" -metadata:s:a:{(string.IsNullOrEmpty(ddpAudio) ? "0" : "1")} handler=\"" + audioName + "\" ";
@@ -83,8 +84,8 @@ namespace N_m3u8DL_CLI
}
Run("ffmpeg", command, Path.GetDirectoryName(files[0]));
LOGGER.WriteLine("Result in [ffreport.log]");
Run(FFMPEG_PATH, command, Path.GetDirectoryName(files[0]));
LOGGER.WriteLine(strings.ffmpegDone);
//Console.WriteLine(command);
}
@@ -92,7 +93,7 @@ namespace N_m3u8DL_CLI
{
if (Global.VIDEO_TYPE == "H264")
{
Run("ffmpeg",
Run(FFMPEG_PATH,
"-loglevel quiet -i \"" + file + "\" -map 0 -c copy -copy_unknown -f mpegts -bsf:v h264_mp4toannexb \""
+ Path.GetFileNameWithoutExtension(file) + "[MPEGTS].ts\"",
Path.GetDirectoryName(file));
@@ -104,7 +105,7 @@ namespace N_m3u8DL_CLI
}
else if (Global.VIDEO_TYPE == "H265")
{
Run("ffmpeg",
Run(FFMPEG_PATH,
"-loglevel quiet -i \"" + file + "\" -map 0 -c copy -copy_unknown -f mpegts -bsf:v hevc_mp4toannexb \""
+ Path.GetFileNameWithoutExtension(file) + "[MPEGTS].ts\"",
Path.GetDirectoryName(file));

File diff suppressed because it is too large Load Diff

783
N_m3u8DL-CLI/MPDParser.cs Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props" Condition="Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" />
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -12,6 +13,8 @@
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
@@ -38,13 +41,16 @@
<ApplicationIcon>logo_3Iv_icon.ico</ApplicationIcon>
</PropertyGroup>
<ItemGroup>
<Reference Include="Costura, Version=4.1.0.0, Culture=neutral, PublicKeyToken=9919ef960d84173d, processorArchitecture=MSIL">
<HintPath>..\packages\Costura.Fody.4.1.0\lib\net40\Costura.dll</HintPath>
</Reference>
<Reference Include="Microsoft.JScript" />
<Reference Include="netstandard, Version=2.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51" />
<Reference Include="Newtonsoft.Json">
<HintPath>..\packages\Newtonsoft.Json.dll</HintPath>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="NiL.JS, Version=2.5.1428.0, Culture=neutral, PublicKeyToken=fa941a7c2a4de689, processorArchitecture=MSIL">
<HintPath>..\packages\NiL.JS.dll</HintPath>
<HintPath>..\packages\NiL.JS.2.5.1428\lib\net45\NiL.JS.dll</HintPath>
</Reference>
<Reference Include="PresentationFramework" />
<Reference Include="System" />
@@ -63,6 +69,10 @@
<Compile Include="CommandLineArgument.cs" />
<Compile Include="CommandLineArgumentParser.cs" />
<Compile Include="Decode51CtoKey.cs" />
<Compile Include="DecodeDdyun.cs" />
<Compile Include="DecodeHuke88Key.cs" />
<Compile Include="DecodeImooc.cs" />
<Compile Include="DecodeNfmovies.cs" />
<Compile Include="Decrypter.cs" />
<Compile Include="FFmpeg.cs" />
<Compile Include="Global.cs" />
@@ -70,10 +80,26 @@
<Compile Include="HLSTags.cs" />
<Compile Include="LOGGER.cs" />
<Compile Include="DownloadManager.cs" />
<Compile Include="MPDParser.cs" />
<Compile Include="Parser.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Downloader.cs" />
<Compile Include="strings.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>strings.resx</DependentUpon>
</Compile>
<Compile Include="strings.en-US.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>strings.en-US.resx</DependentUpon>
</Compile>
<Compile Include="strings.zh-TW.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>strings.zh-TW.resx</DependentUpon>
</Compile>
<Compile Include="Watcher.cs" />
</ItemGroup>
<ItemGroup>
@@ -82,9 +108,6 @@
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<None Include="bin\Debug\Newtonsoft.Json.dll" />
</ItemGroup>
<ItemGroup>
<COMReference Include="Scripting">
<Guid>{420B2830-E718-11CF-893D-00A0C9054228}</Guid>
@@ -99,5 +122,27 @@
<ItemGroup>
<Content Include="logo_3Iv_icon.ico" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="strings.en-US.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>strings.en-US.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="strings.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>strings.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="strings.zh-TW.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>strings.zh-TW.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
<Import Project="..\packages\Fody.6.0.0\build\Fody.targets" Condition="Exists('..\packages\Fody.6.0.0\build\Fody.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Fody.6.0.0\build\Fody.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Fody.6.0.0\build\Fody.targets'))" />
<Error Condition="!Exists('..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Costura.Fody.4.1.0\build\Costura.Fody.props'))" />
</Target>
</Project>

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -10,7 +10,7 @@ using System.Runtime.InteropServices;
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("nilaoda")]
[assembly: AssemblyProduct("N_m3u8DL-CLI")]
[assembly: AssemblyCopyright("Copyright © 2019")]
[assembly: AssemblyCopyright("Copyright © 2020")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
@@ -33,4 +33,4 @@ using System.Runtime.InteropServices;
// 方法是按如下所示使用“*”: :
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("2.7.0.0")]

311
N_m3u8DL-CLI/changelog.txt Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Fody" version="6.0.0" targetFramework="net46" developmentDependency="true" />
<package id="Costura.Fody" version="4.1.0" targetFramework="net46" />
<package id="Newtonsoft.Json" version="12.0.3" targetFramework="net46" />
<package id="NiL.JS" version="2.5.1428" targetFramework="net46" />
</packages>

541
N_m3u8DL-CLI/strings.Designer.cs generated Normal file

File diff suppressed because it is too large Load Diff

0
N_m3u8DL-CLI/strings.en-US.Designer.cs generated Normal file
View File

File diff suppressed because it is too large Load Diff

302
N_m3u8DL-CLI/strings.resx Normal file

File diff suppressed because it is too large Load Diff

0
N_m3u8DL-CLI/strings.zh-TW.Designer.cs generated Normal file
View File

File diff suppressed because it is too large Load Diff

View File

@@ -61,6 +61,7 @@ N_m3u8DL-CLI.exe <URL|JSON|FILE> [OPTIONS]
--muxSetJson File 使用外部json文件定义混流选项
--useKeyFile File 使用外部16字节文件定义AES-128解密KEY
--useKeyBase64 Base64String 使用Base64字符串定义AES-128解密KEY
--useKeyIV HEXString 使用HEX字符串定义AES-128解密IV
--downloadRange Range 仅下载视频的一部分分片或长度
--liveRecDur HH:MM:SS 直播录制时,达到此长度自动退出软件
--stopSpeed Number 当速度低于此值时,重试(单位为KB/s)

View File

@@ -43,6 +43,7 @@ N_m3u8DL-CLI.exe <URL|JSON|FILE> [OPTIONS]
--muxSetJson File Set a json file for mux
--useKeyFile File Use 16 bytes file as KEY for AES-128 decryption
--useKeyBase64 Base64String Use Base64 String as KEY for AES-128 decryption
--useKeyIV HEXString Use HEX String as IV for AES-128 decryption
--downloadRange Range Set range for a video
--stopSpeed Number Speed below this, retry(KB/s)
--maxSpeed Number Set max download speed(KB/s)

File diff suppressed because one or more lines are too long

555
docs/GetM3u8.html Normal file

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

Some files were not shown because too many files have changed in this diff Show More