diff --git a/BililiveRecorder.Core/Event/IOStatsEventArgs.cs b/BililiveRecorder.Core/Event/IOStatsEventArgs.cs
index 40b08ef..e408c94 100644
--- a/BililiveRecorder.Core/Event/IOStatsEventArgs.cs
+++ b/BililiveRecorder.Core/Event/IOStatsEventArgs.cs
@@ -4,6 +4,11 @@ namespace BililiveRecorder.Core.Event
{
public sealed class IOStatsEventArgs : EventArgs
{
+ ///
+ /// 直播服务器域名
+ ///
+ public string? StreamHost { get; set; }
+
///
/// 当前统计区间的开始时间
///
diff --git a/BililiveRecorder.Core/Recording/RecordTaskBase.cs b/BililiveRecorder.Core/Recording/RecordTaskBase.cs
index 16b444e..dd856ff 100644
--- a/BililiveRecorder.Core/Recording/RecordTaskBase.cs
+++ b/BililiveRecorder.Core/Recording/RecordTaskBase.cs
@@ -157,6 +157,7 @@ namespace BililiveRecorder.Core.Recording
this.OnIOStats(new IOStatsEventArgs
{
+ StreamHost = streamHost,
NetworkBytesDownloaded = networkDownloadBytes,
Duration = durationDiff,
StartTime = startTime,
diff --git a/BililiveRecorder.Core/Room.cs b/BililiveRecorder.Core/Room.cs
index 00b6d1a..9e23c01 100644
--- a/BililiveRecorder.Core/Room.cs
+++ b/BililiveRecorder.Core/Room.cs
@@ -353,6 +353,7 @@ namespace BililiveRecorder.Core
{
this.logger.Verbose("IO stats: {@stats}", e);
+ this.Stats.StreamHost = e.StreamHost;
this.Stats.StartTime = e.StartTime;
this.Stats.EndTime = e.EndTime;
this.Stats.Duration = e.Duration;
diff --git a/BililiveRecorder.Core/RoomStats.cs b/BililiveRecorder.Core/RoomStats.cs
index 0a79ad6..cea8cb1 100644
--- a/BililiveRecorder.Core/RoomStats.cs
+++ b/BililiveRecorder.Core/RoomStats.cs
@@ -9,6 +9,7 @@ namespace BililiveRecorder.Core
public class RoomStats : INotifyPropertyChanged
{
#region IO Stats Fields
+ private string? ___StreamHost;
private DateTimeOffset ___StartTime;
private DateTimeOffset ___EndTime;
private TimeSpan ___Duration;
@@ -54,6 +55,11 @@ namespace BililiveRecorder.Core
#region IO Stats Properties
+ ///
+ /// 直播服务器域名
+ ///
+ public string? StreamHost { get => this.___StreamHost; set => this.SetField(ref this.___StreamHost, value); }
+
///
/// 当前统计区间的开始时间
///
@@ -207,6 +213,8 @@ namespace BililiveRecorder.Core
// ------------------------------
+ this.StreamHost = null;
+
this.StartTime = default;
this.EndTime = default;
this.Duration = default;
diff --git a/BililiveRecorder.WPF/App.xaml b/BililiveRecorder.WPF/App.xaml
index aa595f9..1cb446b 100644
--- a/BililiveRecorder.WPF/App.xaml
+++ b/BililiveRecorder.WPF/App.xaml
@@ -33,6 +33,7 @@
+
diff --git a/BililiveRecorder.WPF/Controls/RoomCard.xaml b/BililiveRecorder.WPF/Controls/RoomCard.xaml
index 81dd831..cfe32a9 100644
--- a/BililiveRecorder.WPF/Controls/RoomCard.xaml
+++ b/BililiveRecorder.WPF/Controls/RoomCard.xaml
@@ -11,7 +11,7 @@
l:ResxLocalizationProvider.DefaultDictionary="Strings"
xmlns:local="clr-namespace:BililiveRecorder.WPF.Controls"
xmlns:core="clr-namespace:BililiveRecorder.Core;assembly=BililiveRecorder.Core"
- d:DataContext="{d:DesignInstance core:Room}"
+ d:DataContext="{d:DesignInstance core:IRoom}"
d:DesignWidth="220" d:DesignHeight="110"
mc:Ignorable="d">
- /// 读取直播间统计信息
+ /// 读取直播间录制统计信息
///
///
///
[HttpGet("{roomId:int}/stats")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
- public ActionResult GetRoomStats(int roomId)
+ public ActionResult GetRoomRecordingStats(int roomId)
{
var room = this.FetchRoom(roomId);
if (room is null)
@@ -161,14 +161,14 @@ namespace BililiveRecorder.Web.Api
}
///
- /// 读取直播间统计信息
+ /// 读取直播间录制统计信息
///
///
///
[HttpGet("{objectId:guid}/stats")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
- public ActionResult GetRoomStats(Guid objectId)
+ public ActionResult GetRoomRecordingStats(Guid objectId)
{
var room = this.FetchRoom(objectId);
if (room is null)
@@ -176,6 +176,38 @@ namespace BililiveRecorder.Web.Api
return this.mapper.Map(room.Stats);
}
+ ///
+ /// 读取直播间 IO 统计信息
+ ///
+ ///
+ ///
+ [HttpGet("{roomId:int}/ioStats")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
+ public ActionResult GetRoomIOStats(int roomId)
+ {
+ var room = this.FetchRoom(roomId);
+ if (room is null)
+ return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
+ return this.mapper.Map(room.Stats);
+ }
+
+ ///
+ /// 读取直播间 IO 统计信息
+ ///
+ ///
+ ///
+ [HttpGet("{objectId:guid}/ioStats")]
+ [ProducesResponseType(StatusCodes.Status200OK)]
+ [ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
+ public ActionResult GetRoomIOStats(Guid objectId)
+ {
+ var room = this.FetchRoom(objectId);
+ if (room is null)
+ return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
+ return this.mapper.Map(room.Stats);
+ }
+
#endregion
#region Room Config
diff --git a/BililiveRecorder.Web/Models/Graphql/IOStatsType.cs b/BililiveRecorder.Web/Models/Graphql/IOStatsType.cs
index 7453883..029a7ca 100644
--- a/BililiveRecorder.Web/Models/Graphql/IOStatsType.cs
+++ b/BililiveRecorder.Web/Models/Graphql/IOStatsType.cs
@@ -7,6 +7,7 @@ namespace BililiveRecorder.Web.Models.Graphql
{
public IOStatsType()
{
+ this.Field(x => x.StreamHost, nullable: true);
this.Field(x => x.StartTime);
this.Field(x => x.EndTime);
this.Field(x => x.Duration, type: typeof(TimeSpanMillisecondsGraphType));
diff --git a/BililiveRecorder.Web/Models/Rest/RoomIOStatsDto.cs b/BililiveRecorder.Web/Models/Rest/RoomIOStatsDto.cs
index 32f194a..5c7e64d 100644
--- a/BililiveRecorder.Web/Models/Rest/RoomIOStatsDto.cs
+++ b/BililiveRecorder.Web/Models/Rest/RoomIOStatsDto.cs
@@ -4,6 +4,11 @@ namespace BililiveRecorder.Web.Models.Rest
{
public class RoomIOStatsDto
{
+ ///
+ /// 直播服务器域名
+ ///
+ public string? StreamHost { get; set; }
+
///
/// 当前统计区间的开始时间
///