Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

给视频添加creation_time, 以及一些小修改 #686

Merged
merged 4 commits into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 37 additions & 3 deletions BBDown.Core/APP/Response/playviewreply.proto
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ message VideoInfo {
optional uint32 videoCodecid = 4;
repeated StreamItem streamList = 5;
repeated DashItem dashAudio = 6;
//�űȰ�����E
//杜比伴音流
optional DolbyItem dolby = 7;
optional DolbyItem flac = 9;
}

//�ű���Ƶ��Ϣ
//杜比音频信息
message DolbyItem {
optional int32 type = 1;
//��Ƶ��E
//音频流
optional DashItem audio = 2;
}

Expand Down Expand Up @@ -46,10 +47,17 @@ message PlayAbilityConf {
optional bool shakeDisable = 24;
}

message ClipInfo {
optional int32 start = 2;
optional int32 end = 3;
optional string toastText = 5;
}

message BusinessInfo {
optional bool isPreview = 1;
optional bool bp = 2;
optional string marlinToken = 3;
repeated ClipInfo clipInfo = 6;
}

message Event {
Expand Down Expand Up @@ -121,9 +129,35 @@ message ResponseUrl {
optional string md5 = 6;
}

message RoleAudioProto {
// 配音列表
repeated AudioMaterialProto audioMaterialList = 4;
}

message AudioMaterialProto {
optional string audioId = 1;
optional string title = 2;
optional string edition = 3;
optional string personName = 5;
repeated DashItem audio = 7;
}

message PlayDubbingInfo {
// 背景音频
optional AudioMaterialProto backgroundAudio = 1;
// 角色音频列表
repeated RoleAudioProto roleAudioList = 2;
}

message PlayExtInfo {
// 播放配音信息
optional PlayDubbingInfo playDubbingInfo = 1;
}

message PlayViewReply {
optional VideoInfo videoInfo = 1;
optional PlayAbilityConf playConf = 2;
optional BusinessInfo business = 3;
optional Event event = 4;
optional PlayExtInfo playExtInfo = 7;
}
201 changes: 160 additions & 41 deletions BBDown.Core/AppHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Google.Protobuf;
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;
Expand All @@ -12,13 +13,13 @@ namespace BBDown.Core
class AppHelper
{
private static readonly string API = "https://grpc.biliapi.net/bilibili.app.playurl.v1.PlayURL/PlayView";
private static readonly string API2 = "https://app.bilibili.com/bilibili.pgc.gateway.player.v1.PlayURL/PlayView";
private static readonly string API2 = "https://app.bilibili.com/bilibili.pgc.gateway.player.v2.PlayURL/PlayView";
private static readonly string dalvikVer = "2.1.0";
private static readonly string osVer = "11";
private static readonly string brand = "M2012K11AC";
private static readonly string model = "Build/RKQ1.200826.002";
private static readonly string appVer = "6.32.0";
private static readonly int build = 6320200;
private static readonly string appVer = "7.32.0";
private static readonly int build = 7320200; // 新版才能抓到配音
private static readonly string channel = "xiaomi_cn_tv.danmaku.bili_zm20200902";
private static readonly Network.Types.TYPE networkType = Network.Types.TYPE.Wifi;
private static readonly string networkOid = "46007";
Expand Down Expand Up @@ -54,34 +55,23 @@ private static PlayViewReq.Types.CodeType GetVideoCodeType(string code)
/// <returns></returns>
public static async Task<string> DoReqAsync(string aid, string cid, string epId, string qn, bool bangumi, string encoding, string appkey = "")
{

var headers = GetHeader(appkey);
LogDebug("App-Req-Headers: {0}", JsonSerializer.Serialize(headers, JsonContext.Default.DictionaryStringString));
var body = GetPayload(Convert.ToInt64(aid), Convert.ToInt64(cid), Convert.ToInt64(qn), GetVideoCodeType(encoding));
//Console.WriteLine(ReadMessage<PlayViewReq>(body));
var data = await GetPostResponseAsync(API, body, headers);
PlayViewReply? resp;
try
byte[] body, data;
// 只有pgc接口才有配音和片头尾信息
if (bangumi)
{
resp = new MessageParser<PlayViewReply>(() => new PlayViewReply()).ParseFrom(ReadMessage(data));
body = GetPayload(Convert.ToInt64(epId), Convert.ToInt64(cid), Convert.ToInt64(qn), GetVideoCodeType(encoding));
data = await GetPostResponseAsync(API2, body, headers);
}
catch (Exception ex)
else
{
if (Config.DEBUG_LOG)
{
LogError(ex.Message);
}

if (bangumi)
{
body = GetPayload(Convert.ToInt64(epId), Convert.ToInt64(cid), Convert.ToInt64(qn), GetVideoCodeType(encoding));
data = await GetPostResponseAsync(API2, body, headers);
resp = new MessageParser<PlayViewReply>(() => new PlayViewReply()).ParseFrom(ReadMessage(data));
}
else
{
throw;
}
body = GetPayload(Convert.ToInt64(aid), Convert.ToInt64(cid), Convert.ToInt64(qn), GetVideoCodeType(encoding));
data = await GetPostResponseAsync(API, body, headers);
}
var resp = new MessageParser<PlayViewReply>(() => new PlayViewReply()).ParseFrom(ReadMessage(data));

LogDebug("PlayViewReplyPlain: {0}", JsonSerializer.Serialize(resp, JsonContext.Default.PlayViewReply));
return ConvertToDashJson(resp);
}
Expand All @@ -96,6 +86,7 @@ private static string ConvertToDashJson(object data)
var resp = (PlayViewReply)data;
var videos = new List<object>();
var audios = new List<object>();
var clips = new List<object>();

if (resp.VideoInfo.StreamList != null)
{
Expand All @@ -116,16 +107,24 @@ private static string ConvertToDashJson(object data)

if (resp.VideoInfo.DashAudio != null)
{
foreach (var item in resp.VideoInfo.DashAudio)
{
audios.Add(new AudioInfoWithCodecName(
item.Id,
item.BaseUrl,
item.BackupUrl.ToList(),
item.Bandwidth,
"M4A"
));
}
audios.AddRange(resp.VideoInfo.DashAudio.Select(item => new AudioInfoWithCodecName(
item.Id,
item.BaseUrl,
item.BackupUrl.ToList(),
item.Bandwidth,
"M4A"
)));
}

if (resp.VideoInfo.Flac != null && resp.VideoInfo.Flac.Audio != null)
{
audios.Add(new AudioInfoWithCodecName(
resp.VideoInfo.Flac.Audio.Id,
resp.VideoInfo.Flac.Audio.BaseUrl,
resp.VideoInfo.Flac.Audio.BackupUrl.ToList(),
resp.VideoInfo.Flac.Audio.Bandwidth,
"FLAC"
));
}

if (resp.VideoInfo.Dolby != null && resp.VideoInfo.Dolby.Audio != null)
Expand All @@ -139,6 +138,51 @@ private static string ConvertToDashJson(object data)
));
}

if (resp.Business != null && resp.Business.ClipInfo != null)
{
clips.AddRange(resp.Business.ClipInfo.Select(clip => new DashClip(
clip.Start,
clip.End,
clip.ToastText
)));
}

var backgroundAudios = new List<object>();
var roles = new List<object>();
if (resp.PlayExtInfo != null && resp.PlayExtInfo.PlayDubbingInfo != null && resp.PlayExtInfo.PlayDubbingInfo.BackgroundAudio != null)
{
var dubInfo = resp.PlayExtInfo.PlayDubbingInfo;

backgroundAudios.AddRange(dubInfo.BackgroundAudio.Audio.Select(item => new AudioInfoWithCodecName(
item.Id,
item.BaseUrl,
item.BackupUrl.ToList(),
item.Bandwidth,
"M4A"
)));

foreach (var item in dubInfo.RoleAudioList)
{
foreach (var role in item.AudioMaterialList)
{
List<object> roleAudios = role.Audio.Select(item => new AudioInfoWithCodecName(
item.Id,
item.BaseUrl,
item.BackupUrl.ToList(),
item.Bandwidth,
"M4A"
)).Cast<object>().ToList();

roles.Add(new AudioMaterial(
role.AudioId,
role.Title ?? role.AudioId,
role.PersonName ?? role.Edition ?? "",
roleAudios
));
}
}
}

var json = new DashJson(
0,
"0",
Expand All @@ -148,7 +192,12 @@ private static string ConvertToDashJson(object data)
new DashInfo(
videos,
audios
)
),
clips
),
new DubbingInfo(
backgroundAudios,
roles
)
);

Expand All @@ -164,6 +213,7 @@ private static byte[] GetPayload(long aid, long cid, long qn, PlayViewReq.Types.
//obj.Qn = qn;
Qn = 127,
Fnval = 4048,
Fourk = true,
Spmid = "main.ugc-video-detail.0.0",
FromSpmid = "main.my-history.0.0",
PreferCodecType = codec,
Expand Down Expand Up @@ -369,6 +419,9 @@ public static async Task<byte[]> GetPostResponseAsync(string Url, byte[] postDat
}


[JsonSerializable(typeof(AudioMaterial))]
[JsonSerializable(typeof(DubbingInfo))]
[JsonSerializable(typeof(DashClip))]
[JsonSerializable(typeof(AudioInfoWithCodecName))]
[JsonSerializable(typeof(AudioInfoWitCodecId))]
[JsonSerializable(typeof(DashJson))]
Expand All @@ -377,6 +430,66 @@ public static async Task<byte[]> GetPostResponseAsync(string Url, byte[] postDat
[JsonSerializable(typeof(Dictionary<string, string>))]
internal partial class JsonContext : JsonSerializerContext { }

internal class AudioMaterial
{
[JsonPropertyName("audio_id")]
public string AudioId { get; }
[JsonPropertyName("title")]
public string Title { get; }
[JsonPropertyName("person_name")]
public string PersonName { get; }
[JsonPropertyName("audio")]
public List<object> Audio { get; }

public AudioMaterial(string audio_id, string title, string person_name, List<object> audio)
{
AudioId = audio_id;
Title = title;
PersonName = person_name;
Audio = audio;
}

public override bool Equals(object? obj) => obj is AudioMaterial other && AudioId == other.AudioId && Title == other.Title && PersonName == other.PersonName && Audio == other.Audio;
public override int GetHashCode() => HashCode.Combine(Title, Audio);
}

internal class DubbingInfo
{
[JsonPropertyName("background_audio")]
public List<object> BackgroundAudio { get; }
[JsonPropertyName("role_audio_list")]
public List<object> RoleAudioList { get; }

public DubbingInfo(List<object> background_audio, List<object> role_audio_list)
{
BackgroundAudio = background_audio;
RoleAudioList = role_audio_list;
}

public override bool Equals(object? obj) => obj is DubbingInfo other && BackgroundAudio == other.BackgroundAudio && RoleAudioList == other.RoleAudioList;
public override int GetHashCode() => HashCode.Combine(BackgroundAudio, RoleAudioList);
}

internal class DashClip
{
[JsonPropertyName("start")]
public int Start { get; }
[JsonPropertyName("end")]
public int End { get; }
[JsonPropertyName("toastText")]
public string ToastText { get; }

public DashClip(int start, int end, string toastText)
{
Start = start;
End = end;
ToastText = toastText;
}

public override bool Equals(object? obj) => obj is DashClip other && Start == other.Start && End == other.End && ToastText == other.ToastText;
public override int GetHashCode() => HashCode.Combine(Start, End, ToastText);
}

internal class AudioInfoWithCodecName
{
[JsonPropertyName("id")]
Expand Down Expand Up @@ -452,15 +565,18 @@ internal class DashData
public ulong TimeLength { get; }
[JsonPropertyName("dash")]
public DashInfo Dash { get; }
[JsonPropertyName("clip_info_list")]
public List<object> ClipList { get; }

public DashData(ulong timelength, DashInfo dash)
public DashData(ulong timelength, DashInfo dash, List<object> clipList)
{
TimeLength = timelength;
Dash = dash;
ClipList = clipList;
}

public override bool Equals(object? obj) => obj is DashData other && TimeLength == other.TimeLength && EqualityComparer<DashInfo>.Default.Equals(Dash, other.Dash);
public override int GetHashCode() => HashCode.Combine(TimeLength, Dash);
public override bool Equals(object? obj) => obj is DashData other && TimeLength == other.TimeLength && EqualityComparer<DashInfo>.Default.Equals(Dash, other.Dash) && EqualityComparer<List<object>>.Default.Equals(ClipList, other.ClipList);
public override int GetHashCode() => HashCode.Combine(TimeLength, Dash, ClipList);
}

internal class DashJson
Expand All @@ -473,16 +589,19 @@ internal class DashJson
public int Ttl { get; }
[JsonPropertyName("data")]
public DashData Data { get; }
[JsonPropertyName("dubbing_info")]
public DubbingInfo DubbingInfo { get; }

public DashJson(int code, string message, int ttl, DashData data)
public DashJson(int code, string message, int ttl, DashData data, DubbingInfo dubbingInfo)
{
Code = code;
Message = message;
Ttl = ttl;
Data = data;
DubbingInfo = dubbingInfo;
}

public override bool Equals(object? obj) => obj is DashJson other && Code == other.Code && Message == other.Message && Ttl == other.Ttl && EqualityComparer<DashData>.Default.Equals(Data, other.Data);
public override int GetHashCode() => HashCode.Combine(Code, Message, Ttl, Data);
public override int GetHashCode() => HashCode.Combine(Code, Message, Ttl, Data, DubbingInfo);
}
}
Loading