修复工作
This commit is contained in:
@@ -85,6 +85,7 @@ public class MediaTransferFlvByFFmpeg extends MediaTransfer {
|
|||||||
public MediaTransferFlvByFFmpeg(CameraDto cameraDto) {
|
public MediaTransferFlvByFFmpeg(CameraDto cameraDto) {
|
||||||
command.add(System.getProperty(MediaConstant.ffmpegPathKey));
|
command.add(System.getProperty(MediaConstant.ffmpegPathKey));
|
||||||
this.cameraDto = cameraDto;
|
this.cameraDto = cameraDto;
|
||||||
|
this.enableLog = true; // 临时启用日志,用于调试
|
||||||
buildCommand();
|
buildCommand();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -176,15 +177,21 @@ public class MediaTransferFlvByFFmpeg extends MediaTransfer {
|
|||||||
command.add(output);
|
command.add(output);
|
||||||
|
|
||||||
String join = CollUtil.join(command, " ");
|
String join = CollUtil.join(command, " ");
|
||||||
|
log.info("========== FFmpeg 命令 ==========");
|
||||||
log.info(join);
|
log.info(join);
|
||||||
|
log.info("RTSP URL: {}", cameraDto.getUrl());
|
||||||
|
log.info("输出地址: {}", output);
|
||||||
|
log.info("=================================");
|
||||||
try {
|
try {
|
||||||
process = new ProcessBuilder(command).start();
|
process = new ProcessBuilder(command).start();
|
||||||
running = true;
|
running = true;
|
||||||
|
log.info("✅ FFmpeg 进程已启动,等待数据...");
|
||||||
listenNetTimeout();
|
listenNetTimeout();
|
||||||
dealStream(process);
|
dealStream(process);
|
||||||
outputData();
|
outputData();
|
||||||
listenClient();
|
listenClient();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
log.error("❌ FFmpeg 启动失败: {}", e.getMessage());
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@@ -215,13 +222,15 @@ public class MediaTransferFlvByFFmpeg extends MediaTransfer {
|
|||||||
if (header == null && len >= 13) {
|
if (header == null && len >= 13) {
|
||||||
header = new byte[13];
|
header = new byte[13];
|
||||||
System.arraycopy(buffer, 0, header, 0, 13);
|
System.arraycopy(buffer, 0, header, 0, 13);
|
||||||
log.debug("FLV header已获取: {} bytes", header.length);
|
log.info("✅ FLV header已获取: {} bytes", header.length);
|
||||||
headerSent = true;
|
headerSent = true;
|
||||||
|
|
||||||
// 如果有剩余数据(包含header+数据),一起发送
|
// 如果有剩余数据(包含header+数据),一起发送
|
||||||
if (len > 0) {
|
if (len > 0) {
|
||||||
byte[] data = new byte[len];
|
byte[] data = new byte[len];
|
||||||
System.arraycopy(buffer, 0, data, 0, len);
|
System.arraycopy(buffer, 0, data, 0, len);
|
||||||
|
log.info("📤 发送第一批数据: {} bytes,客户端数量: HTTP={}, WS={}",
|
||||||
|
len, httpClients.size(), wsClients.size());
|
||||||
sendFrameData(data);
|
sendFrameData(data);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
@@ -384,7 +393,12 @@ public class MediaTransferFlvByFFmpeg extends MediaTransfer {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (enableLog) {
|
if (enableLog) {
|
||||||
log.info("err: " + line);
|
log.info("[FFmpeg] " + line);
|
||||||
|
}
|
||||||
|
// 即使不启用日志,也输出关键错误信息
|
||||||
|
if (!enableLog && (line.contains("error") || line.contains("failed") ||
|
||||||
|
line.contains("Connection") || line.contains("timeout"))) {
|
||||||
|
log.error("[FFmpeg Error] " + line);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@@ -536,14 +550,17 @@ public class MediaTransferFlvByFFmpeg extends MediaTransfer {
|
|||||||
* @param ctype enum,ClientType
|
* @param ctype enum,ClientType
|
||||||
*/
|
*/
|
||||||
public void addClient(ChannelHandlerContext ctx, ClientType ctype) {
|
public void addClient(ChannelHandlerContext ctx, ClientType ctype) {
|
||||||
|
log.info("🔗 新客户端连接: 类型={}, Channel={}", ctype, ctx.channel().remoteAddress());
|
||||||
int timeout = 0;
|
int timeout = 0;
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
if (header != null) {
|
if (header != null) {
|
||||||
|
log.info("✅ FLV header 已就绪,准备发送给客户端");
|
||||||
try {
|
try {
|
||||||
if (ctx.channel().isWritable()) {
|
if (ctx.channel().isWritable()) {
|
||||||
// 发送帧前先发送header
|
// 发送帧前先发送header
|
||||||
if (ClientType.HTTP == ctype) {
|
if (ClientType.HTTP == ctype) {
|
||||||
|
log.info("📤 发送 FLV header 到 HTTP 客户端: {} bytes", header.length);
|
||||||
ChannelFuture future = ctx.writeAndFlush(Unpooled.copiedBuffer(header));
|
ChannelFuture future = ctx.writeAndFlush(Unpooled.copiedBuffer(header));
|
||||||
future.addListener(new GenericFutureListener<Future<? super Void>>() {
|
future.addListener(new GenericFutureListener<Future<? super Void>>() {
|
||||||
@Override
|
@Override
|
||||||
@@ -574,10 +591,18 @@ public class MediaTransferFlvByFFmpeg extends MediaTransfer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 等待推拉流启动
|
// 等待推拉流启动
|
||||||
|
if (timeout == 0) {
|
||||||
|
log.info("⏳ 等待 FLV header...");
|
||||||
|
}
|
||||||
Thread.sleep(50);
|
Thread.sleep(50);
|
||||||
// 启动录制器失败
|
// 启动录制器失败
|
||||||
timeout += 50;
|
timeout += 50;
|
||||||
|
if (timeout % 5000 == 0) {
|
||||||
|
log.warn("⚠️ 等待 FLV header 超时: {} ms,可能 FFmpeg 拉流失败", timeout);
|
||||||
|
}
|
||||||
if (timeout > 30000) {
|
if (timeout > 30000) {
|
||||||
|
log.error("❌ 等待 FLV header 超时 30 秒,放弃连接");
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} catch (java.lang.Exception e) {
|
} catch (java.lang.Exception e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user