Skip to content

Commit

Permalink
Merge pull request #492 from My-Responsitories/master
Browse files Browse the repository at this point in the history
make biliplus support ss/md & replace upos host
  • Loading branch information
nilaoda authored Dec 16, 2022
2 parents 50f723f + 3cb326e commit e4e9c21
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 107 deletions.
2 changes: 1 addition & 1 deletion BBDown.Core/Parser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,7 @@ private static string GetTimeStamp(bool bflag)
private static string GetSign(string parms, bool isBiliPlus)
{
string toEncode = parms + (isBiliPlus ? "acd495b248ec528c2eed1e862d393126" : "59b43e04ad6965f34319062b478f83dd");
return string.Join("", MD5.HashData(Encoding.UTF8.GetBytes(toEncode)).Select(i => i.ToString("x2")).ToArray());
return string.Concat(MD5.HashData(Encoding.UTF8.GetBytes(toEncode)).Select(i => i.ToString("x2")).ToArray());
}

[GeneratedRegex("window.__playinfo__=([\\s\\S]*?)<\\/script>")]
Expand Down
136 changes: 67 additions & 69 deletions BBDown/BBDownUtil.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Collections.Specialized;
Expand Down Expand Up @@ -53,14 +53,10 @@ public static async Task<string> GetAvIdAsync(string input)
{
avid = AvRegex().Match(input).Groups[1].Value;
}
else if (input.Contains("video/BV"))
else if (input.ToLower().Contains("video/bv"))
{
avid = await GetAidByBVAsync(BVRegex().Match(input).Groups[1].Value);
}
else if (input.Contains("video/bv"))
{
avid = await GetAidByBVAsync(BvRegex().Match(input).Groups[1].Value);
}
else if (input.Contains("/cheese/"))
{
string epId = "";
Expand All @@ -79,6 +75,11 @@ public static async Task<string> GetAvIdAsync(string input)
string epId = EpRegex().Match(input).Groups[1].Value;
avid = $"ep:{epId}";
}
else if (input.Contains("/ss"))
{
string epId = await GetEpIdByBangumiSSIdAsync(SsRegex().Match(input).Groups[1].Value);
avid = $"ep:{epId}";
}
else if (input.Contains("/medialist/") && input.Contains("business_id=") && input.Contains("business=space_collection")) //列表类型是合集
{
string bizId = GetQueryString("business_id", input);
Expand Down Expand Up @@ -135,11 +136,7 @@ public static async Task<string> GetAvIdAsync(string input)
avid = $"ep:{epId}";
}
}
else if (input.StartsWith("BV"))
{
avid = await GetAidByBVAsync(input[2..]);
}
else if (input.StartsWith("bv"))
else if (input.ToLower().StartsWith("bv"))
{
avid = await GetAidByBVAsync(input[2..]);
}
Expand All @@ -154,31 +151,14 @@ public static async Task<string> GetAvIdAsync(string input)
}
else if (input.StartsWith("ss"))
{
string web = await GetWebSourceAsync("https://www.bilibili.com/bangumi/play/" + input);
Regex regex = StateRegex();
string json = regex.Match(web).Groups[1].Value;
try
{
using var jDoc = JsonDocument.Parse(json);
string epId = jDoc.RootElement.GetProperty("epList").EnumerateArray().First().GetProperty("id").ToString();
avid = $"ep:{epId}";
}
catch (JsonException)
{
throw new Exception("输入有误");
}
string epId = await GetEpIdByBangumiSSIdAsync(input[2..]);
avid = $"ep:{epId}";
}
else if (input.StartsWith("md"))
{
string mdId = MdRegex().Match(input).Groups[1].Value;
try
{
avid = await GetAvIdAsync(await GetSSIdByMDAsync(mdId));
}
catch (JsonException)
{
throw new Exception("输入有误");
}
string epId = await GetEpIdByMDAsync(mdId);
avid = $"ep:{epId}";
}
else
{
Expand Down Expand Up @@ -209,7 +189,7 @@ public static string FormatTime(int time, bool absolute = false)
}

/// <summary>
/// 通过avid检测是否为版权内容如果是的话返回ep:xx格式
/// 通过avid检测是否为版权内容, 如果是的话返回ep:xx格式
/// </summary>
/// <param name="avid"></param>
/// <returns></returns>
Expand Down Expand Up @@ -238,11 +218,31 @@ public static async Task<string> FixAvidAsync(string avid)

public static async Task<string> GetAidByBVAsync(string bv)
{
string api = $"https://api.bilibili.com/x/web-interface/archive/stat?bvid={bv}";
string json = await GetWebSourceAsync(api);
using var jDoc = JsonDocument.Parse(json);
string aid = jDoc.RootElement.GetProperty("data").GetProperty("aid").ToString();
return aid;
if (bv.Length == 10)
{
// 能在本地就在本地
string TABLE = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF";
var BVChange = new Dictionary<char, byte>();
byte[] S = { 9, 8, 1, 6, 2, 4 };
long XOR = 177451812;
long ADD = 8728348608;
for (byte i = 0; i < 58; i++) BVChange.Add(TABLE[i], i);

long T = 0;
for (byte i = 0; i < 6; i++)
{
T += (long)Math.Pow(58, i) * BVChange[bv[S[i]]];
}
return ((T - ADD) ^ XOR).ToString();
}
else
{
string api = $"https://api.bilibili.com/x/web-interface/archive/stat?bvid={bv}";
string json = await GetWebSourceAsync(api);
using var jDoc = JsonDocument.Parse(json);
string aid = jDoc.RootElement.GetProperty("data").GetProperty("aid").ToString();
return aid;
}
}

public static async Task<string> GetEpidBySSIdAsync(string ssid)
Expand All @@ -254,13 +254,22 @@ public static async Task<string> GetEpidBySSIdAsync(string ssid)
return epId;
}

public static async Task<string> GetSSIdByMDAsync(string mdId)
public static async Task<string> GetEpIdByBangumiSSIdAsync(string ssId)
{
string api = $"https://{Core.Config.EPHOST}/pgc/view/web/season?season_id={ssId}";
string json = await GetWebSourceAsync(api);
using var jDoc = JsonDocument.Parse(json);
string epId = jDoc.RootElement.GetProperty("result").GetProperty("episodes").EnumerateArray().First().GetProperty("id").ToString();
return epId;
}

public static async Task<string> GetEpIdByMDAsync(string mdId)
{
var api = $"https://api.bilibili.com/pgc/review/user?media_id={mdId}";
var json = await GetWebSourceAsync(api);
string api = $"https://api.bilibili.com/pgc/review/user?media_id={mdId}";
string json = await GetWebSourceAsync(api);
using var jDoc = JsonDocument.Parse(json);
var ssId = "ss" + jDoc.RootElement.GetProperty("result").GetProperty("media").GetProperty("season_id").ToString();
return ssId;
string epId = jDoc.RootElement.GetProperty("result").GetProperty("media").GetProperty("new_ep").GetProperty("id").ToString();
return epId;
}

private static async Task RangeDownloadToTmpAsync(int id, string url, string tmpName, long fromPosition, long? toPosition, Action<int, long, long> onProgress, bool failOnRangeNotSupported = false)
Expand Down Expand Up @@ -402,7 +411,7 @@ await RangeDownloadToTmpAsync(clip.index, url, tmp, clip.from, clip.to == -1 ? n
}
catch (NotSupportedException)
{
if (++retry == 3) throw new Exception($"服务器可能并不支持多线程下载请使用 --multi-thread false 关闭多线程");
if (++retry == 3) throw new Exception($"服务器可能并不支持多线程下载, 请使用 --multi-thread false 关闭多线程");
goto reDown;
}
catch (Exception)
Expand Down Expand Up @@ -448,7 +457,7 @@ private static List<Clip> GetAllClips(string url, long fileSize)
}

/// <summary>
/// 输入一堆已存在的文件合并到新文件
/// 输入一堆已存在的文件, 合并到新文件
/// </summary>
/// <param name="files"></param>
/// <param name="outputFilePath"></param>
Expand Down Expand Up @@ -564,7 +573,7 @@ public static string GetValidFileName(string input, string re = ".", bool filter


/// <summary>
/// 获取url字符串参数返回参数值字符串
/// 获取url字符串参数, 返回参数值字符串
/// </summary>
/// <param name="name">参数名称</param>
/// <param name="url">url字符串</param>
Expand Down Expand Up @@ -605,22 +614,13 @@ public static string GetSession(string buvid3)
public static string GetSign(string parms)
{
string toEncode = parms + "59b43e04ad6965f34319062b478f83dd";
byte[] bs = Encoding.UTF8.GetBytes(toEncode);
byte[] hs = MD5.HashData(bs);
StringBuilder sb = new();
foreach (byte b in hs)
{
sb.Append(b.ToString("x2"));
}
return sb.ToString();
return string.Concat(MD5.HashData(Encoding.UTF8.GetBytes(toEncode)).Select(i => i.ToString("x2")).ToArray());
}

public static string GetTimeStamp(bool bflag)
{
TimeSpan ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
string ret = bflag ? Convert.ToInt64(ts.TotalSeconds).ToString() : Convert.ToInt64(ts.TotalMilliseconds).ToString();

return ret;
DateTimeOffset ts = DateTimeOffset.Now;
return bflag ? ts.ToUnixTimeSeconds().ToString() : ts.ToUnixTimeMilliseconds().ToString();
}

//https://stackoverflow.com/questions/1344221/how-can-i-generate-random-alphanumeric-strings
Expand Down Expand Up @@ -750,7 +750,7 @@ public static async Task<List<ViewPoint>> FetchPointsAsync(string cid, string ai
}

/// <summary>
/// 生成metadata文件用于ffmpeg混流章节信息
/// 生成metadata文件, 用于ffmpeg混流章节信息
/// </summary>
/// <param name="points"></param>
/// <returns></returns>
Expand All @@ -772,7 +772,7 @@ public static string GetFFmpegMetaString(List<ViewPoint> points)
}

/// <summary>
/// 生成metadata文件用于mp4box混流章节信息
/// 生成metadata文件, 用于mp4box混流章节信息
/// </summary>
/// <param name="points"></param>
/// <returns></returns>
Expand Down Expand Up @@ -810,27 +810,25 @@ public static async Task<bool> CheckLogin(string cookie)
}
}

[GeneratedRegex("av(\\d{1,})")]
[GeneratedRegex("av(\\d+)")]
private static partial Regex AvRegex();
[GeneratedRegex("BV(\\w+)")]
[GeneratedRegex("[Bb][Vv](\\w+)")]
private static partial Regex BVRegex();
[GeneratedRegex("bv(\\w+)")]
private static partial Regex BvRegex();
[GeneratedRegex("/ep(\\d{1,})")]
[GeneratedRegex("/ep(\\d+)")]
private static partial Regex EpRegex();
[GeneratedRegex("/ss(\\d{1,})")]
[GeneratedRegex("/ss(\\d+)")]
private static partial Regex SsRegex();
[GeneratedRegex("space\\.bilibili\\.com/(\\d{1,})")]
[GeneratedRegex("space\\.bilibili\\.com/(\\d+)")]
private static partial Regex UidRegex();
[GeneratedRegex("global\\.bilibili\\.com/play/\\d+/(\\d+)")]
private static partial Regex GlobalEpRegex();
[GeneratedRegex("bangumi/media/(md\\d+)")]
private static partial Regex BangumiMdRegex();
[GeneratedRegex("window.__INITIAL_STATE__=([\\s\\S].*?);\\(function\\(\\)")]
private static partial Regex StateRegex();
[GeneratedRegex("ep(\\d{1,})")]
[GeneratedRegex("ep(\\d+)")]
private static partial Regex EpRegex2();
[GeneratedRegex("md(\\d{1,})")]
[GeneratedRegex("md(\\d+)")]
private static partial Regex MdRegex();
[GeneratedRegex("^\\d+$")]
private static partial Regex NumRegex();
Expand Down
5 changes: 4 additions & 1 deletion BBDown/CommandLineInvoker.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ internal class CommandLineInvoker
private readonly static Argument<string> Url = new("url", description: "视频地址 或 av|bv|BV|ep|ss");
private readonly static Option<bool> UseTvApi = new(new string[] { "--use-tv-api", "-tv" }, "使用TV端解析模式");
private readonly static Option<bool> UseAppApi = new(new string[] { "--use-app-api", "-app" }, "使用APP端解析模式");
private readonly static Option<bool> UseIntlApi = new(new string[] { "--use-intl-api", "-intl" }, "使用国际版解析模式");
private readonly static Option<bool> UseIntlApi = new(new string[] { "--use-intl-api", "-intl" }, "使用国际版(东南亚视频)解析模式");
private readonly static Option<bool> UseMP4box = new(new string[] { "--use-mp4box" }, "使用MP4Box来混流");
private readonly static Option<string> EncodingPriority = new(new string[] { "--encoding-priority" }, "视频编码的选择优先级, 用逗号分割 例: \"hevc,av1,avc\"");
private readonly static Option<string> DfnPriority = new(new string[] { "--dfn-priority" }, "画质优先级,用逗号分隔 例: \"8K 超高清, 1080P 高码率, HDR 真彩, 杜比视界\"");
Expand Down Expand Up @@ -44,6 +44,7 @@ internal class CommandLineInvoker
private readonly static Option<string> FFmpegPath = new(new string[] { "--ffmpeg-path" }, "设置ffmpeg的路径");
private readonly static Option<string> Mp4boxPath = new(new string[] { "--mp4box-path" }, "设置mp4box的路径");
private readonly static Option<string> Aria2cPath = new(new string[] { "--aria2c-path" }, "设置aria2c的路径");
private readonly static Option<string> UposHost = new(new string[] { "--upos-host" }, "自定义upos服务器");
private readonly static Option<string> DelayPerPage = new(new string[] { "--delay-per-page" }, "设置下载合集分P之间的下载间隔时间(单位: 秒, 默认无间隔)");
private readonly static Option<string> FilePattern = new(new string[] { "--file-pattern", "-F" }, $"使用内置变量自定义单P存储文件名:\r\n\r\n" + $"<videoTitle>: 视频主标题\r\n" + $"<pageNumber>: 视频分P序号\r\n" + $"<pageNumberWithZero>: 视频分P序号(前缀补零)\r\n" + $"<pageTitle>: 视频分P标题\r\n" + $"<aid>: 视频aid\r\n" + $"<cid>: 视频cid\r\n" + $"<dfn>: 视频清晰度\r\n" + $"<res>: 视频分辨率\r\n" + $"<fps>: 视频帧率\r\n" + $"<videoCodecs>: 视频编码\r\n" + $"<videoBandwidth>: 视频码率\r\n" + $"<audioCodecs>: 音频编码\r\n" + $"<audioBandwidth>: 音频码率\r\n" + $"<ownerName>: 上传者名称\r\n" + $"<ownerMid>: 上传者mid\r\n\r\n" + $"默认为: {Program.SinglePageDefaultSavePath}\r\n");
private readonly static Option<string> MultiFilePattern = new(new string[] { "--multi-file-pattern", "-M" }, $"使用内置变量自定义多P存储文件名:\r\n\r\n" + $"默认为: {Program.MultiPageDefaultSavePath}\r\n");
Expand Down Expand Up @@ -102,6 +103,7 @@ protected override MyOption GetBoundValue(BindingContext bindingContext)
if (bindingContext.ParseResult.HasOption(FFmpegPath)) option.FFmpegPath = bindingContext.ParseResult.GetValueForOption(FFmpegPath)!;
if (bindingContext.ParseResult.HasOption(Mp4boxPath)) option.Mp4boxPath = bindingContext.ParseResult.GetValueForOption(Mp4boxPath)!;
if (bindingContext.ParseResult.HasOption(Aria2cPath)) option.Aria2cPath = bindingContext.ParseResult.GetValueForOption(Aria2cPath)!;
if (bindingContext.ParseResult.HasOption(UposHost)) option.UposHost = bindingContext.ParseResult.GetValueForOption(UposHost)!;
if (bindingContext.ParseResult.HasOption(DelayPerPage)) option.DelayPerPage = bindingContext.ParseResult.GetValueForOption(DelayPerPage)!;
if (bindingContext.ParseResult.HasOption(Host)) option.Host = bindingContext.ParseResult.GetValueForOption(Host)!;
if (bindingContext.ParseResult.HasOption(EpHost)) option.EpHost = bindingContext.ParseResult.GetValueForOption(EpHost)!;
Expand Down Expand Up @@ -156,6 +158,7 @@ public static RootCommand GetRootCommand(Func<MyOption, Task> action)
FFmpegPath,
Mp4boxPath,
Aria2cPath,
UposHost,
DelayPerPage,
Host,
EpHost,
Expand Down
1 change: 1 addition & 0 deletions BBDown/MyOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ internal class MyOption
public string FFmpegPath { get; set; } = "";
public string Mp4boxPath { get; set; } = "";
public string Aria2cPath { get; set; } = "";
public string UposHost { get; set; } = "";
public string DelayPerPage { get; set; } = "0";
public string Host { get; set; } = "api.bilibili.com";
public string EpHost { get; set; } = "api.bilibili.com";
Expand Down
Loading

0 comments on commit e4e9c21

Please sign in to comment.