feat: 支持HDMI关闭传输

This commit is contained in:
SikongJueluo 2025-08-04 17:00:31 +08:00
parent a331494fde
commit 8396b7aaea
No known key found for this signature in database
2 changed files with 62 additions and 16 deletions

View File

@ -60,4 +60,38 @@ public class HdmiVideoStreamController : ControllerBase
var endpoint = _videoStreamService.GetVideoEndpoint(boardId.ToString()); var endpoint = _videoStreamService.GetVideoEndpoint(boardId.ToString());
return Ok(endpoint); return Ok(endpoint);
} }
// 禁用指定板子的 HDMI 传输
[HttpPost("DisableHdmiTransmission")]
[Authorize]
public async Task<IActionResult> DisableHdmiTransmission()
{
var userName = User.FindFirstValue(ClaimTypes.Name);
if (string.IsNullOrEmpty(userName))
return Unauthorized("User name not found in claims.");
var db = new AppDataConnection();
if (db == null)
return NotFound("Database connection failed.");
var userRet = db.GetUserByName(userName);
if (!userRet.IsSuccessful || !userRet.Value.HasValue)
return NotFound("User not found.");
var user = userRet.Value.Value;
var boardId = user.BoardID;
if (boardId == Guid.Empty)
return NotFound("No board bound to this user.");
try
{
await _videoStreamService.DisableHdmiTransmissionAsync(boardId.ToString());
return Ok($"HDMI transmission for board {boardId} disabled.");
}
catch (Exception ex)
{
logger.Error(ex, $"Failed to disable HDMI transmission for board {boardId}");
return StatusCode(500, $"Error disabling HDMI transmission: {ex.Message}");
}
}
} }

View File

@ -18,7 +18,7 @@ public class HttpHdmiVideoStreamService : BackgroundService
private HttpListener? _httpListener; private HttpListener? _httpListener;
private readonly int _serverPort = 4322; private readonly int _serverPort = 4322;
private readonly ConcurrentDictionary<string, HdmiIn> _hdmiInDict = new(); private readonly ConcurrentDictionary<string, HdmiIn> _hdmiInDict = new();
private bool _isEnabled = true; private readonly ConcurrentDictionary<string, CancellationTokenSource> _hdmiInCtsDict = new();
public override async Task StartAsync(CancellationToken cancellationToken) public override async Task StartAsync(CancellationToken cancellationToken)
{ {
@ -72,29 +72,33 @@ public class HttpHdmiVideoStreamService : BackgroundService
public override async Task StopAsync(CancellationToken cancellationToken) public override async Task StopAsync(CancellationToken cancellationToken)
{ {
logger.Info("Stopping HDMI Video Stream Service..."); logger.Info("Stopping HDMI Video Stream Service...");
_isEnabled = false;
// 禁用所有活跃的HDMI传输 // 禁用所有活跃的HDMI传输
var disableTasks = new List<Task>(); var disableTasks = new List<Task>();
foreach (var hdmiIn in _hdmiInDict.Values) foreach (var hdmiKey in _hdmiInDict.Keys)
{ {
disableTasks.Add(DisableHdmiTransmissionAsync(hdmiIn)); disableTasks.Add(DisableHdmiTransmissionAsync(hdmiKey));
} }
// 等待所有禁用操作完成 // 等待所有禁用操作完成
await Task.WhenAll(disableTasks); await Task.WhenAll(disableTasks);
// 清空字典 // 清空字典
_hdmiInDict.Clear(); _hdmiInDict.Clear();
_hdmiInCtsDict.Clear();
_httpListener?.Close(); // 立即关闭监听器,唤醒阻塞 _httpListener?.Close(); // 立即关闭监听器,唤醒阻塞
await base.StopAsync(cancellationToken); await base.StopAsync(cancellationToken);
} }
private async Task DisableHdmiTransmissionAsync(HdmiIn hdmiIn) public async Task DisableHdmiTransmissionAsync(string key)
{ {
try try
{ {
var cts = _hdmiInCtsDict[key];
cts.Cancel();
var hdmiIn = _hdmiInDict[key];
var disableResult = await hdmiIn.EnableTrans(false); var disableResult = await hdmiIn.EnableTrans(false);
if (disableResult.IsSuccessful) if (disableResult.IsSuccessful)
{ {
@ -134,7 +138,7 @@ public class HttpHdmiVideoStreamService : BackgroundService
var board = boardRet.Value.Value; var board = boardRet.Value.Value;
hdmiIn = new HdmiIn(board.IpAddr, board.Port, 0); // taskID 可根据实际需求调整 hdmiIn = new HdmiIn(board.IpAddr, board.Port, 0); // taskID 可根据实际需求调整
// 启用HDMI传输 // 启用HDMI传输
try try
{ {
@ -153,6 +157,7 @@ public class HttpHdmiVideoStreamService : BackgroundService
} }
_hdmiInDict[boardId] = hdmiIn; _hdmiInDict[boardId] = hdmiIn;
_hdmiInCtsDict[boardId] = new CancellationTokenSource();
return hdmiIn; return hdmiIn;
} }
@ -173,13 +178,20 @@ public class HttpHdmiVideoStreamService : BackgroundService
return; return;
} }
var hdmiInToken = _hdmiInCtsDict[boardId].Token;
if (hdmiInToken == null)
{
await SendErrorAsync(context.Response, "HDMI input is not available");
return;
}
if (path == "/snapshot") if (path == "/snapshot")
{ {
await HandleSnapshotRequestAsync(context.Response, hdmiIn, cancellationToken); await HandleSnapshotRequestAsync(context.Response, hdmiIn, hdmiInToken);
} }
else if (path == "/mjpeg") else if (path == "/mjpeg")
{ {
await HandleMjpegStreamAsync(context.Response, hdmiIn, cancellationToken); await HandleMjpegStreamAsync(context.Response, hdmiIn, hdmiInToken);
} }
else if (path == "/video") else if (path == "/video")
{ {
@ -218,7 +230,7 @@ public class HttpHdmiVideoStreamService : BackgroundService
var expectedLength = frameWidth * frameHeight * 2; var expectedLength = frameWidth * frameHeight * 2;
if (rgb565Data.Length != expectedLength) if (rgb565Data.Length != expectedLength)
{ {
logger.Warn("HDMI快照数据长度不匹配期望: {Expected}, 实际: {Actual}", logger.Warn("HDMI快照数据长度不匹配期望: {Expected}, 实际: {Actual}",
expectedLength, rgb565Data.Length); expectedLength, rgb565Data.Length);
} }
@ -285,7 +297,7 @@ public class HttpHdmiVideoStreamService : BackgroundService
const int frameWidth = 960; // HDMI输入分辨率 const int frameWidth = 960; // HDMI输入分辨率
const int frameHeight = 540; const int frameHeight = 540;
while (!cancellationToken.IsCancellationRequested && _isEnabled) while (!cancellationToken.IsCancellationRequested)
{ {
try try
{ {
@ -381,7 +393,7 @@ public class HttpHdmiVideoStreamService : BackgroundService
{ {
logger.Error(ex, "禁用HDMI传输时出错"); logger.Error(ex, "禁用HDMI传输时出错");
} }
try try
{ {
response.Close(); response.Close();