FPGA_WebLab/server/src/Controllers/VideoStreamController.cs

246 lines
8.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System.ComponentModel.DataAnnotations;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Mvc;
/// <summary>
/// 视频流控制器,支持动态配置摄像头连接
/// </summary>
[ApiController]
[Route("api/[controller]")]
public class VideoStreamController : ControllerBase
{
private static NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
private readonly server.Services.HttpVideoStreamService _videoStreamService;
/// <summary>
/// 摄像头配置请求模型
/// </summary>
public class CameraConfigRequest
{
/// <summary>
/// 摄像头地址
/// </summary>
[Required]
[RegularExpression(@"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$", ErrorMessage = "IP地址")]
public string Address { get; set; } = "";
/// <summary>
/// 摄像头端口
/// </summary>
[Required]
[Range(1, 65535, ErrorMessage = "端口必须在1-65535范围内")]
public int Port { get; set; }
}
/// <summary>
/// 初始化HTTP视频流控制器
/// </summary>
/// <param name="videoStreamService">HTTP视频流服务</param>
public VideoStreamController(server.Services.HttpVideoStreamService videoStreamService)
{
logger.Info("创建VideoStreamController命名空间{Namespace}", this.GetType().Namespace);
_videoStreamService = videoStreamService;
}
/// <summary>
/// 获取 HTTP 视频流服务状态
/// </summary>
/// <returns>服务状态信息</returns>
[HttpGet("Status")]
[EnableCors("Users")]
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)]
public IResult GetStatus()
{
try
{
logger.Info("GetStatus方法被调用控制器{Controller}路径api/VideoStream/Status", this.GetType().Name);
// 使用HttpVideoStreamService提供的状态信息
var status = _videoStreamService.GetServiceStatus();
// 转换为小写首字母的JSON属性符合前端惯例
return TypedResults.Ok(status);
}
catch (Exception ex)
{
logger.Error(ex, "获取 HTTP 视频流服务状态失败");
return TypedResults.InternalServerError(ex.Message);
}
}
/// <summary>
/// 获取 HTTP 视频流信息
/// </summary>
/// <returns>流信息</returns>
[HttpGet("StreamInfo")]
[EnableCors("Users")]
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)]
public IResult GetStreamInfo()
{
try
{
logger.Info("获取 HTTP 视频流信息");
return TypedResults.Ok(new
{
frameRate = _videoStreamService.FrameRate,
frameWidth = _videoStreamService.FrameWidth,
frameHeight = _videoStreamService.FrameHeight,
format = "MJPEG",
htmlUrl = $"http://localhost:{_videoStreamService.ServerPort}/video-feed.html",
mjpegUrl = $"http://localhost:{_videoStreamService.ServerPort}/video-stream",
snapshotUrl = $"http://localhost:{_videoStreamService.ServerPort}/snapshot",
});
}
catch (Exception ex)
{
logger.Error(ex, "获取 HTTP 视频流信息失败");
return TypedResults.InternalServerError(ex.Message);
}
}
/// <summary>
/// 配置摄像头连接参数
/// </summary>
/// <param name="config">摄像头配置</param>
/// <returns>配置结果</returns>
[HttpPost("ConfigureCamera")]
[EnableCors("Users")]
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(object), StatusCodes.Status400BadRequest)]
[ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)]
public async Task<IResult> ConfigureCamera([FromBody] CameraConfigRequest config)
{
try
{
logger.Info("配置摄像头连接: {Address}:{Port}", config.Address, config.Port);
var success = await _videoStreamService.ConfigureCameraAsync(config.Address, config.Port);
if (success)
{
return TypedResults.Ok(new
{
success = true,
message = "摄像头配置成功",
cameraAddress = config.Address,
cameraPort = config.Port
});
}
else
{
return TypedResults.BadRequest(new
{
success = false,
message = "摄像头配置失败",
cameraAddress = config.Address,
cameraPort = config.Port
});
}
}
catch (Exception ex)
{
logger.Error(ex, "配置摄像头连接失败");
return TypedResults.InternalServerError(ex.Message);
}
}
/// <summary>
/// 获取当前摄像头配置
/// </summary>
/// <returns>摄像头配置信息</returns>
[HttpGet("CameraConfig")]
[EnableCors("Users")]
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)]
public IResult GetCameraConfig()
{
try
{
logger.Info("获取摄像头配置");
var cameraStatus = _videoStreamService.GetCameraStatus();
return TypedResults.Ok(new
{
address = _videoStreamService.CameraAddress,
port = _videoStreamService.CameraPort,
isConfigured = cameraStatus.GetType().GetProperty("IsConfigured")?.GetValue(cameraStatus),
connectionString = $"{_videoStreamService.CameraAddress}:{_videoStreamService.CameraPort}"
});
}
catch (Exception ex)
{
logger.Error(ex, "获取摄像头配置失败");
return TypedResults.InternalServerError(ex.Message);
}
}
/// <summary>
/// 控制 HTTP 视频流服务开关
/// </summary>
/// <param name="enabled">是否启用服务</param>
/// <returns>操作结果</returns>
[HttpPost("SetEnabled")]
[EnableCors("Users")]
[ProducesResponseType(typeof(object), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)]
public IResult SetEnabled([FromQuery] bool enabled)
{
logger.Info("设置视频流服务开关: {Enabled}", enabled);
_videoStreamService.Enabled = enabled;
return TypedResults.Ok(new
{
success = true,
enabled = _videoStreamService.Enabled
});
}
/// <summary>
/// 测试 HTTP 视频流连接
/// </summary>
/// <returns>连接测试结果</returns>
[HttpPost("TestConnection")]
[EnableCors("Users")]
[ProducesResponseType(typeof(bool), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(Exception), StatusCodes.Status500InternalServerError)]
public async Task<IResult> TestConnection()
{
try
{
logger.Info("测试 HTTP 视频流连接");
// 尝试通过HTTP请求检查视频流服务是否可访问
bool isConnected = false;
using (var httpClient = new HttpClient())
{
httpClient.Timeout = TimeSpan.FromSeconds(2); // 设置较短的超时时间
var response = await httpClient.GetAsync($"http://localhost:{_videoStreamService.ServerPort}/");
// 只要能连接上就认为成功,不管返回状态
isConnected = response.IsSuccessStatusCode;
}
logger.Info("测试摄像头连接");
var (isSuccess, message) = await _videoStreamService.TestCameraConnectionAsync();
return TypedResults.Ok(new
{
isConnected = isConnected,
success = isSuccess,
message = message,
cameraAddress = _videoStreamService.CameraAddress,
cameraPort = _videoStreamService.CameraPort,
timestamp = DateTime.Now
});
}
catch (Exception ex)
{
logger.Error(ex, "HTTP 视频流连接测试失败");
// 连接失败但不抛出异常,而是返回连接失败的结果
return TypedResults.Ok(false);
}
}
}