feat: 支持HDMI关闭传输
This commit is contained in:
parent
a331494fde
commit
8396b7aaea
|
@ -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}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue