From f88208f68d4a9a608045c94861dded560df04d54 Mon Sep 17 00:00:00 2001 From: Leo Chen <1234567890chw@163.com> Date: Mon, 17 Jun 2019 14:10:40 +0800 Subject: [PATCH] =?UTF-8?q?[1.1.2.3]=201.=E4=BF=AE=E5=A4=8D=E4=BA=86?= =?UTF-8?q?=E6=A6=82=E7=8E=87=E6=80=A7=E5=9B=A0=E4=B8=BA=E5=AE=9A=E6=97=B6?= =?UTF-8?q?=E6=8A=95=E7=A8=BF=E4=BA=8B=E5=81=87=E6=8D=A2=E7=AE=97=E5=8F=AF?= =?UTF-8?q?=E8=83=BD=E5=AF=BC=E8=87=B4=E6=8A=95=E7=A8=BF=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82=202.=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E4=BA=86=E5=81=B6=E5=8F=91=E6=80=A7=E5=88=86=E7=89=87=E4=B8=8A?= =?UTF-8?q?=E4=BC=A0=E5=90=8E=E7=B3=BB=E7=BB=9F=E4=B8=8D=E8=AF=86=E5=88=AB?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BiliUploader/File2Base64Helper.cs | 4 +- BiliUploader/Program.cs | 21 +- BiliUploader/Properties/AssemblyInfo.cs | 4 +- BiliUploader/Uploader.cs | 337 +++++++++++++++--------- BiliUploader/app.config | 2 +- BiliUploader/compressor.cs | 76 ++++-- BiliUploader/http.cs | 3 - BiliUploader/variables.cs | 134 +++++----- 8 files changed, 363 insertions(+), 218 deletions(-) diff --git a/BiliUploader/File2Base64Helper.cs b/BiliUploader/File2Base64Helper.cs index 37f7814..2576c67 100644 --- a/BiliUploader/File2Base64Helper.cs +++ b/BiliUploader/File2Base64Helper.cs @@ -1,7 +1,7 @@ using System; using System.IO; -using System.Web; using System.Text; +using System.Web; namespace BiliUploader { @@ -84,7 +84,7 @@ public static string ImageToBase64(string filename) header = "data:image/png;base64,"; break; } - return HttpUtility.UrlEncode(header + Convert.ToBase64String(tmp),Encoding.UTF8); + return HttpUtility.UrlEncode(header + Convert.ToBase64String(tmp), Encoding.UTF8); } } diff --git a/BiliUploader/Program.cs b/BiliUploader/Program.cs index 1f26bf8..61edea9 100644 --- a/BiliUploader/Program.cs +++ b/BiliUploader/Program.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Threading.Tasks; using System.Windows.Forms; @@ -24,45 +23,59 @@ private static void Main(string[] args) case "-c"://cookies variables.CookiesString = args[++args_index]; break; + case "-ls"://list start IsList = true; break; + case "-le"://list end IsList = false; break; + case "-title": variables.Title = args[++args_index]; break; + case "-cover"://cover image variables.CoverFile = args[++args_index]; break; + case "-type"://type id variables.type = int.Parse(args[++args_index]); break; + case "-tags"://tags variables.tags = args[++args_index]; break; + case "-desc"://description variables.desc = args[++args_index]; break; + case "-dynamic"://dynamic variables.dynamic = args[++args_index]; break; + case "-dt"://publish time(if smaller than the submit time +4h, dt=st+4h) variables.dt = int.Parse(args[++args_index]); break; + case "-copyright": variables.copyright = int.Parse(args[++args_index]); break; + case "-mid": variables.mission_id = int.Parse(args[++args_index]); break; + case "-subtitle": variables.Subtitle = args[++args_index]; break; + case "-f": variables.IsIgnoreError = true; break; + case "-com": string[] settings = args[++args_index].Split(','); if (File.Exists("ffmpeg.exe")) @@ -85,15 +98,18 @@ private static void Main(string[] args) Console.Error.WriteLine("未找到ffmpeg,将不会对视频进行处理。"); } break; + case "-d": variables.IsDeleteTmp = true; break; + case "-h": case "-?": case "?": Console.WriteLine(Properties.Resources.helpstr); Console.ReadKey(); return; + default: if (IsList) { @@ -160,13 +176,12 @@ private static async Task UploadTask(int p) //视频压制 if (variables.IsCompress) { - variables.FileList[p-1] = await compressor.compress(variables.FileList[p - 1]); + variables.FileList[p - 1] = await compressor.compress(variables.FileList[p - 1]); } //上传 await new Uploader().DoUpload(variables.FileList[p - 1], p); } - #endregion Private Methods } } \ No newline at end of file diff --git a/BiliUploader/Properties/AssemblyInfo.cs b/BiliUploader/Properties/AssemblyInfo.cs index 68d3c62..d5df734 100644 --- a/BiliUploader/Properties/AssemblyInfo.cs +++ b/BiliUploader/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 // 方法是按如下所示使用“*”: : // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.1.1.2")] -[assembly: AssemblyFileVersion("1.1.1.2")] \ No newline at end of file +[assembly: AssemblyVersion("1.1.2.3")] +[assembly: AssemblyFileVersion("1.1.2.3")] \ No newline at end of file diff --git a/BiliUploader/Uploader.cs b/BiliUploader/Uploader.cs index d45c40b..eb44ca1 100644 --- a/BiliUploader/Uploader.cs +++ b/BiliUploader/Uploader.cs @@ -1,5 +1,4 @@ - -using Newtonsoft.Json; +using Newtonsoft.Json; using Newtonsoft.Json.Linq; using System; using System.Collections.Generic; @@ -38,6 +37,11 @@ internal class Uploader /// public string Auth { get; private set; } + /// + /// biz_id + /// + public string Biz_id { get; private set; } + /// /// 分片数 /// @@ -72,81 +76,6 @@ internal class Uploader #region Public Methods - /// - /// 执行上传 - /// - /// 文件路径 - /// 分Pid - public async Task DoUpload(string filename, int pid = 1) - { - Console.WriteLine("正在准备上传:P" + pid + "。"); - await Task.Run(() => - { - PreUpload(filename); - if (IsPreloadSucceed) - { - Console.WriteLine("开始上传:P" + pid + "。"); - //创建分片队列 - List> UploadQueue = new List>(); - int taskwaiting = ChunkCount; - while (taskwaiting > 0) - { - for (int i = 0; i < UploadQueue.Count; i++) - { - if (UploadQueue[i].IsCompleted) - { - if (UploadQueue[i].Result == false) - { - Console.Error.WriteLine("上传错误:P" + pid + "分片上传错误。"); - variables.IsHasError = true; - return; - } - else - { - UploadQueue.Remove(UploadQueue[i]); - } - } - } - - while (UploadQueue.Count < ThreadCount) - { - UploadQueue.Add(ChunkUpload(filename, pid, ChunkCount - taskwaiting)); - taskwaiting--; - } - } - - //等待所有分片上传 - foreach (Task task in UploadQueue) - { - if (task.Result == false) - { - Console.Error.WriteLine("上传错误:P" + pid + "分片上传错误。"); - variables.IsHasError = true; - return; - } - } - - fns = Key.Remove(0, 5); - fns = fns.Remove(fns.LastIndexOf('.')); - - variables.FileList[pid - 1] = fns; - Console.WriteLine("上传完成:P" + pid + "。"); - - //默认封面 - if (pid == 1 && variables.CoverFile == "") - { - Console.WriteLine("未设置稿件封面,将使用P1的第一张系统截图作为封面。"); - SetDefaultCover(); - } - } - else - { - Console.Error.WriteLine("上传错误:P" + pid + "上传预配置接口错误。"); - variables.IsHasError = true; - } - }); - } - /// /// 发布稿件 /// @@ -157,7 +86,7 @@ public static void Publish() if (!string.IsNullOrEmpty(str)) { JObject obj = JObject.Parse(str); - if((int)obj["code"] == 0 && (bool)obj["data"]["limit"]["add"] == false) + if ((int)obj["code"] == 0 && (bool)obj["data"]["limit"]["add"] == false) { //开始投稿 PublishInfo info = new PublishInfo() @@ -176,7 +105,7 @@ public static void Publish() subtitle = new SubtitleInfo() }; //添加分P列表 - for(int i = 0; i - /// 稿件信息模板 - /// - private class PublishInfo - { - public int copyright = 1; - public List videos; - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore),DefaultValue(-1)] - public int mission_id = -1; - public int no_reprint = 1; - public int tid; - public string cover; - public string title; - public string tag; - public int desc_format_id; - public string desc; - public string dynamic; - [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore),DefaultValue(-1)] - public int dtime ; - public SubtitleInfo subtitle; - } - - /// - /// 分p视频信息模板 - /// - private class VideoInfo - { - public string filename; - public string title; - public string desc = ""; - } - - private class SubtitleInfo - { - public int open = 0; - public string lan = ""; - } - /// /// 上传封面 /// @@ -281,10 +172,132 @@ public static void SetCover() Console.Error.WriteLine("上传封面错误!"); } + /// + /// 执行上传 + /// + /// 文件路径 + /// 分Pid + public async Task DoUpload(string filename, int pid = 1) + { + Console.WriteLine("正在准备上传:P" + pid + "。"); + await Task.Run(() => + { + PreUpload(filename); + if (IsPreloadSucceed) + { + Console.WriteLine("开始上传:P" + pid + "。"); + //创建分片队列 + List> UploadQueue = new List>(); + int taskwaiting = ChunkCount; + while (taskwaiting > 0) + { + for (int i = 0; i < UploadQueue.Count; i++) + { + if (UploadQueue[i].IsCompleted) + { + if (UploadQueue[i].Result == false) + { + Console.Error.WriteLine("上传错误:P" + pid + "分片上传错误。"); + variables.IsHasError = true; + return; + } + else + { + UploadQueue.Remove(UploadQueue[i]); + } + } + } + + while (UploadQueue.Count < ThreadCount && taskwaiting > 0) + { + UploadQueue.Add(ChunkUpload(filename, pid, ChunkCount - taskwaiting)); + taskwaiting--; + } + } + + //等待所有分片上传 + foreach (Task task in UploadQueue) + { + task.Wait(); + if (task.Result == false) + { + Console.Error.WriteLine("上传错误:P" + pid + "分片上传错误。"); + variables.IsHasError = true; + return; + } + } + + //完成分片上传 + if (variables.IsIgnoreError || !variables.IsHasError) + { + if (http.Options("https:" + EndPoint + Key + "?output=json&name=" + fi.Name + "&profile=ugcupos%2Fbup&uploadId=" + UploadId + "&biz_id=" + Biz_id, variables.Cookies)) + { + PartInfo pi = new PartInfo() + { + parts = new List() + }; + + for (int i = 1; i <= ChunkCount; i++) + { + pi.parts.Add(new ChunkInfo() { partNumber = i }); + } + + WebHeaderCollection headers = new WebHeaderCollection(); + headers.Add("X-Upos-Auth", Auth); + + string str = http.PostBody("https:" + EndPoint + Key + "?output=json&name=" + fi.Name + "&profile=ugcupos%2Fbup&uploadId=" + UploadId + "&biz_id=" + Biz_id, JsonConvert.SerializeObject(pi), variables.Cookies, "application/json; charset=utf-8", "", "", headers); + if (!string.IsNullOrEmpty(str)) + { + JObject obj = JObject.Parse(str); + if ((int)obj["OK"] == 1) + { + fns = Key.Remove(0, 5); + fns = fns.Remove(fns.LastIndexOf('.')); + + variables.FileList[pid - 1] = fns; + Console.WriteLine("上传完成:P" + pid + "。"); + } + else + { + Console.Error.WriteLine("上传错误:P" + pid + "上传错误。无法完成上传。"); + variables.IsHasError = true; + return; + } + } + else + { + Console.Error.WriteLine("上传错误:P" + pid + "上传错误。无法完成上传。"); + variables.IsHasError = true; + return; + } + } + else + { + Console.Error.WriteLine("上传错误:P" + pid + "上传错误。无法完成上传。"); + variables.IsHasError = true; + return; + } + } + + //默认封面 + if (pid == 1 && variables.CoverFile == "") + { + Console.WriteLine("未设置稿件封面,将使用P1的第一张系统截图作为封面。"); + SetDefaultCover(); + } + } + else + { + Console.Error.WriteLine("上传错误:P" + pid + "上传预配置接口错误。"); + variables.IsHasError = true; + } + }); + } + #endregion Public Methods #region Private Methods - + /// /// 获取formatid /// @@ -295,7 +308,7 @@ private static int GetFormatId() if (!string.IsNullOrEmpty(str)) { JObject obj = JObject.Parse(str); - if((int)obj["code"] == 0) + if ((int)obj["code"] == 0) { return obj["data"].HasValues ? (int)obj["data"]["id"] : -1; } @@ -386,6 +399,7 @@ private void PreUpload(string filename) ThreadCount = (int)obj["threads"]; ChunkSize = (int)obj["chunk_size"]; ChunkCount = fi.Length % ChunkSize == 0 ? (int)(fi.Length / ChunkSize) : (int)(fi.Length / ChunkSize) + 1; + Biz_id = obj["biz_id"].ToString(); Auth = obj["auth"].ToString(); if (http.Options("https:" + EndPoint + Key + "?uploads&output=json", variables.Cookies)) @@ -429,5 +443,88 @@ private void SetDefaultCover() } #endregion Private Methods + + #region Private Classes + + /// + /// 分片信息模板 + /// + private class ChunkInfo + { + #region Public Fields + + public string eTag = "etag"; + public int partNumber; + + #endregion Public Fields + } + + /// + /// 分片上传合并模板 + /// + private class PartInfo + { + #region Public Fields + + public List parts; + + #endregion Public Fields + } + + /// + /// 稿件信息模板 + /// + private class PublishInfo + { + #region Public Fields + + public int copyright = 1; + public string cover; + public string desc; + public int desc_format_id; + + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore), DefaultValue(-1)] + public int dtime; + + public string dynamic; + + [JsonProperty(DefaultValueHandling = DefaultValueHandling.Ignore), DefaultValue(-1)] + public int mission_id = -1; + + public int no_reprint = 1; + public SubtitleInfo subtitle; + public string tag; + public int tid; + public string title; + public List videos; + + #endregion Public Fields + } + + private class SubtitleInfo + { + #region Public Fields + + public string lan = ""; + public int open = 0; + + #endregion Public Fields + } + + /// + /// 分p视频信息模板 + /// + private class VideoInfo + { + #region Public Fields + + public string desc = ""; + public string filename; + public string title; + + #endregion Public Fields + } + + #endregion Private Classes } } \ No newline at end of file diff --git a/BiliUploader/app.config b/BiliUploader/app.config index 51278a4..2567682 100644 --- a/BiliUploader/app.config +++ b/BiliUploader/app.config @@ -1,3 +1,3 @@ - + \ No newline at end of file diff --git a/BiliUploader/compressor.cs b/BiliUploader/compressor.cs index 3ad384d..d1c5c12 100644 --- a/BiliUploader/compressor.cs +++ b/BiliUploader/compressor.cs @@ -1,14 +1,15 @@ using System; using System.Diagnostics; using System.IO; -using System.Threading; -using System.Threading.Tasks; using System.Text.RegularExpressions; +using System.Threading.Tasks; namespace BiliUploader { - class compressor + internal class compressor { + #region Public Methods + /// /// 压制函数 /// @@ -54,6 +55,25 @@ public static async Task compress(string filename) return "tmptoupload_" + new FileInfo(filename).Name; } + /// + /// 删除缓存文件 + /// + public static void DeleteTmp() + { + Regex reg = new Regex("tmptoupload_ *.*"); + foreach (string file in variables.FileList) + { + if (reg.IsMatch(file)) + { + File.Delete(file); + } + } + } + + #endregion Public Methods + + #region Private Methods + /// /// 执行压制 /// @@ -76,7 +96,8 @@ private static async Task DoCompress(string arguments) }; process.Start(); - await Task.Run(() =>{ + await Task.Run(() => + { while (!process.HasExited) { Console.WriteLine(process.StandardError.ReadToEnd()); @@ -127,54 +148,55 @@ private static void GetVideoInfo(string filename, ref VideoInfo info) } } + #endregion Private Methods + + #region Private Classes + /// /// 视频信息模板 /// private class VideoInfo { + #region Public Properties + /// - /// 视频宽 + /// 视频帧率 /// - public string Width { get; set; } + public string Fps { get; set; } + /// /// 视频高 /// public string Height { get; set; } + + /// + /// 视频码率 + /// + public string Rate { get; set; } + /// /// 宽高比 /// public string Scale { get; set; } + /// /// 宽高比宽 /// public string ScaleX { get; set; } + /// /// 宽高比高 /// public string ScaleY { get; set; } + /// - /// 视频帧率 - /// - public string Fps { get; set; } - /// - /// 视频码率 + /// 视频宽 /// - public string Rate { get; set; } - } + public string Width { get; set; } - /// - /// 删除缓存文件 - /// - public static void DeleteTmp() - { - Regex reg = new Regex("tmptoupload_ *.*"); - foreach (string file in variables.FileList) - { - if (reg.IsMatch(file)) - { - File.Delete(file); - } - } + #endregion Public Properties } + + #endregion Private Classes } -} +} \ No newline at end of file diff --git a/BiliUploader/http.cs b/BiliUploader/http.cs index a2e5be9..12917bf 100644 --- a/BiliUploader/http.cs +++ b/BiliUploader/http.cs @@ -102,8 +102,6 @@ public static string PostBody(string url, string data = "", CookieCollection coo sdata.Write(bdata, 0, bdata.Length); sdata.Close(); - - if (!string.IsNullOrEmpty(referer)) req.Referer = referer; if (!string.IsNullOrEmpty(user_agent)) req.UserAgent = user_agent; @@ -159,7 +157,6 @@ public static bool Options(string url, CookieCollection cookie = null, rep = (HttpWebResponse)req.GetResponse(); if (rep.StatusCode == HttpStatusCode.OK) result = true; - } finally { diff --git a/BiliUploader/variables.cs b/BiliUploader/variables.cs index 19b7070..6fd81ee 100644 --- a/BiliUploader/variables.cs +++ b/BiliUploader/variables.cs @@ -10,10 +10,31 @@ namespace BiliUploader /// internal class variables { + #region Public Fields + + /// + /// 版权信息 + /// + public static int copyright = 1; + + /// + /// 视频文件列表 + /// + public static List FileList = new List(); + + /// + /// 活动id + /// + public static int mission_id = -1; + + #endregion Public Fields #region Private Fields + private static string _CookiesString; + private static int _dt = -1; + #endregion Private Fields #region Public Properties @@ -23,8 +44,6 @@ internal class variables /// public static CookieCollection Cookies { get; private set; } - public static string csrf { get; private set; } - /// /// Cookies字符串 /// @@ -40,19 +59,39 @@ public static string CookiesString } /// - /// 指示是否忽略错误 + /// 封面图片 /// - public static bool IsIgnoreError { get; set; } + public static string CoverFile { get; set; } + + public static string csrf { get; private set; } /// - /// 指示是否出现错误 + /// 稿件简介 /// - public static bool IsHasError { get; set; } + public static string desc { get; set; } /// - /// 视频文件列表 + /// 投稿时间 /// - public static List FileList = new List(); + public static int dt + { + get + { + if (_dt != -1 && GetNowTimeStamp() + 14400 > _dt) return GetNowTimeStamp() + 14400; + else return _dt; + } + set { _dt = value; } + } + + /// + /// 动态 + /// + public static string dynamic { get; set; } + + /// + /// 指示视频是否压制 + /// + public static bool IsCompress { get; set; } /// /// 指示是否删除压制缓存 @@ -60,19 +99,19 @@ public static string CookiesString public static bool IsDeleteTmp { get; set; } /// - /// 稿件标题 + /// 指示是否出现错误 /// - public static string Title { get; set; } + public static bool IsHasError { get; set; } /// - /// 封面图片 + /// 指示是否忽略错误 /// - public static string CoverFile { get; set; } + public static bool IsIgnoreError { get; set; } /// - /// 分区id + /// 字幕语言 /// - public static int type { get; set; } + public static string Subtitle { get; set; } /// /// 标签 @@ -80,76 +119,38 @@ public static string CookiesString public static string tags { get; set; } /// - /// 稿件简介 - /// - public static string desc { get; set; } - - /// - /// 动态 + /// 稿件标题 /// - public static string dynamic { get; set; } + public static string Title { get; set; } /// - /// 视频处理大小 + /// 分区id /// - public static string v_size { get; set; } + public static int type { get; set; } /// /// 视频处理帧数 /// public static string v_fps { get; set; } - /// - /// 视频处理码率 - /// - public static string v_rate { get; set; } /// /// 视频处理最高码率 /// public static string v_maxrate { get; set; } /// - /// 指示视频是否压制 + /// 视频处理码率 /// - public static bool IsCompress { get; set; } + public static string v_rate { get; set; } /// - /// 版权信息 - /// - public static int copyright = 1; - /// - /// 活动id + /// 视频处理大小 /// - public static int mission_id = -1; - - private static int _dt = -1; + public static string v_size { get; set; } - /// - /// 投稿时间 - /// - public static int dt { - get { - if (_dt != -1 && GetNowTimeStamp() + 14400 > _dt) return GetNowTimeStamp() + 14400; - else return _dt; - } - set { _dt = value; } - } #endregion Public Properties #region Public Methods - /// - /// 字幕语言 - /// - public static string Subtitle { get; set; } - - /// - /// 获取当前时间戳 - /// - /// - private static int GetNowTimeStamp() - { - return (int)(DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000; - } /// /// 设置Cookies @@ -180,5 +181,18 @@ public static CookieCollection SetCookies(string cookiestr) } #endregion Public Methods + + #region Private Methods + + /// + /// 获取当前时间戳 + /// + /// + private static int GetNowTimeStamp() + { + return (int)((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000); + } + + #endregion Private Methods } } \ No newline at end of file