Skip to content

Commit

Permalink
Merge pull request #818 from My-Responsitories/master
Browse files Browse the repository at this point in the history
fix app subtitle download
  • Loading branch information
nilaoda authored May 12, 2024
2 parents 1196918 + 03c4c45 commit ea08021
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 78 deletions.
2 changes: 1 addition & 1 deletion BBDown.Core/APP/Response/dmviewreply.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ message VideoMask {
message VideoSubtitle {
optional string lan = 1;
optional string lanDoc = 2;
optional SubtitleItem subtitles = 3;
repeated SubtitleItem subtitles = 3;

}

Expand Down
31 changes: 3 additions & 28 deletions BBDown.Core/AppHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
using System.Buffers.Binary;
using System.IO.Compression;
using System.Linq;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Text.Json.Serialization;
using static BBDown.Core.Util.HTTPUtil;
using static BBDown.Core.Logger;

namespace BBDown.Core
Expand Down Expand Up @@ -322,7 +322,7 @@ private static string GenerateFawkesReqBin()
/// </summary>
/// <param name="data"></param>
/// <returns>字节流</returns>
private static byte[] ReadMessage(byte[] data)
public static byte[] ReadMessage(byte[] data)
{
byte first;
int size;
Expand All @@ -348,7 +348,7 @@ private static (byte first, int size) ReadInfo(byte[] data)
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
private static byte[] PackMessage(byte[] input)
public static byte[] PackMessage(byte[] input)
{
using var stream = new MemoryStream();
using (var writer = new BinaryWriter(stream))
Expand Down Expand Up @@ -393,31 +393,6 @@ private static byte[] GzipDecompress(byte[] data)
}
return output.ToArray();
}

public static async Task<byte[]> GetPostResponseAsync(string Url, byte[] postData, Dictionary<string, string> headers)
{
LogDebug("Post to: {0}, data: {1}", Url, Convert.ToBase64String(postData));

ByteArrayContent content = new(postData);
content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/grpc");

HttpRequestMessage request = new()
{
RequestUri = new Uri(Url),
Method = HttpMethod.Post,
Content = content,
//Version = HttpVersion.Version20
};

if (headers != null)
foreach (KeyValuePair<string, string> header in headers)
request.Headers.TryAddWithoutValidation(header.Key, header.Value);

HttpResponseMessage response = await Util.HTTPUtil.AppHttpClient.SendAsync(request);
byte[] bytes = await response.Content.ReadAsByteArrayAsync();

return bytes;
}
}


Expand Down
38 changes: 28 additions & 10 deletions BBDown.Core/Util/HTTPUtil.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,18 +70,36 @@ public static async Task<string> GetWebLocationAsync(string url)
return location;
}

public static async Task<string> GetPostResponseAsync(string Url, byte[] postData)
public static async Task<byte[]> GetPostResponseAsync(string Url, byte[] postData, Dictionary<string, string> headers = null)
{
LogDebug("Post to: {0}, data: {1}", Url, Convert.ToBase64String(postData));
using HttpRequestMessage request = new(HttpMethod.Post, Url);
request.Headers.TryAddWithoutValidation("Content-Type", "application/grpc");
request.Headers.TryAddWithoutValidation("Content-Length", postData.Length.ToString());
request.Headers.TryAddWithoutValidation("User-Agent", "Dalvik/2.1.0 (Linux; U; Android 6.0.1; oneplus a5010 Build/V417IR) 6.10.0 os/android model/oneplus a5010 mobi_app/android build/6100500 channel/bili innerVer/6100500 osVer/6.0.1 network/2");
request.Headers.TryAddWithoutValidation("Cookie", Config.COOKIE);
request.Content = new ByteArrayContent(postData);
var webResponse = await AppHttpClient.SendAsync(request, HttpCompletionOption.ResponseHeadersRead);
string htmlCode = await webResponse.Content.ReadAsStringAsync();
return htmlCode;

ByteArrayContent content = new(postData);
content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/grpc");

HttpRequestMessage request = new()
{
RequestUri = new Uri(Url),
Method = HttpMethod.Post,
Content = content,
//Version = HttpVersion.Version20
};

if (headers != null)
{
foreach (KeyValuePair<string, string> header in headers)
request.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
else
{
request.Headers.TryAddWithoutValidation("User-Agent", "Dalvik/2.1.0 (Linux; U; Android 6.0.1; oneplus a5010 Build/V417IR) 6.10.0 os/android model/oneplus a5010 mobi_app/android build/6100500 channel/bili innerVer/6100500 osVer/6.0.1 network/2");
request.Headers.TryAddWithoutValidation("grpc-encoding", "gzip");
}

HttpResponseMessage response = await AppHttpClient.SendAsync(request);
byte[] bytes = await response.Content.ReadAsByteArrayAsync();

return bytes;
}
}
}
77 changes: 38 additions & 39 deletions BBDown.Core/Util/SubUtil.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.Text;
using BBDown.Core.Protobuf;
using Google.Protobuf;
using System.Text;
using static BBDown.Core.Entity.Entity;
using static BBDown.Core.Util.HTTPUtil;
using System.Text.RegularExpressions;
Expand Down Expand Up @@ -356,48 +358,39 @@ public static (string, string) GetSubtitleCode(string key)
}
}

private static byte[] GetPayload(long aid, long cid)
{
var obj = new DmViewReq
{
Pid = aid,
Oid = cid,
Type = 1,
Spmid = "main.ugc-video-detail.0.0",
};
return AppHelper.PackMessage(obj.ToByteArray());
}

private static async Task<List<Subtitle>?> GetSubtitlesFromApi3Async(string aid, string cid, string epId, int index)
{
try
{
List<Subtitle> subtitles = new();
//grpc调用接口 protobuf
string api = "https://app.biliapi.net/bilibili.community.service.dm.v1.DM/DmView";
int _aid = Convert.ToInt32(aid);
int _cid = Convert.ToInt32(cid);
int _type = 1;
byte[] data = new byte[18];
data[0] = 0x0; data[1] = 0x0; data[2] = 0x0; data[3] = 0x0; data[4] = 0xD; //先固定死了
int i = 5;
data[i++] = Convert.ToByte((1 << 3) | 0); // index=1
while ((_aid & -128) != 0)
{
data[i++] = Convert.ToByte((_aid & 127) | 128);
_aid >>= 7;
}
data[i++] = Convert.ToByte(_aid);
data[i++] = Convert.ToByte((2 << 3) | 0); // index=2
while ((_cid & -128) != 0)

var data = GetPayload(Convert.ToInt64(aid), Convert.ToInt64(cid));

var t = AppHelper.ReadMessage(await GetPostResponseAsync(api, data));
var resp = new MessageParser<DmViewReply>(() => new DmViewReply()).ParseFrom(t);

if (resp.Subtitle != null && resp.Subtitle.Subtitles != null)
{
data[i++] = Convert.ToByte((_cid & 127) | 128);
_cid >>= 7;
subtitles.AddRange(resp.Subtitle.Subtitles.Select(item => new Subtitle() {
url = item.SubtitleUrl,
lan = item.Lan,
path = $"{aid}/{aid}.{cid}.{item.Lan}.srt"
}));
}
data[i++] = Convert.ToByte(_cid);
data[i++] = Convert.ToByte((3 << 3) | 0); // index=3
data[i++] = Convert.ToByte(_type);
string t = await GetPostResponseAsync(api, data);
Regex reg = CnJsonRegex();
foreach (Match m in reg.Matches(t).Cast<Match>())
{
Subtitle subtitle = new()
{
url = m.Groups[2].Value,
lan = m.Groups[1].Value,
path = $"{aid}/{aid}.{cid}.{m.Groups[1].Value}.srt"
};
subtitles.Add(subtitle);
}

//有空的URL 不合法
if (subtitles.Any(s => string.IsNullOrEmpty(s.url)))
throw new Exception("Bad url");
Expand All @@ -421,9 +414,17 @@ public static async Task<List<Subtitle>> GetSubtitlesAsync(string aid, string ci
}
else
{
subtitles = await GetSubtitlesFromApi2Async(aid, cid, epId, index)
?? await GetSubtitlesFromApi1Async(aid, cid, epId, index)
?? await GetSubtitlesFromApi3Async(aid, cid, epId, index);
if (Config.COOKIE == "")
{
subtitles = await GetSubtitlesFromApi3Async(aid, cid, epId, index); // 未登录只有APP可以拿到字幕了
}
else
{
subtitles = await GetSubtitlesFromApi2Async(aid, cid, epId, index)
?? await GetSubtitlesFromApi1Async(aid, cid, epId, index)
?? await GetSubtitlesFromApi3Async(aid, cid, epId, index);
}

}

if (subtitles == null)
Expand Down Expand Up @@ -480,7 +481,5 @@ private static string FormatTime(double sec) //64.13

[GeneratedRegex("-[a-z]")]
private static partial Regex NonCapsRegex();
[GeneratedRegex("(zh-Han[st]).*?(http.*?\\.json)")]
private static partial Regex CnJsonRegex();
}
}

0 comments on commit ea08021

Please sign in to comment.