BililiveRecorder/BililiveRecorder.Web/Api/RoomController.cs

448 lines
17 KiB
C#
Raw Normal View History

2022-04-03 13:34:55 +08:00
using System;
using System.Linq;
2022-04-07 16:58:20 +08:00
using System.Runtime.CompilerServices;
2022-04-03 13:34:55 +08:00
using System.Threading.Tasks;
using AutoMapper;
using BililiveRecorder.Core;
using BililiveRecorder.Web.Models;
using BililiveRecorder.Web.Models.Rest;
2022-04-03 13:34:55 +08:00
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace BililiveRecorder.Web.Api
{
[ApiController, Route("api/[controller]", Name = "[controller] [action]")]
public sealed class RoomController : ControllerBase
2022-04-03 13:34:55 +08:00
{
private readonly IMapper mapper;
private readonly IRecorder recorder;
public RoomController(IMapper mapper, IRecorder recorder)
{
this.mapper = mapper ?? throw new ArgumentNullException(nameof(mapper));
this.recorder = recorder ?? throw new ArgumentNullException(nameof(recorder));
}
2022-04-07 16:58:20 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2022-04-03 13:34:55 +08:00
private IRoom? FetchRoom(int roomId) => this.recorder.Rooms.FirstOrDefault(x => x.ShortId == roomId || x.RoomConfig.RoomId == roomId);
2022-04-07 16:58:20 +08:00
[MethodImpl(MethodImplOptions.AggressiveInlining)]
2022-04-03 13:34:55 +08:00
private IRoom? FetchRoom(Guid objectId) => this.recorder.Rooms.FirstOrDefault(x => x.ObjectId == objectId);
/// <summary>
/// 列出所有直播间
/// </summary>
/// <returns></returns>
[HttpGet]
public RoomDto[] GetRooms() => this.mapper.Map<RoomDto[]>(this.recorder.Rooms);
#region Create & Delete
/// <summary>
/// 添加直播间
/// </summary>
/// <param name="createRoom"></param>
/// <returns></returns>
[HttpPost]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status400BadRequest)]
public ActionResult<RoomDto> CreateRoom([FromBody] CreateRoomDto createRoom)
{
if (createRoom.RoomId <= 0)
return this.BadRequest(new RestApiError { Code = RestApiErrorCode.RoomidOutOfRange, Message = "Roomid must be greater than 0." });
var room = this.FetchRoom(createRoom.RoomId);
if (room is not null)
2022-04-07 16:58:20 +08:00
{
if (room.RoomConfig.AutoRecord != createRoom.AutoRecord)
room.RoomConfig.AutoRecord = createRoom.AutoRecord;
}
else
{
room = this.recorder.AddRoom(createRoom.RoomId, createRoom.AutoRecord);
}
2022-04-03 13:34:55 +08:00
return this.mapper.Map<RoomDto>(room);
}
/// <summary>
/// 删除直播间
/// </summary>
/// <param name="roomId"></param>
/// <returns></returns>
[HttpDelete("{roomId:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomDto> DeleteRoom(int roomId)
{
var room = this.FetchRoom(roomId);
if (room is null)
return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
this.recorder.RemoveRoom(room);
return this.mapper.Map<RoomDto>(room);
}
/// <summary>
/// 删除直播间
/// </summary>
/// <param name="objectId"></param>
/// <returns></returns>
[HttpDelete("{objectId:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomDto> DeleteRoom(Guid objectId)
{
var room = this.FetchRoom(objectId);
if (room is null)
return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
this.recorder.RemoveRoom(room);
return this.mapper.Map<RoomDto>(room);
}
#endregion
#region Get Room
/// <summary>
/// 读取一个直播间
/// </summary>
/// <param name="roomId"></param>
/// <returns></returns>
[HttpGet("{roomId:int}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomDto> GetRoom(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<RoomDto>(room);
}
/// <summary>
/// 读取一个直播间
/// </summary>
/// <param name="objectId"></param>
/// <returns></returns>
[HttpGet("{objectId:guid}")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomDto> GetRoom(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<RoomDto>(room);
}
#endregion
#region Get Room Stats
/// <summary>
2022-06-29 19:46:58 +08:00
/// 读取直播间录制统计信息
2022-04-03 13:34:55 +08:00
/// </summary>
/// <param name="roomId"></param>
/// <returns></returns>
[HttpGet("{roomId:int}/stats")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
2022-06-29 19:46:58 +08:00
public ActionResult<RoomRecordingStatsDto> GetRoomRecordingStats(int roomId)
2022-04-03 13:34:55 +08:00
{
var room = this.FetchRoom(roomId);
if (room is null)
return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
2022-04-09 16:43:05 +08:00
return this.mapper.Map<RoomRecordingStatsDto>(room.Stats);
2022-04-03 13:34:55 +08:00
}
/// <summary>
2022-06-29 19:46:58 +08:00
/// 读取直播间录制统计信息
2022-04-03 13:34:55 +08:00
/// </summary>
/// <param name="objectId"></param>
/// <returns></returns>
[HttpGet("{objectId:guid}/stats")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
2022-06-29 19:46:58 +08:00
public ActionResult<RoomRecordingStatsDto> GetRoomRecordingStats(Guid objectId)
2022-04-03 13:34:55 +08:00
{
var room = this.FetchRoom(objectId);
if (room is null)
return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
2022-04-09 16:43:05 +08:00
return this.mapper.Map<RoomRecordingStatsDto>(room.Stats);
2022-04-03 13:34:55 +08:00
}
2022-06-29 19:46:58 +08:00
/// <summary>
/// 读取直播间 IO 统计信息
/// </summary>
/// <param name="roomId"></param>
/// <returns></returns>
[HttpGet("{roomId:int}/ioStats")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomIOStatsDto> 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<RoomIOStatsDto>(room.Stats);
}
/// <summary>
/// 读取直播间 IO 统计信息
/// </summary>
/// <param name="objectId"></param>
/// <returns></returns>
[HttpGet("{objectId:guid}/ioStats")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomIOStatsDto> 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<RoomIOStatsDto>(room.Stats);
}
2022-04-03 13:34:55 +08:00
#endregion
#region Room Config
/// <summary>
/// 读取直播间设置
/// </summary>
/// <param name="roomId"></param>
/// <returns></returns>
[HttpGet("{roomId:int}/config")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomConfigDto> GetRoomConfig(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<RoomConfigDto>(room.RoomConfig);
}
/// <summary>
/// 读取直播间设置
/// </summary>
/// <param name="objectId"></param>
/// <returns></returns>
[HttpGet("{objectId:guid}/config")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomConfigDto> GetRoomConfig(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<RoomConfigDto>(room.RoomConfig);
}
/// <summary>
/// 修改直播间设置
/// </summary>
/// <param name="roomId"></param>
/// <param name="config"></param>
/// <returns></returns>
[HttpPost("{roomId:int}/config")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomConfigDto> SetRoomConfig(int roomId, [FromBody] SetRoomConfig config)
{
var room = this.FetchRoom(roomId);
if (room is null)
return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
config.ApplyTo(room.RoomConfig);
2022-07-08 21:13:00 +08:00
this.recorder.SaveConfig();
2022-04-03 13:34:55 +08:00
return this.mapper.Map<RoomConfigDto>(room.RoomConfig);
}
/// <summary>
/// 修改直播间设置
/// </summary>
/// <param name="objectId"></param>
/// <param name="config"></param>
/// <returns></returns>
[HttpPost("{objectId:guid}/config")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomConfigDto> SetRoomConfig(Guid objectId, [FromBody] SetRoomConfig config)
{
var room = this.FetchRoom(objectId);
if (room is null)
return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
config.ApplyTo(room.RoomConfig);
2022-07-08 21:13:00 +08:00
this.recorder.SaveConfig();
2022-04-03 13:34:55 +08:00
return this.mapper.Map<RoomConfigDto>(room.RoomConfig);
}
#endregion
#region Room Action
/// <summary>
/// 开始录制
/// </summary>
/// <param name="roomId"></param>
/// <returns></returns>
[HttpPost("{roomId:int}/start")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomDto> StartRecording(int roomId)
{
var room = this.FetchRoom(roomId);
if (room is null)
return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
room.StartRecord();
return this.mapper.Map<RoomDto>(room);
}
/// <summary>
/// 开始录制
/// </summary>
/// <param name="objectId"></param>
/// <returns></returns>
[HttpPost("{objectId:guid}/start")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomDto> StartRecording(Guid objectId)
{
var room = this.FetchRoom(objectId);
if (room is null)
return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
room.StartRecord();
return this.mapper.Map<RoomDto>(room);
}
/// <summary>
/// 停止录制
/// </summary>
/// <param name="roomId"></param>
/// <returns></returns>
[HttpPost("{roomId:int}/stop")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomDto> StopRecording(int roomId)
{
var room = this.FetchRoom(roomId);
if (room is null)
return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
room.StopRecord();
return this.mapper.Map<RoomDto>(room);
}
/// <summary>
/// 停止录制
/// </summary>
/// <param name="objectId"></param>
/// <returns></returns>
[HttpPost("{objectId:guid}/stop")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomDto> StopRecording(Guid objectId)
{
var room = this.FetchRoom(objectId);
if (room is null)
return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
room.StopRecord();
return this.mapper.Map<RoomDto>(room);
}
/// <summary>
/// 手动分段
/// </summary>
/// <param name="roomId"></param>
/// <returns></returns>
[HttpPost("{roomId:int}/split")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomDto> SplitRecording(int roomId)
{
var room = this.FetchRoom(roomId);
if (room is null)
return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
room.SplitOutput();
return this.mapper.Map<RoomDto>(room);
}
/// <summary>
/// 手动分段
/// </summary>
/// <param name="objectId"></param>
/// <returns></returns>
[HttpPost("{objectId:guid}/split")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public ActionResult<RoomDto> SplitRecording(Guid objectId)
{
var room = this.FetchRoom(objectId);
if (room is null)
return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
room.SplitOutput();
return this.mapper.Map<RoomDto>(room);
}
/// <summary>
/// 刷新直播间信息
/// </summary>
/// <param name="roomId"></param>
/// <returns></returns>
[HttpPost("{roomId:int}/refresh")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public async Task<ActionResult<RoomDto>> RefreshRecordingAsync(int roomId)
{
var room = this.FetchRoom(roomId);
if (room is null)
return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
await room.RefreshRoomInfoAsync().ConfigureAwait(false);
return this.mapper.Map<RoomDto>(room);
}
/// <summary>
/// 刷新直播间信息
/// </summary>
/// <param name="objectId"></param>
/// <returns></returns>
[HttpPost("{objectId:guid}/refresh")]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(typeof(RestApiError), StatusCodes.Status404NotFound)]
public async Task<ActionResult<RoomDto>> RefreshRecordingAsync(Guid objectId)
{
var room = this.FetchRoom(objectId);
if (room is null)
return this.NotFound(new RestApiError { Code = RestApiErrorCode.RoomNotFound, Message = "Room not found" });
await room.RefreshRoomInfoAsync().ConfigureAwait(false);
return this.mapper.Map<RoomDto>(room);
}
#endregion
}
}