/// <summary> /// 获取番剧播放信息 /// </summary> /// <param name="aid">番剧类型标识</param> /// <param name="cid">视频分Pid</param> /// <param name="qn">分辨率ID</param> /// <returns></returns> public async Task <VideoPlayBase> GetBangumiPlayAsync(int type, int cid, int qn = 64) { var param = new Dictionary <string, string>(); param.Add("module", "bangumi"); param.Add("season_type", type.ToString()); param.Add("cid", cid.ToString()); param.Add("qn", qn.ToString()); param.Add("fnver", "0"); param.Add("otype", "json"); param.Add("fnval", "16"); string url = BiliTool.UrlContact(Api.ANIME_PLAY, param, true, true); var data = await BiliTool.GetTextFromWebAsync(url); if (!string.IsNullOrEmpty(data)) { var jobj = JObject.Parse(data); if (jobj.ContainsKey("dash")) { return(JsonConvert.DeserializeObject <VideoPlayDash>(data)); } else if (jobj.ContainsKey("durl")) { return(JsonConvert.DeserializeObject <VideoPlayFlv>(data)); } } return(null); }
/// <summary> /// 获取动漫索引筛查结果 /// </summary> /// <param name="page">页码</param> /// <param name="type">分区类型</param> /// <param name="conditions">限制条件</param> /// <returns></returns> public async Task <Tuple <bool, List <AnimeIndexResult> > > GetBangumiIndexResultsAsync(int page, int type, List <KeyValueModel> conditions) { var param = new Dictionary <string, string>(); foreach (var item in conditions) { param.Add(item.Key, item.Value); } param.Add("type", "0"); param.Add("page", page.ToString()); param.Add("season_type", type.ToString()); param.Add("pagesize", "21"); string url = BiliTool.UrlContact(Api.ANIME_INDEX_RESULT, param, true); var response = await BiliTool.GetTextFromWebAsync(url); try { if (!string.IsNullOrEmpty(response)) { var jobj = JObject.Parse(response); bool hasNext = jobj["has_next"].ToString() == "1"; var data = JsonConvert.DeserializeObject <List <AnimeIndexResult> >(jobj["list"].ToString()); return(new Tuple <bool, List <AnimeIndexResult> >(hasNext, data)); } } catch (Exception) { } return(null); }
/// <summary> /// 获取历史动态 /// </summary> /// <param name="offset">偏移值,初次不需要,每次请求会返回下一次请求的偏移值</param> /// <returns>Item1:下次偏移值;Item2:动态列表</returns> public async Task <Tuple <string, List <Topic> > > GetHistoryDynamicAsync(string offset) { var param = new Dictionary <string, string>(); param.Add("qn", "32"); param.Add("uid", BiliTool.mid); param.Add("offset_dynamic_id", offset); param.Add("rsp_type", "2"); param.Add("type_list", "268435455"); string url = BiliTool.UrlContact(Api.DYNAMIC_HISTORY, param, true); var data = await BiliTool.GetTextFromWebAsync(url); if (!string.IsNullOrEmpty(data)) { try { var jobj = JObject.Parse(data); string nextOffset = jobj["next_offset"].ToString(); var topics = JsonConvert.DeserializeObject <List <Topic> >(jobj["cards"].ToString()); topics.RemoveAll(p => p == null || p.card == null || p.card.Length < 10 || p.desc.status != 1); return(new Tuple <string, List <Topic> >(nextOffset, topics)); } catch (Exception) { } } return(null); }
/// <summary> /// 获取频道下的视频信息 /// </summary> /// <param name="channelId">频道ID</param> /// <param name="sort">排序方式,可选值(hot,view,new)</param> /// <param name="offset">偏移值,初次不需要,每次请求会返回下一次请求的偏移值</param> /// <returns>Item1:下次偏移值;Item2:榜一视频(如果有);Item3:视频列表</returns> public async Task <Tuple <string, VideoBase, List <VideoChannel> > > GetChannelVideosAsync(int channelId, string sort = "hot", string offset = "") { var param = new Dictionary <string, string>(); param.Add("channel_id", channelId.ToString()); param.Add("sort", sort); if (!string.IsNullOrEmpty(offset)) { param.Add("offset", offset); } string url = BiliTool.UrlContact(Api.CHANNEL_VIDEO, param, true); string content = await BiliTool.GetTextFromWebAsync(url, true); if (!string.IsNullOrEmpty(content)) { var jobj = JObject.Parse(content); if (jobj["code"].ToString() == "0") { var items = jobj["data"]["items"]; string nextOffset = jobj.SelectToken("data.offset").ToString(); VideoBase rankFirst = null; if (items.First()["goto"].ToString() == "channel_detail_rank") { rankFirst = JsonConvert.DeserializeObject <VideoBase>(items.First().SelectToken("items[0]").ToString()); } var videoList = JsonConvert.DeserializeObject <List <VideoChannel> >(items.ToString()); videoList.RemoveAll(p => p.@goto != "av"); return(new Tuple <string, VideoBase, List <VideoChannel> >(nextOffset, rankFirst, videoList)); } } return(null); }
/// <summary> /// 获取用户空间历史动态 /// </summary> /// <param name="uid">要查看的用户ID</param> /// <param name="page">页码</param> /// <param name="offset_id">偏移值,初次不需要,每次请求会返回下一次请求的偏移值</param> /// <returns>Item1:下次偏移值;Item2:动态列表</returns> public async Task <Tuple <string, List <Topic> > > GetUserSpaceDynamicAsync(int uid, int page = 1, string offset_id = "0") { var param = new Dictionary <string, string>(); param.Add("host_uid", uid.ToString()); param.Add("qn", "32"); if (!string.IsNullOrEmpty(BiliTool.mid)) { param.Add("visitor_uid", BiliTool.mid); } param.Add("offset_dynamic_id", offset_id); param.Add("page", page.ToString()); string url = BiliTool.UrlContact(Api.DYNAMIC_USER_HISTORY, param, true); var data = await BiliTool.GetTextFromWebAsync(url); if (!string.IsNullOrEmpty(data)) { try { var jobj = JObject.Parse(data); string nextOffset = jobj["next_offset"].ToString(); var topics = JsonConvert.DeserializeObject <List <Topic> >(jobj["cards"].ToString()); topics.RemoveAll(p => p == null || p.card == null || p.card.Length < 10 || p.desc.status != 1); return(new Tuple <string, List <Topic> >(nextOffset, topics)); } catch (Exception) { } } return(null); }
/// <summary> /// 转发动态 /// </summary> /// <param name="content">附加内容</param> /// <param name="dynamicId">被转发动态ID</param> /// <param name="rid">被转发动态评论ID</param> /// <param name="type">被转发动态类型</param> /// <param name="atIds">at的人</param> /// <returns></returns> public async Task <bool> RepostDynamicAsync(string content, string dynamicId, string rid, int type, List <RepostLocation> atIds) { if (atIds == null) { atIds = new List <RepostLocation>(); } var param = new Dictionary <string, string>(); param.Add("content", Uri.EscapeDataString(content)); param.Add("at_uids", string.Join(',', atIds.Select(p => p.data))); param.Add("ctrl", Uri.EscapeDataString(JsonConvert.SerializeObject(atIds))); param.Add("dynamic_id", dynamicId); param.Add("rid", rid); param.Add("repost_code", "10000"); param.Add("sync_comment", "0"); param.Add("spec_type", "0"); param.Add("type", type.ToString()); param.Add("uid", BiliTool.mid.ToString()); param.Add("extension", Uri.EscapeDataString("{\"emoji_type\":1}")); param.Add("statistics", Uri.EscapeDataString("{\"appId\":1,\"version\":\"5.56.1\",\"abtest\":\"\",\"platform\":1}")); var req = BiliTool.UrlContact("", param, true); var response = await BiliTool.PostContentToWebAsync(Api.DYNAMIC_REPOST, req); if (!string.IsNullOrEmpty(response)) { var jobj = JObject.Parse(response); return(jobj["code"].ToString() == "0"); } return(false); }
/// <summary> /// 设置动态点赞状态 /// </summary> /// <param name="isLike">是否点赞</param> /// <param name="dynamicId">动态ID</param> /// <param name="rid">动态里的参数</param> /// <param name="uid">用户ID</param> /// <returns></returns> public async Task <bool> SetDynamicLikeStatus(bool isLike, string dynamicId, string rid, string uid) { if (string.IsNullOrEmpty(uid) || string.IsNullOrEmpty(dynamicId) || string.IsNullOrEmpty(rid)) { return(false); } var param = new Dictionary <string, string>(); param.Add("dynamic_id", dynamicId); param.Add("rid", rid); param.Add("uid", uid); param.Add("up", isLike ? "1" : "2"); var data = BiliTool.UrlContact("", param, true); var response = await BiliTool.PostContentToWebAsync(Api.DYNAMIC_LIKE, data); if (!string.IsNullOrEmpty(response)) { var jobj = JObject.Parse(response); if (jobj["code"].ToString() == "0") { return(true); } } return(false); }
/// <summary> /// 转发视频 /// </summary> /// <param name="content">转发内容</param> /// <param name="videoId">视频ID</param> /// <param name="atIds">At的人</param> /// <returns></returns> public async Task <bool> RepostVideoAsync(string content, int videoId, List <RepostLocation> atIds) { var param = new Dictionary <string, string>(); param.Add("content", Uri.EscapeDataString(content)); param.Add("at_uids", string.Join(',', atIds.Select(p => p.data))); param.Add("ctrl", Uri.EscapeDataString(JsonConvert.SerializeObject(atIds))); param.Add("share_uid", BiliTool.mid.ToString()); param.Add("rid", videoId.ToString()); param.Add("type", "8"); param.Add("repost_code", "20000"); param.Add("sync_comment", "0"); param.Add("sketch", ""); param.Add("uid", "0"); param.Add("share_info", ""); param.Add("extension", Uri.EscapeDataString("{\"emoji_type\":1}")); param.Add("statistics", Uri.EscapeDataString("{\"appId\":1,\"version\":\"5.56.1\",\"abtest\":\"\",\"platform\":1}")); var req = BiliTool.UrlContact("", param, true); var response = await BiliTool.PostContentToWebAsync(Api.VIDEO_REPOST, req); if (!string.IsNullOrEmpty(response)) { var jobj = JObject.Parse(response); return(jobj["code"].ToString() == "0"); } return(false); }
/// <summary> /// 不喜欢某视频 /// </summary> /// <param name="arg">参数</param> /// <param name="reason_id">原因ID</param> /// <param name="go">类型</param> /// <param name="isFeedback">标识是反馈还是不感兴趣</param> /// <returns></returns> public async Task <bool> DislikeRecommendVideoAsync(Args arg, int reason_id, string go, bool isFeedback = false) { var param = new Dictionary <string, string>(); param.Add("id", arg.aid.ToString()); param.Add("rid", arg.rid.ToString()); if (isFeedback) { param.Add("feedback_id", reason_id.ToString()); } else { param.Add("reason_id", reason_id.ToString()); } param.Add("goto", go); param.Add("mid", arg.up_id.ToString()); param.Add("tag_id", arg.tid.ToString()); var url = BiliTool.UrlContact(Api.VIDEO_RECOMMEND_DISLIKE, param, true); var response = await BiliTool.GetTextFromWebAsync(url, true); if (!string.IsNullOrEmpty(response)) { var jobj = JObject.Parse(response); return(jobj["code"].ToString() == "0"); } return(false); }
/// <summary> /// 获取频道分类索引 /// </summary> /// <returns></returns> public async Task <List <ChannelTab> > GetChannelTabsAsync() { var url = BiliTool.UrlContact(Api.CHANNEL_TABS, hasAccessKey: true); var data = await BiliTool.ConvertEntityFromWebAsync <List <ChannelTab> >(url); return(data); }
/// <summary> /// 获取我收藏的播单(最多20个) /// </summary> /// <returns>Item1: 我创建的;Item2: 我收藏的</returns> public async Task <Tuple <List <FavoriteItem>, List <FavoriteItem> > > GetMyMainlyFavoritesAsync() { var param = new Dictionary <string, string>(); param.Add("up_mid", _userId); string url = BiliTool.UrlContact(Api.ACCOUNT_MEDIALIST, param, true); string response = await BiliTool.GetTextFromWebAsync(url); try { var jarr = JArray.Parse(response); bool hasMy = jarr[0]["mediaListResponse"] != null; bool hasOther = jarr[1]["mediaListResponse"] != null; var myList = new List <FavoriteItem>(); var otherList = new List <FavoriteItem>(); if (hasMy) { myList = JsonConvert.DeserializeObject <List <FavoriteItem> >(jarr[0].SelectToken("mediaListResponse.list").ToString()); } if (hasOther) { otherList = JsonConvert.DeserializeObject <List <FavoriteItem> >(jarr[1].SelectToken("mediaListResponse.list").ToString()); } return(new Tuple <List <FavoriteItem>, List <FavoriteItem> >(myList, otherList)); } catch (Exception) { return(null); } }
/// <summary> /// 获取动漫区块综合信息 /// </summary> /// <param name="isJp"><c>true</c>代表番剧,<c>false</c>代表国创</param> /// <returns></returns> public async Task <List <AnimeModule> > GetAnimeSquareAsync(bool isJp = true) { string api = isJp ? Api.ANIME_JP_SQUARE : Api.ANIME_CHN_SQUARE; var url = BiliTool.UrlContact(api, null, true); return(await BiliTool.ConvertEntityFromWebAsync <List <AnimeModule> >(url, "result.modules")); }
/// <summary> /// 获取分区索引 /// </summary> /// <returns></returns> public async Task <List <RegionContainer> > GetRegionIndexAsync() { string url = BiliTool.UrlContact(Api.REGION_INDEX); var result = await BiliTool.ConvertEntityFromWebAsync <List <RegionContainer> >(url); return(result); }
/// <summary> /// 清空观看历史记录 /// </summary> /// <returns></returns> public async Task <bool> ClearHistoryAsync() { string url = BiliTool.UrlContact(Api.ACCOUNT_HISTORY_CLEAR, null, true); string content = await BiliTool.PostContentToWebAsync(url, ""); return(content != null); }
/// <summary> /// 加密密码 /// </summary> /// <param name="password">密码</param> /// <returns></returns> private async Task <string> EncryptedPasswordAsync(string password) { string base64String; try { string param = BiliTool.UrlContact("").TrimStart('?'); string content = await BiliTool.PostContentToWebAsync(Api.PASSPORT_KEY_ENCRYPT, param); JObject jobj = JObject.Parse(content); string str = jobj["data"]["hash"].ToString(); string str1 = jobj["data"]["key"].ToString(); string str2 = string.Concat(str, password); string str3 = Regex.Match(str1, "BEGIN PUBLIC KEY-----(?<key>[\\s\\S]+)-----END PUBLIC KEY").Groups["key"].Value.Trim(); byte[] numArray = Convert.FromBase64String(str3); AsymmetricKeyAlgorithmProvider asymmetricKeyAlgorithmProvider = AsymmetricKeyAlgorithmProvider.OpenAlgorithm(AsymmetricAlgorithmNames.RsaPkcs1); CryptographicKey cryptographicKey = asymmetricKeyAlgorithmProvider.ImportPublicKey(WindowsRuntimeBufferExtensions.AsBuffer(numArray), 0); IBuffer buffer = CryptographicEngine.Encrypt(cryptographicKey, WindowsRuntimeBufferExtensions.AsBuffer(Encoding.UTF8.GetBytes(str2)), null); base64String = Convert.ToBase64String(WindowsRuntimeBufferExtensions.ToArray(buffer)); } catch (Exception) { base64String = password; } return(base64String); }
/// <summary> /// 获取账户的未读消息 /// </summary> /// <returns></returns> public async Task <MyMessage> GetMyUnreadMessageAsync() { string url = BiliTool.UrlContact(Api.ACCOUNT_UNREAD, null, true); var data = await BiliTool.ConvertEntityFromWebAsync <MyMessage>(url); return(data); }
/// <summary> /// 添加评论 /// </summary> /// <param name="oid">源ID</param> /// <param name="message">信息</param> /// <param name="type">类型</param> /// <returns></returns> public async Task <Reply> AddReplyAsync(string oid, string message, string parentId, string rootId, string type = "1") { var param = new Dictionary <string, string>(); param.Add("oid", oid); param.Add("parent", parentId); param.Add("root", rootId); param.Add("type", type); param.Add("message", Uri.EscapeDataString(message)); param.Add("lottery", "0"); param.Add("vote", "0"); var data = BiliTool.UrlContact("", param, true); try { string response = await BiliTool.PostContentToWebAsync(Api.REPLY_ADD, data); var jobj = JObject.Parse(response); if (jobj.ContainsKey("data")) { return(JsonConvert.DeserializeObject <Reply>(jobj["data"]["reply"].ToString())); } } catch (Exception) { } return(null); }
/// <summary> /// 操作收藏夹 /// </summary> /// <param name="aid">视频ID</param> /// <param name="addIds">添加的收藏夹ID列表</param> /// <param name="delIds">移出的收藏夹ID列表</param> /// <returns></returns> public async Task <bool> AddVideoToFavoriteAsync(int aid, List <string> addIds, List <string> delIds) { if (addIds.Count == 0 && delIds.Count == 0) { return(false); } var param = new Dictionary <string, string>(); param.Add("rid", aid.ToString()); param.Add("type", "2"); if (addIds.Count > 0) { param.Add("add_media_ids", string.Join(',', addIds)); } else if (delIds.Count > 0) { param.Add("del_media_ids", string.Join(',', delIds)); } var result = await BiliTool.PostContentToWebAsync(Api.VIDEO_FAVORITE, BiliTool.UrlContact("", param, true)); if (!string.IsNullOrEmpty(result)) { var jobj = JObject.Parse(result); return(jobj["code"].ToString() == "0"); } return(false); }
/// <summary> /// 清空稍后观看列表 /// </summary> /// <returns></returns> public async Task <bool> ClearViewLaterAsync() { string url = BiliTool.UrlContact(Api.ACCOUNT_VIEWLATER_CLEAR, null, true); string content = await BiliTool.PostContentToWebAsync(url, ""); return(content != null); }
/// <summary> /// 获取我的个人信息 /// </summary> /// <returns></returns> public async Task <Me> GetMeAsync() { var url = BiliTool.UrlContact(Api.ACCOUNT_MINE, hasAccessKey: true); var data = await BiliTool.ConvertEntityFromWebAsync <Me>(url); Me = data; BiliTool.mid = _userId = data.mid.ToString(); return(data); }
/// <summary> /// 获取表情包 /// </summary> /// <returns></returns> public async Task <List <EmojiReplyContainer> > GetUserEmojiAsync() { var param = new Dictionary <string, string>(); param.Add("business", "reply"); string url = BiliTool.UrlContact(Api.ACCOUNT_EMOJI_PANEL, param, true); var items = await BiliTool.ConvertEntityFromWebAsync <List <EmojiReplyContainer> >(url, "data.packages"); return(items); }
/// <summary> /// 获取区块刷新信息 /// </summary> /// <param name="type">类型</param> /// <param name="moduleId">模块ID</param> /// <returns></returns> public async Task <List <AnimeModuleItem> > GetAnimeSectionExchange(int type, int moduleId) { var param = new Dictionary <string, string>(); param.Add("type", type.ToString()); param.Add("oid", moduleId.ToString()); string url = BiliTool.UrlContact(Api.ANIME_EXCHANGE, param, true); return(await BiliTool.ConvertEntityFromWebAsync <List <AnimeModuleItem> >(url, "result")); }
/// <summary> /// 获取视频简易信息 /// </summary> /// <param name="aid">视频avid</param> /// <returns></returns> public async Task <VideoSlim> GetVideoSlimAsync(int aid) { var param = new Dictionary <string, string>(); param.Add("aid", aid.ToString()); string url = BiliTool.UrlContact(Api.VIDEO_SLIM_INFO, param, true); var data = await BiliTool.ConvertEntityFromWebAsync <VideoSlim>(url); return(data); }
/// <summary> /// 获取标签信息 /// </summary> /// <param name="tagId">标签ID</param> /// <returns></returns> public async Task <ChannelTag> GetTagDetail(int tagId) { var param = new Dictionary <string, string>(); param.Add("channel_id", tagId.ToString()); string url = BiliTool.UrlContact(Api.CHANNEL_TAG_TAB, param, true); var data = await BiliTool.ConvertEntityFromWebAsync <ChannelTag>(url); return(data); }
/// <summary> /// 获取用户空间信息(经过删减) /// </summary> /// <param name="uid">用户ID</param> /// <returns></returns> public async Task <UserResponse> GetUserSpaceAsync(int uid) { var param = new Dictionary <string, string>(); param.Add("vmid", uid.ToString()); string url = BiliTool.UrlContact(Api.ACCOUNT_USER_SPACE, param, true); var data = await BiliTool.ConvertEntityFromWebAsync <UserResponse>(url); return(data); }
/// <summary> /// 获取视频相关 /// </summary> /// <param name="aid">视频avid</param> /// <returns></returns> public async Task <List <VideoDetail> > GetVideoRelatedAsync(int aid) { var param = new Dictionary <string, string>(); param.Add("aid", aid.ToString()); string url = BiliTool.UrlContact(Api.VIDEO_RELATED, param, true); var data = await BiliTool.ConvertEntityFromWebAsync <List <VideoDetail> >(url); return(data); }
/// <summary> /// 获取回复我的列表 /// </summary> /// <param name="replyTime">偏移值(上次请求的底部时间戳)</param> /// <returns></returns> public async Task <FeedReplyResponse> GetReplyMeListAsync(int replyTime = 0) { var param = new Dictionary <string, string>(); param.Add("reply_time", replyTime.ToString()); string url = BiliTool.UrlContact(Api.ACCOUNT_FEEDBACK_REPLY, param, true); var response = await BiliTool.ConvertEntityFromWebAsync <FeedReplyResponse>(url); return(response); }
/// <summary> /// 获取我的关注的分组 /// </summary> /// <returns></returns> public async Task <List <FollowTag> > GetMyFollowTagsAsync() { var param = new Dictionary <string, string>(); param.Add("vmid", BiliTool.mid); string url = BiliTool.UrlContact(Api.ACCOUNT_RELATION_FOLLOW_TAGS, param, true); var data = await BiliTool.ConvertEntityFromWebAsync <List <FollowTag> >(url); return(data); }
/// <summary> /// 获取视频分P /// </summary> /// <param name="aid">视频avid</param> /// <returns></returns> public async Task <List <VideoPart> > GetVideoPartsAsync(int aid) { var param = new Dictionary <string, string>(); param.Add("aid", aid.ToString()); string url = BiliTool.UrlContact(Api.VIDEO_PART, param, true); var parts = await BiliTool.ConvertEntityFromWebAsync <List <VideoPart> >(url); return(parts); }
/// <summary> /// 转发动漫/电影/电视剧等 /// </summary> /// <param name="content">转发内容</param> /// <param name="videoId">视频ID</param> /// <param name="atIds">At的人</param> /// <param name="typeName">番剧:4097,影视:4098,电视剧:4099,国创:4100</param> /// <returns></returns> public async Task <bool> RepostBangumiAsync(string content, int epId, string typeName, List <RepostLocation> atIds) { var param = new Dictionary <string, string>(); string type = ""; switch (typeName) { case "番剧": type = "4097"; break; case "影视": type = "4098"; break; case "电视剧": case "综艺": type = "4099"; break; case "国创": type = "4100"; break; case "纪录片": type = "4101"; break; default: type = "4097"; break; } param.Add("content", Uri.EscapeDataString(content)); param.Add("at_uids", string.Join(',', atIds.Select(p => p.data))); param.Add("ctrl", Uri.EscapeDataString(JsonConvert.SerializeObject(atIds))); param.Add("share_uid", BiliTool.mid.ToString()); param.Add("rid", epId.ToString()); param.Add("type", type); param.Add("repost_code", "20000"); param.Add("sync_comment", "0"); param.Add("sketch", ""); param.Add("uid", "0"); param.Add("share_info", ""); param.Add("extension", Uri.EscapeDataString("{\"emoji_type\":1}")); param.Add("statistics", Uri.EscapeDataString("{\"appId\":1,\"version\":\"5.56.1\",\"abtest\":\"\",\"platform\":1}")); var req = BiliTool.UrlContact("", param, true); var response = await BiliTool.PostContentToWebAsync(Api.VIDEO_REPOST, req); if (!string.IsNullOrEmpty(response)) { var jobj = JObject.Parse(response); return(jobj["code"].ToString() == "0"); } return(false); }