feat: 完成jpeg读取后端

This commit is contained in:
2025-08-15 21:04:50 +08:00
parent 774c9575d4
commit 3644c75304
3 changed files with 236 additions and 31 deletions

View File

@@ -20,6 +20,11 @@ public class HdmiVideoStreamClient
public required Jpeg JpegClient { get; set; }
public required CancellationTokenSource CTS { get; set; }
public required int Offset { get; set; }
public int Width { get; set; }
public int Height { get; set; }
}
public class HttpHdmiVideoStreamService : BackgroundService
@@ -97,14 +102,14 @@ public class HttpHdmiVideoStreamService : BackgroundService
var client = _clientDict[key];
client.CTS.Cancel();
var disableResult = await client.HdmiInClient.EnableTrans(false);
if (disableResult.IsSuccessful)
var disableResult = await client.JpegClient.SetEnable(false);
if (disableResult)
{
logger.Info("Successfully disabled HDMI transmission");
}
else
{
logger.Error($"Failed to disable HDMI transmission: {disableResult.Error}");
logger.Error($"Failed to disable HDMI transmission");
}
}
catch (Exception ex)
@@ -115,7 +120,12 @@ public class HttpHdmiVideoStreamService : BackgroundService
private async Task<HdmiVideoStreamClient?> GetOrCreateClientAsync(string boardId)
{
if (_clientDict.TryGetValue(boardId, out var client)) return client;
if (_clientDict.TryGetValue(boardId, out var client))
{
client.Width = client.JpegClient.Width;
client.Height = client.JpegClient.Height;
return client;
}
var userManager = new Database.UserManager();
@@ -132,19 +142,20 @@ public class HttpHdmiVideoStreamService : BackgroundService
{
HdmiInClient = new HdmiIn(board.IpAddr, board.Port, 1),
JpegClient = new Jpeg(board.IpAddr, board.Port, 1),
CTS = new CancellationTokenSource()
CTS = new CancellationTokenSource(),
Offset = 0
};
// 启用HDMI传输
try
{
var hdmiEnableRet = await client.HdmiInClient.EnableTrans(true);
if (!hdmiEnableRet.IsSuccessful)
{
logger.Error($"Failed to enable HDMI transmission for board {boardId}: {hdmiEnableRet.Error}");
return null;
}
logger.Info($"Successfully enabled HDMI transmission for board {boardId}");
// var hdmiEnableRet = await client.JpegClient.EnableTrans(true);
// if (!hdmiEnableRet.IsSuccessful)
// {
// logger.Error($"Failed to enable HDMI transmission for board {boardId}: {hdmiEnableRet.Error}");
// return null;
// }
// logger.Info($"Successfully enabled HDMI transmission for board {boardId}");
var jpegEnableRet = await client.JpegClient.Init(true);
if (!jpegEnableRet.IsSuccessful)
@@ -153,6 +164,9 @@ public class HttpHdmiVideoStreamService : BackgroundService
return null;
}
logger.Info($"Successfully enabled JPEG transmission for board {boardId}");
client.Width = client.JpegClient.Width;
client.Height = client.JpegClient.Height;
}
catch (Exception ex)
{
@@ -209,8 +223,8 @@ public class HttpHdmiVideoStreamService : BackgroundService
logger.Debug("处理HDMI快照请求");
// 从HDMI读取RGB565数据
var frameResult = await client.HdmiInClient.ReadFrame();
if (!frameResult.IsSuccessful || frameResult.Value == null)
var frameResult = await client.JpegClient.GetMultiFrames((uint)client.Offset);
if (!frameResult.IsSuccessful || frameResult.Value == null || frameResult.Value.Count == 0)
{
logger.Error("HDMI快照获取失败");
response.StatusCode = 500;
@@ -220,17 +234,27 @@ public class HttpHdmiVideoStreamService : BackgroundService
return;
}
var jpegData = frameResult.Value;
var jpegData = frameResult.Value[0];
var jpegImage = Common.Image.CompleteJpegData(jpegData, client.Width, client.Height);
if (!jpegImage.IsSuccessful)
{
logger.Error("JPEG数据补全失败");
response.StatusCode = 500;
var errorBytes = System.Text.Encoding.UTF8.GetBytes("Failed to complete JPEG data");
await response.OutputStream.WriteAsync(errorBytes, 0, errorBytes.Length, cancellationToken);
response.Close();
return;
}
// 设置响应头参考Camera版本
response.ContentType = "image/jpeg";
response.ContentLength64 = jpegData.Length;
response.ContentLength64 = jpegImage.Value.Length;
response.Headers.Add("Cache-Control", "no-cache, no-store, must-revalidate");
await response.OutputStream.WriteAsync(jpegData, 0, jpegData.Length, cancellationToken);
await response.OutputStream.WriteAsync(jpegImage.Value, 0, jpegImage.Value.Length, cancellationToken);
await response.OutputStream.FlushAsync(cancellationToken);
logger.Debug("已发送HDMI快照图像大小{Size} 字节", jpegData.Length);
logger.Debug("已发送HDMI快照图像大小{Size} 字节", jpegImage.Value.Length);
}
catch (Exception ex)
{
@@ -260,13 +284,35 @@ public class HttpHdmiVideoStreamService : BackgroundService
while (!cancellationToken.IsCancellationRequested)
{
try
{
var frameStartTime = DateTime.UtcNow;
var frameStartTime = DateTime.UtcNow;
var ret = await client.HdmiInClient.GetMJpegFrame();
if (ret == null) continue;
var frame = ret.Value;
var frameResult =
await client.JpegClient.GetMultiFrames((uint)client.Offset);
if (!frameResult.IsSuccessful || frameResult.Value == null || frameResult.Value.Count == 0)
{
logger.Error("获取HDMI帧失败");
await Task.Delay(100, cancellationToken);
continue;
}
foreach (var framebytes in frameResult.Value)
{
var jpegImage = Common.Image.CompleteJpegData(framebytes, client.Width, client.Height);
if (!jpegImage.IsSuccessful)
{
logger.Error("JPEG数据不完整");
await Task.Delay(100, cancellationToken);
continue;
}
var frameRet = Common.Image.CreateMjpegFrameFromJpeg(jpegImage.Value);
if (!frameRet.IsSuccessful)
{
logger.Error("创建MJPEG帧失败");
await Task.Delay(100, cancellationToken);
continue;
}
var frame = frameRet.Value;
await response.OutputStream.WriteAsync(frame.header, 0, frame.header.Length, cancellationToken);
await response.OutputStream.WriteAsync(frame.data, 0, frame.data.Length, cancellationToken);
@@ -283,10 +329,7 @@ public class HttpHdmiVideoStreamService : BackgroundService
logger.Debug("HDMI帧 {FrameNumber} 性能统计 - 总计: {TotalTime:F1}ms, JPEG大小: {JpegSize} 字节",
frameCounter, totalTime, frame.data.Length);
}
}
catch (Exception ex)
{
logger.Error(ex, "处理HDMI帧时发生错误");
}
}
}