1. 添加了上游代理支持,现在可以将无关的请求转发到其他的代理地址!详见下方配置说明upstreamProxy

2. 内部添加了webRoomid 的缓存映射,只要打开直播间地址即可缓存WebRoomId和Roomid的映射关系,`WebRoomId`现已添加至ws弹幕流数据中!,需要注意直播伴侣端提取的弹幕当前不会有该字段,除非在开播后打开浏览器访问一次你的直播间
3. MsgPack 现在添加了进程名字段`ProcessName`
This commit is contained in:
小白猿
2023-09-24 12:47:55 +08:00
parent 00b929b83f
commit a39e2c4f96
10 changed files with 1008 additions and 194 deletions
@@ -3,7 +3,7 @@
/// <summary>
/// 弹幕消息类型
/// </summary>
public enum BarrageMsgType
public enum PackMsgType
{
无 = 0,
弹幕消息 = 1,
@@ -50,7 +50,12 @@
/// <summary>
/// 消息类型
/// </summary>
public BarrageMsgType Type { get; set; }
public PackMsgType Type { get; set; }
/// <summary>
/// 进程名
/// </summary>
public string ProcessName { get; set; }
/// <summary>
/// 消息对象
@@ -62,10 +67,11 @@
}
public BarrageMsgPack(string data, BarrageMsgType type)
public BarrageMsgPack(string data, PackMsgType type,string processName)
{
Data = data;
Type = type;
ProcessName = processName;
}
}
@@ -93,6 +99,11 @@
/// 房间号
/// </summary>
public long RoomId { get; set; }
/// <summary>
/// web直播间ID
/// </summary>
public long WebRoomId { get; set; }
}
/// <summary>
+576
View File
@@ -0,0 +1,576 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
namespace BarrageGrab.Modles
{
[Serializable]
public class RoomInfo
{
/// <summary>
/// Web房间号
/// </summary>
public string WebRoomId { get; set; }
/// <summary>
/// 房间号
/// </summary>
public string RoomId { get; set; }
/// <summary>
/// 直播间名称
/// </summary>
public string Title { get; set; }
/// <summary>
/// 是否直播中
/// </summary>
public bool IsLive { get; set; }
/// <summary>
/// 实时在线人数
/// </summary>
public long UserCount { get; set; }
/// <summary>
/// 累计在线人数
/// </summary>
public string TotalUserCount { get; set; }
/// <summary>
/// 点赞数
/// </summary>
public long LikeCount { get; set; }
/// <summary>
/// 直播间二维码图像链接
/// </summary>
public string QrcodeUrl { get; set; }
/// <summary>
/// 直播间地址
/// </summary>
public string LiveUrl { get; set; }
/// <summary>
/// 封面链接
/// </summary>
public string Cover { get; set; }
/// <summary>
/// 直播间管理员用户id
/// </summary>
public List<string> AdminUserIds { get; set; } = new List<string>();
/// <summary>
/// 主播信息
/// </summary>
public RoomAnchor Owner { get; set; }
/// <summary>
/// 直播间的一些配置
/// </summary>
public RoomAuth AuthInfo { get; set; }
/// <summary>
/// 自身信息,Api方式没有
/// </summary>
public OdinData Odin { get; set; }
/// <summary>
/// Response请求头设置的 Ttwid,Api方式没有
/// </summary>
public string Ttwid { get; set; }
public class RoomAnchor
{
/// <summary>
/// 用户ID
/// </summary>
public string UserId { get; set; }
/// <summary>
/// SecUid
/// </summary>
public string SecUid { get; set; }
/// <summary>
/// 昵称
/// </summary>
public string Nickname { get; set; }
/// <summary>
/// 头像地址
/// </summary>
public string HeadUrl { get; set; }
/// <summary>
/// 关注状态 0未关注,1已关注,...
/// </summary>
public int FollowStatus { get; set; }
}
public class RoomAuth
{
/// <summary>
/// 是否允许聊天
/// </summary>
public bool Chat { get; set; }
/// <summary>
/// 是否允许弹幕
/// </summary>
public bool Danmaku { get; set; }
/// <summary>
/// 是否允许送礼物
/// </summary>
public bool Gift { get; set; }
/// <summary>
/// 是否允许发红包
/// </summary>
public bool LuckMoney { get; set; }
/// <summary>
/// 是否允许点赞
/// </summary>
public bool Digg { get; set; }
/// <summary>
/// 是否允许房间贡献者
/// </summary>
public bool RoomContributor { get; set; }
/// <summary>
/// 是否允许使用道具
/// </summary>
public bool Props { get; set; }
/// <summary>
/// 是否允许查看用户名片
/// </summary>
public bool UserCard { get; set; }
/// <summary>
/// 是否允许查看 POI
/// </summary>
public bool POI { get; set; }
/// <summary>
/// 更多主播?
/// </summary>
public int MoreAnchor { get; set; }
/// <summary>
/// banner?
/// </summary>
public int Banner { get; set; }
/// <summary>
/// 分享配置?
/// </summary>
public int Share { get; set; }
/// <summary>
/// 用户角标?
/// </summary>
public int UserCorner { get; set; }
/// <summary>
/// 横屏?
/// </summary>
public int Landscape { get; set; }
/// <summary>
/// 横屏聊天?
/// </summary>
public int LandscapeChat { get; set; }
/// <summary>
/// 公屏?
/// </summary>
public int PublicScreen { get; set; }
/// <summary>
/// 礼物主播魔法表情配置?
/// </summary>
public int GiftAnchorMt { get; set; }
/// <summary>
/// 录屏配置?
/// </summary>
public int RecordScreen { get; set; }
/// <summary>
/// 打赏贴纸配置?
/// </summary>
public int DonationSticker { get; set; }
/// <summary>
/// 小时榜配置?
/// </summary>
public int HourRank { get; set; }
/// <summary>
/// 商务名片配置?
/// </summary>
public int CommerceCard { get; set; }
/// <summary>
/// 语音聊天配置?
/// </summary>
public int AudioChat { get; set; }
/// <summary>
/// 弹幕默认开关
/// </summary>
public int DanmakuDefault { get; set; }
/// <summary>
/// KTV 点歌?
/// </summary>
public int KtvOrderSong { get; set; }
/// <summary>
/// 选集?
/// </summary>
public int SelectionAlbum { get; set; }
/// <summary>
/// 点赞?
/// </summary>
public int Like { get; set; }
/// <summary>
/// 倍速播放?
/// </summary>
public int MultiplierPlayback { get; set; }
/// <summary>
/// 下载视频?
/// </summary>
public int DownloadVideo { get; set; }
/// <summary>
/// 收藏?
/// </summary>
public int Collect { get; set; }
/// <summary>
/// 定时下播?
/// </summary>
public int TimedShutdown { get; set; }
/// <summary>
/// 快进?
/// </summary>
public int Seek { get; set; }
/// <summary>
/// 举报?
/// </summary>
public int Denounce { get; set; }
/// <summary>
/// 踩?
/// </summary>
public int Dislike { get; set; }
/// <summary>
/// 只看 TA?
/// </summary>
public int OnlyTa { get; set; }
/// <summary>
/// 投屏?
/// </summary>
public int CastScreen { get; set; }
/// <summary>
/// 评论墙?
/// </summary>
public int CommentWall { get; set; }
/// <summary>
/// 弹幕样式
/// </summary>
public object BulletStyle { get; set; }
/// <summary>
/// 显示游戏插件?
/// </summary>
public int ShowGamePlugin { get; set; }
/// <summary>
/// PK礼物?
/// </summary>
public int VSGift { get; set; }
/// <summary>
/// PK话题?
/// </summary>
public int VSTopic { get; set; }
/// <summary>
/// PK排行榜?
/// </summary>
public int VSRank { get; set; }
/// <summary>
/// 管理员评论墙?
/// </summary>
public int AdminCommentWall { get; set; }
/// <summary>
/// 商务组件?
/// </summary>
public int CommerceComponent { get; set; }
/// <summary>
/// 抖音会员?
/// </summary>
public int DouPlus { get; set; }
/// <summary>
/// 游戏积分玩法?
/// </summary>
public int GamePointsPlaying { get; set; }
/// <summary>
/// 海报?
/// </summary>
public int Poster { get; set; }
/// <summary>
/// 精彩时刻?
/// </summary>
public int Highlights { get; set; }
/// <summary>
/// 打字评论状态?
/// </summary>
public int TypingCommentState { get; set; }
/// <summary>
/// 上下滑动引导?
/// </summary>
public int StrokeUpDownGuide { get; set; }
/// <summary>
/// 右上角统计浮层?
/// </summary>
public int UpRightStatsFloatingLayer { get; set; }
/// <summary>
/// 投屏显式?
/// </summary>
public int CastScreenExplicit { get; set; }
/// <summary>
/// 选集?
/// </summary>
public int Selection { get; set; }
/// <summary>
/// 行业服务?
/// </summary>
public int IndustryService { get; set; }
/// <summary>
/// 竖屏排行榜?
/// </summary>
public int VerticalRank { get; set; }
/// <summary>
/// 进场特效?
/// </summary>
public int EnterEffects { get; set; }
/// <summary>
/// 粉丝团?
/// </summary>
public int FansClub { get; set; }
/// <summary>
/// 表情外显?
/// </summary>
public int EmojiOutside { get; set; }
/// <summary>
/// 售票?
/// </summary>
public int CanSellTicket { get; set; }
/// <summary>
/// 抖音会员人气宝石?
/// </summary>
public int DouPlusPopularityGem { get; set; }
/// <summary>
/// 任务中心?
/// </summary>
public int MissionCenter { get; set; }
/// <summary>
///扩展屏幕?
/// </summary>
public int ExpandScreen { get; set; }
/// <summary>
/// 粉丝群?
/// </summary>
public int FansGroup { get; set; }
/// <summary>
/// 话题?
/// </summary>
public int Topic { get; set; }
/// <summary>
/// 主播任务?
/// </summary>
public int AnchorMission { get; set; }
/// <summary>
/// 跑马灯?
/// </summary>
public int Teleprompter { get; set; }
/// <summary>
/// 长按?
/// </summary>
public int LongTouch { get; set; }
/// <summary>
/// 特殊样式
/// </summary>
public SpecialStyle SpecialStyle { get; set; }
/// <summary>
/// 固定聊天?
/// </summary>
public int FixedChat { get; set; }
/// <summary>
/// 竞猜?
/// </summary>
public int QuizGamePointsPlaying { get; set; }
}
public class ChatStyle
{
/// <summary>
/// 是否禁用样式
/// </summary>
public int UnableStyle { get; set; }
/// <summary>
/// 内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 关闭类型
/// </summary>
public int OffType { get; set; }
}
public class SpecialStyle
{
/// <summary>
/// 聊天样式
/// </summary>
public ChatStyle Chat { get; set; }
/// <summary>
/// 点赞样式
/// </summary>
public ChatStyle Like { get; set; }
}
public class OdinData
{
public string user_id { get; set; }
public string user_type { get; set; }
public string user_is_auth { get; set; }
public string user_is_login { get; set; }
public string user_unique_id { get; set; }
}
/// <summary>
/// 将 直播间页面元素 转为房间信息对象
/// </summary>
/// <param name="html"></param>
/// <param name="result"></param>
/// <returns></returns>
public static (int, string) TryParseRoomPageHtml(string html, out RoomInfo result)
{
result = null;
if (html.IsNullOrWhiteSpace())
{
return (-1, "无效的页面数据");
}
var roomDataReg = new Regex(@"(?<=self\.__pace_f\.push\(\[1,""a:)\[.+?\](?=\\n?""\]\)[\s\n\r]*?<\/script>)");
var match = roomDataReg.Match(html);
if (!match.Success)
{
Logger.LogError("在通过正则匹配直播页房间信息时失败,可能是官方做了升级");
return (1, "未能匹配到房间信息");
}
var matchData = Regex.Unescape(match.Value);
JToken jsonObject = null;
try
{
jsonObject = JsonConvert.DeserializeObject<JArray>(matchData)[3];
}
catch (Exception ex)
{
return (2, "匹配到的房间数据格式有错误");
}
var roomInfo = jsonObject["state"]["roomStore"]["roomInfo"];
var odin = jsonObject["state"]["userStore"]["odin"];
var room = roomInfo["room"];
var roomOwner = roomInfo["anchor"];
if (room == null)
{
return (3, "房间信息为空,获取失败");
}
result = new RoomInfo();
result.Odin = odin?.ToObject<RoomInfo.OdinData>();
result.WebRoomId = roomInfo["web_rid"]?.ToString() ?? "";
result.RoomId = roomInfo["roomId"]?.ToString() ?? "";
result.AdminUserIds = room["admin_user_ids_str"]?.Values<string>()?.ToList() ?? new List<string>();
result.IsLive = room["status"]?.Value<int>() == 2;
result.Title = room["title"]?.ToString() ?? "";
result.UserCount = room["room_view_stats"]?["display_value"]?.Value<long>() ?? 0;
result.TotalUserCount = room["stats"]?["total_user_str"]?.Value<string>() ?? "0";
result.LikeCount = room["like_count"]?.Value<long>() ?? 0;
result.QrcodeUrl = roomInfo["qrcode_url"]?.ToString() ?? "";
result.AuthInfo = room["room_auth"]?.ToObject<RoomInfo.RoomAuth>();
result.Cover = room["cover"]?["url_list"]?.Values<string>().FirstOrDefault() ?? "";//下播情况下没有cover字段
if (roomOwner != null)
{
result.Owner = new RoomInfo.RoomAnchor()
{
UserId = roomOwner["id_str"].ToString(),
Nickname = roomOwner["nickname"].ToString(),
SecUid = roomOwner["sec_uid"].ToString(),
HeadUrl = roomOwner["avatar_thumb"]["url_list"].Values<string>()?.FirstOrDefault() ?? "",
FollowStatus = roomOwner["follow_info"]["follow_status"].Value<int>()
};
}
return (0, "succ");
}
}
}