From 24f28d6ce22aca7769e9c81eff751b71532fe78e Mon Sep 17 00:00:00 2001 From: Kengwang Date: Fri, 5 Feb 2021 17:44:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=20=E5=AD=97=E5=B9=95?= =?UTF-8?q?=E4=B8=8B=E8=BD=BD=20&=20Release=202.1.7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 此次的契机是缓存 LexBurner 直播恶心发言的字幕. 同时对于 LexBurner 的发言,我个人表示十分厌恶,已经取关了. 贴个知乎链接: https://www.zhihu.com/question/442911026 --- BiliDuang/BiliDuang.csproj | 4 +- BiliDuang/DownloadObject.cs | 127 +++++++++++------- BiliDuang/JSONCallback/SubPlayer.cs | 84 ++++++++++++ BiliDuang/MainForm.Designer.cs | 22 ++- BiliDuang/MainForm.cs | 7 + BiliDuang/Settings.cs | 8 +- .../UI/Download/DownloadItem.Designer.cs | 19 --- BiliDuang/tools/Bcc2srt.cs | 43 ++++++ BiliDuang/{ => tools}/DanmakuAss.cs | 0 9 files changed, 239 insertions(+), 75 deletions(-) create mode 100644 BiliDuang/JSONCallback/SubPlayer.cs create mode 100644 BiliDuang/tools/Bcc2srt.cs rename BiliDuang/{ => tools}/DanmakuAss.cs (100%) diff --git a/BiliDuang/BiliDuang.csproj b/BiliDuang/BiliDuang.csproj index dd0361d..6f2b46f 100644 --- a/BiliDuang/BiliDuang.csproj +++ b/BiliDuang/BiliDuang.csproj @@ -63,7 +63,9 @@ - + + + diff --git a/BiliDuang/DownloadObject.cs b/BiliDuang/DownloadObject.cs index 4ebab6b..22c466b 100644 --- a/BiliDuang/DownloadObject.cs +++ b/BiliDuang/DownloadObject.cs @@ -124,7 +124,10 @@ public void LinkStart() single = true; } - DownloadDanmaku(); + if (Settings.downloaddanmaku) + DownloadDanmaku(); + if (Settings.downloadcc) + DownloadSubtitle(); if (type == 0) { @@ -389,64 +392,83 @@ private void Completed(bool complete, string msg) } } + private void DownloadSubtitle(string sid = "") + { + string playerback = Encoding.UTF8.GetString(new WebClient().DownloadData(string.Format("https://api.bilibili.com/x/player/v2?cid={0}&aid={1}", cid, aid))); + JSONCallback.SubPlayer.Root playerbackjson = JsonConvert.DeserializeObject(playerback); + if (playerbackjson.code != 0) + { + Console.WriteLine("下载字幕出错"); + return; + } + string bcc = ""; + if (playerbackjson.data.subtitle.subtitles.Count == 0) return; + if (playerbackjson.data.subtitle.subtitles.FindIndex((x) => { return x.id == sid; }) != -1) + { + bcc = Encoding.UTF8.GetString(new WebClient().DownloadData("https:" + playerbackjson.data.subtitle.subtitles.Find((x) => { return x.id == sid; }).subtitle_url)); + } + else + { + bcc = Encoding.UTF8.GetString(new WebClient().DownloadData("https:" + playerbackjson.data.subtitle.subtitles[0].subtitle_url)); + + } + File.WriteAllText(saveto + "/" + avname + ".srt", Bcc2srt.Convert(bcc)); + } + private void DownloadDanmaku() { - if (Settings.downloaddanmaku) + try { - try + message = "正在下载弹幕"; + //1.'https://comment.bilibili.com/' + cid + '.xml' + //2.'https://api.bilibili.com/x/v1/dm/list.so?oid=' + cid + string danmakuorigin = Other.GetHtml("https://comment.bilibili.com/" + cid + ".xml"); + //暂时存一下原始弹幕 + File.WriteAllText(saveto + "/" + avname + ".xml", danmakuorigin); + XmlDocument xml = new XmlDocument(); + xml.LoadXml(danmakuorigin); + if (xml.GetElementsByTagName("state")[0].InnerText != "0") { - message = "正在下载弹幕"; - //1.'https://comment.bilibili.com/' + cid + '.xml' - //2.'https://api.bilibili.com/x/v1/dm/list.so?oid=' + cid - string danmakuorigin = Other.GetHtml("https://comment.bilibili.com/" + cid + ".xml"); - //暂时存一下原始弹幕 - File.WriteAllText(saveto + "/" + avname + ".xml", danmakuorigin); - XmlDocument xml = new XmlDocument(); - xml.LoadXml(danmakuorigin); - if (xml.GetElementsByTagName("state")[0].InnerText != "0") - { - //弹幕出错 - message = "弹幕下载出错"; - } - else + //弹幕出错 + message = "弹幕下载出错"; + } + else + { + XmlNodeList xmlNodeList = xml.GetElementsByTagName("d"); + if (urls[0].width == 0) { - XmlNodeList xmlNodeList = xml.GetElementsByTagName("d"); - if (urls[0].width == 0) + switch (quality) { - switch (quality) - { - case 120://4K - urls[0].width = 4096; - urls[0].height = 2160; - break; - case 116://1080P60 - case 112://1080P+ - case 80://1080P - urls[0].width = 1920; - urls[0].height = 1080; - break; - case 74://720P60 - case 64://720P - urls[0].width = 1280; - urls[0].height = 720; - break; - case 32://480P - urls[0].width = 720; - urls[0].height = 480; - break; - case 16://360P - urls[0].width = 480; - urls[0].height = 360; - break; - } + case 120://4K + urls[0].width = 4096; + urls[0].height = 2160; + break; + case 116://1080P60 + case 112://1080P+ + case 80://1080P + urls[0].width = 1920; + urls[0].height = 1080; + break; + case 74://720P60 + case 64://720P + urls[0].width = 1280; + urls[0].height = 720; + break; + case 32://480P + urls[0].width = 720; + urls[0].height = 480; + break; + case 16://360P + urls[0].width = 480; + urls[0].height = 360; + break; } - string assdmk = DanmakuAss.DanmakuAss.Convert(xmlNodeList, urls[0].width, urls[0].height); - File.WriteAllText(saveto + "/" + avname + ".ass", assdmk); } + string assdmk = DanmakuAss.DanmakuAss.Convert(xmlNodeList, urls[0].width, urls[0].height); + File.WriteAllText(saveto + "/" + avname + ".ass", assdmk); } - catch (Exception) { } } - + catch (Exception) { } } @@ -667,7 +689,7 @@ private bool GetDownloadUrls() } catch (Exception e) { - message = "链接数据解析失败: "+e.Message; + message = "链接数据解析失败: " + e.Message; return false; } if (player.code == -404) @@ -835,13 +857,14 @@ private bool GetDownloadUrls() } } - }catch (Exception e) + } + catch (Exception e) { Console.WriteLine("下载链接获取出错: " + e.ToString()); message = "获取下载链接出错"; return false; } - + } #region Aria2c下载 diff --git a/BiliDuang/JSONCallback/SubPlayer.cs b/BiliDuang/JSONCallback/SubPlayer.cs new file mode 100644 index 0000000..15e289b --- /dev/null +++ b/BiliDuang/JSONCallback/SubPlayer.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BiliDuang.JSONCallback.SubPlayer +{ + + public class SubtitlesItem + { + /// + /// + /// + public string id { get; set; } + /// + /// + /// + public string lan { get; set; } + /// + /// 中文(中国) + /// + public string lan_doc { get; set; } + /// + /// + /// + public string is_lock { get; set; } + /// + /// + /// + public int author_mid { get; set; } + /// + /// + /// + public string subtitle_url { get; set; } + } + + public class Subtitle + { + /// + /// + /// + public string allow_submit { get; set; } + /// + /// + /// + public string lan { get; set; } + /// + /// + /// + public string lan_doc { get; set; } + /// + /// + /// + public List subtitles { get; set; } + } + + public class Data + { + + public Subtitle subtitle { get; set; } + } + + public class Root + { + /// + /// + /// + public int code { get; set; } + /// + /// + /// + public string message { get; set; } + /// + /// + /// + public int ttl { get; set; } + /// + /// + /// + public Data data { get; set; } + } + +} diff --git a/BiliDuang/MainForm.Designer.cs b/BiliDuang/MainForm.Designer.cs index 886a0cb..8d69159 100644 --- a/BiliDuang/MainForm.Designer.cs +++ b/BiliDuang/MainForm.Designer.cs @@ -77,6 +77,7 @@ private void InitializeComponent() this.materialLabel2 = new MaterialSkin.Controls.MaterialLabel(); this.LoginButton = new MaterialSkin.Controls.MaterialFlatButton(); this.SeasonSelectBox = new MaterialSkin.Controls.MaterialComboBox(); + this.materialCheckBox4 = new MaterialSkin.Controls.MaterialCheckBox(); this.Tabs.SuspendLayout(); this.SearchResult.SuspendLayout(); this.panel3.SuspendLayout(); @@ -369,6 +370,7 @@ private void InitializeComponent() // Setttings // this.Setttings.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(63)))), ((int)(((byte)(81)))), ((int)(((byte)(181))))); + this.Setttings.Controls.Add(this.materialCheckBox4); this.Setttings.Controls.Add(this.materialCheckBox3); this.Setttings.Controls.Add(this.materialFlatButton8); this.Setttings.Controls.Add(this.APILink); @@ -398,7 +400,7 @@ private void InitializeComponent() this.materialCheckBox3.AutoSize = true; this.materialCheckBox3.Depth = 0; this.materialCheckBox3.Font = new System.Drawing.Font("微软雅黑", 10F); - this.materialCheckBox3.Location = new System.Drawing.Point(673, 102); + this.materialCheckBox3.Location = new System.Drawing.Point(836, 103); this.materialCheckBox3.Margin = new System.Windows.Forms.Padding(0); this.materialCheckBox3.MouseLocation = new System.Drawing.Point(-1, -1); this.materialCheckBox3.MouseState = MaterialSkin.MouseState.HOVER; @@ -791,6 +793,23 @@ private void InitializeComponent() this.SeasonSelectBox.Visible = false; this.SeasonSelectBox.SelectedIndexChanged += new System.EventHandler(this.SeasonSelectBox_SelectedIndexChanged); // + // materialCheckBox4 + // + this.materialCheckBox4.AutoSize = true; + this.materialCheckBox4.Depth = 0; + this.materialCheckBox4.Font = new System.Drawing.Font("微软雅黑", 10F); + this.materialCheckBox4.Location = new System.Drawing.Point(644, 103); + this.materialCheckBox4.Margin = new System.Windows.Forms.Padding(0); + this.materialCheckBox4.MouseLocation = new System.Drawing.Point(-1, -1); + this.materialCheckBox4.MouseState = MaterialSkin.MouseState.HOVER; + this.materialCheckBox4.Name = "materialCheckBox4"; + this.materialCheckBox4.Ripple = true; + this.materialCheckBox4.Size = new System.Drawing.Size(154, 30); + this.materialCheckBox4.TabIndex = 18; + this.materialCheckBox4.Text = "同时下载字幕并转换"; + this.materialCheckBox4.UseVisualStyleBackColor = true; + this.materialCheckBox4.CheckedChanged += new System.EventHandler(this.materialCheckBox4_CheckedChanged); + // // MainForm // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); @@ -876,6 +895,7 @@ private void materialListView1_ColumnWidthChanged(object sender, ColumnWidthChan private MaterialSkin.Controls.MaterialSingleLineTextField APILink; private MaterialSkin.Controls.MaterialFlatButton materialFlatButton8; private MaterialSkin.Controls.MaterialCheckBox materialCheckBox3; + private MaterialSkin.Controls.MaterialCheckBox materialCheckBox4; } } diff --git a/BiliDuang/MainForm.cs b/BiliDuang/MainForm.cs index 24c2e9a..895fb9a 100644 --- a/BiliDuang/MainForm.cs +++ b/BiliDuang/MainForm.cs @@ -39,6 +39,7 @@ private void Initialize() Tabs.Size = new Size(Tabs.Width, Tabs.Height + 30); materialCheckBox1.Checked = Settings.usearia2c; materialCheckBox2.Checked = Settings.downloaddanmaku; + materialCheckBox4.Checked = Settings.downloadcc; aria2cargu.Visible = materialCheckBox1.Checked; aria2cargu.Text = Settings.aria2cargument; materialFlatButton7.Visible = materialCheckBox1.Checked; @@ -523,5 +524,11 @@ private void materialCheckBox3_CheckedChanged(object sender, EventArgs e) { Settings.thailandphrase = materialCheckBox3.Checked; } + + private void materialCheckBox4_CheckedChanged(object sender, EventArgs e) + { + Settings.downloadcc = materialCheckBox4.Checked; + Settings.SaveSettings(); + } } } diff --git a/BiliDuang/Settings.cs b/BiliDuang/Settings.cs index 76f7e44..ec0b6b1 100644 --- a/BiliDuang/Settings.cs +++ b/BiliDuang/Settings.cs @@ -6,8 +6,8 @@ namespace BiliDuang { internal class Settings { - public static string versionCode = "2.1.6"; - public static string versionName = "Arks"; + public static string versionCode = "2.1.7"; + public static string versionName = "Staroshi"; public static int maxMission = 1; public static int useapi = 0; //0 - Bilibili 1 - BiliPlus 2 - BiliBili TV @@ -18,6 +18,7 @@ internal class Settings public static bool usearia2c = false; public static bool thailandphrase = false; public static bool downloaddanmaku = false; + public static bool downloadcc = false; public static string aria2cargument = ""; public static void SaveSettings() @@ -32,6 +33,7 @@ public static void SaveSettings() usearia2c = Settings.usearia2c, aria2cargument = Settings.aria2cargument, downloaddanmaku = Settings.downloaddanmaku, + downloadcc = Settings.downloadcc, apilink = Settings.apilink }; File.WriteAllText(Environment.CurrentDirectory + "/config/settings", JsonConvert.SerializeObject(settings)); @@ -50,6 +52,7 @@ public static void ReadSettings() Settings.usearia2c = setting.usearia2c; Settings.aria2cargument = setting.aria2cargument; Settings.downloaddanmaku = setting.downloaddanmaku; + Settings.downloadcc = setting.downloadcc; Settings.apilink = setting.apilink; } catch (Exception) @@ -68,6 +71,7 @@ internal class _Settings public bool autodark = true; public bool usearia2c = false; public bool downloaddanmaku = false; + public bool downloadcc = false; public string aria2cargument = ""; internal string apilink; } diff --git a/BiliDuang/UI/Download/DownloadItem.Designer.cs b/BiliDuang/UI/Download/DownloadItem.Designer.cs index 6c54fa9..0743246 100644 --- a/BiliDuang/UI/Download/DownloadItem.Designer.cs +++ b/BiliDuang/UI/Download/DownloadItem.Designer.cs @@ -34,7 +34,6 @@ private void InitializeComponent() this.MissonCancel = new System.Windows.Forms.Label(); this.MissionStateChange = new System.Windows.Forms.Label(); this.StatusBox = new MaterialSkin.Controls.MaterialLabel(); - this.SelectBox = new MaterialSkin.Controls.MaterialCheckBox(); this.SuspendLayout(); // // MissionName @@ -113,26 +112,10 @@ private void InitializeComponent() this.StatusBox.TabIndex = 5; this.StatusBox.Text = "正在获取状态"; // - // SelectBox - // - this.SelectBox.AutoSize = true; - this.SelectBox.Depth = 0; - this.SelectBox.Font = new System.Drawing.Font("微软雅黑", 10F); - this.SelectBox.Location = new System.Drawing.Point(723, 3); - this.SelectBox.Margin = new System.Windows.Forms.Padding(0); - this.SelectBox.MouseLocation = new System.Drawing.Point(-1, -1); - this.SelectBox.MouseState = MaterialSkin.MouseState.HOVER; - this.SelectBox.Name = "SelectBox"; - this.SelectBox.Ripple = true; - this.SelectBox.Size = new System.Drawing.Size(26, 30); - this.SelectBox.TabIndex = 6; - this.SelectBox.UseVisualStyleBackColor = true; - // // DownloadItem // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.SelectBox); this.Controls.Add(this.StatusBox); this.Controls.Add(this.MissionStateChange); this.Controls.Add(this.MissonCancel); @@ -142,7 +125,6 @@ private void InitializeComponent() this.Name = "DownloadItem"; this.Size = new System.Drawing.Size(761, 92); this.ResumeLayout(false); - this.PerformLayout(); } @@ -154,6 +136,5 @@ private void InitializeComponent() private System.Windows.Forms.Label MissonCancel; private System.Windows.Forms.Label MissionStateChange; private MaterialSkin.Controls.MaterialLabel StatusBox; - private MaterialSkin.Controls.MaterialCheckBox SelectBox; } } diff --git a/BiliDuang/tools/Bcc2srt.cs b/BiliDuang/tools/Bcc2srt.cs new file mode 100644 index 0000000..fc331d8 --- /dev/null +++ b/BiliDuang/tools/Bcc2srt.cs @@ -0,0 +1,43 @@ +using Newtonsoft.Json; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace BiliDuang.tools +{ + class Bcc2srt + { + public static string Convert(string bcc) + { + bccFile bccfile = JsonConvert.DeserializeObject(bcc); + int cnt = 0; + string output = ""; + foreach (bccDialog dialog in bccfile.body) + { + DateTime from = new DateTime(long.Parse((double.Parse(dialog.from) * 10000000).ToString())); + DateTime to = new DateTime(long.Parse((double.Parse(dialog.to) * 10000000).ToString())); + string fromstr = from.ToString("H:mm:ss,fff"); + string tostr = to.ToString("H:mm:ss,fff"); + output += cnt.ToString() + "\r\n" + fromstr + " --> " + tostr + "\r\n" + dialog.content+"\r\n\r\n"; + cnt++; + } + return output; + } + } + + struct bccFile + { + public List body { get; set; } + } + + struct bccDialog + { + public string from { get; set; } + public string to { get; set; } + public string location { get; set; } + public string content { get; set; } + } +} diff --git a/BiliDuang/DanmakuAss.cs b/BiliDuang/tools/DanmakuAss.cs similarity index 100% rename from BiliDuang/DanmakuAss.cs rename to BiliDuang/tools/DanmakuAss.cs