diff --git a/src/main/java/com/tuoheng/steam/controller/StreamRecordController.java b/src/main/java/com/tuoheng/steam/controller/StreamRecordController.java index ecd71d1..68e8cf0 100644 --- a/src/main/java/com/tuoheng/steam/controller/StreamRecordController.java +++ b/src/main/java/com/tuoheng/steam/controller/StreamRecordController.java @@ -177,11 +177,11 @@ public class StreamRecordController { public String streamSwitch(String source){ - if(Objects.nonNull(srsdomain) && !srsdomain.isEmpty()){ - if(Objects.nonNull(source) && !source.isEmpty()){ - return dockerFix(source); - } - } +// if(Objects.nonNull(srsdomain) && !srsdomain.isEmpty()){ +// if(Objects.nonNull(source) && !source.isEmpty()){ +// return dockerFix(source); +// } +// } if(source.contains("stream.t-aaron.com")){ diff --git a/src/main/java/com/tuoheng/steam/service/innerService/ProcessService.java b/src/main/java/com/tuoheng/steam/service/innerService/ProcessService.java index 09f1afe..e786b49 100644 --- a/src/main/java/com/tuoheng/steam/service/innerService/ProcessService.java +++ b/src/main/java/com/tuoheng/steam/service/innerService/ProcessService.java @@ -17,6 +17,8 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.*; import java.util.concurrent.*; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.TimeoutException; import java.util.stream.Collectors; @Service @@ -49,11 +51,13 @@ public class ProcessService { flvRecord.getStream().getDayRecord().getDay() + File.separator + flvRecord.getStream().getStreamId() + File.separator +flvRecord.getStartTime() + ".mp4"; - ProcessBuilder pb = new ProcessBuilder(command.split(" ")); pb.redirectErrorStream(true); Process process = pb.start(); + // 使用原子布尔值来标记进程是否被终止 + AtomicBoolean processTerminated = new AtomicBoolean(false); + loggingService.execute(new Runnable() { @Override public void run() { @@ -61,55 +65,88 @@ public class ProcessService { try (BufferedReader reader = new BufferedReader( new InputStreamReader(process.getInputStream()))) { String line; - while ((line = reader.readLine()) != null) { + while ((line = reader.readLine()) != null && !processTerminated.get()) { logger.info("mergeMp4-------- {}",line); } } catch (IOException e) { - logger.info("mergeMp4-------- Over",e); + if (!processTerminated.get()) { + logger.info("mergeMp4-------- Over",e); + } } logger.info("mergeMp4 Over"); - File delete = new File(recordPath+ File.separator + - flvRecord.getStream().getDayRecord().getDay() + File.separator + - flvRecord.getStream().getStreamId() + File.separator + flvRecord.getFlv()); - FileUtil.deleteFile(delete); + + // 删除源文件的逻辑移到这里,根据转换结果决定是否删除 + // 这里暂时不删除,让主线程来决定是否删除源文件 } }); CompletableFuture future = process.onExit(); - // 阻塞等待进程结束 + // 阻塞等待进程结束,增加超时时间到5分钟 Process completedProcess = null; try { - completedProcess = future.get(4, TimeUnit.SECONDS); + completedProcess = future.get(5, TimeUnit.MINUTES); logger.info("mergeMp4正常完成-------- Over"); - }catch (Exception e) { + }catch (TimeoutException e) { String fileName = recordPath+ File.separator + flvRecord.getStream().getDayRecord().getDay() + File.separator + flvRecord.getStream().getStreamId() + File.separator +flvRecord.getStartTime() + ".mp4"; File file = new File(fileName); - if(file.exists()){ - logger.info("mergeMp4超时4S完成-------- Over",e); + + logger.warn("mergeMp4超时5分钟,检查输出文件是否存在: {}", fileName); + + if(file.exists() && file.length() > 0){ + logger.info("mergeMp4超时但文件已生成,标记为完成-------- Over"); + processTerminated.set(true); process.destroy(); } else { - try { - completedProcess = future.get(4, TimeUnit.SECONDS); - }catch (Exception e1) { - if(file.exists()){ - logger.info("mergeMp4超时8S完成-------- Over",e); - process.destroy(); - }else { - logger.info("mergeMp4超时8S未完成-------- Over",e); - process.destroy(); - } - } + logger.error("mergeMp4超时且文件未生成,强制终止进程-------- Over"); + processTerminated.set(true); + process.destroyForcibly(); } + } catch (Exception e) { + logger.error("mergeMp4执行异常", e); + processTerminated.set(true); + process.destroyForcibly(); } + // 删除源文件的逻辑 + String sourceFlvPath = recordPath+ File.separator + + flvRecord.getStream().getDayRecord().getDay() + File.separator + + flvRecord.getStream().getStreamId() + File.separator + flvRecord.getFlv(); + File sourceFlvFile = new File(sourceFlvPath); + if(Objects.nonNull(completedProcess)) { // 检查进程是否成功结束 if (completedProcess.exitValue() == 0) { logger.info("进程成功结束!"); + // 正常完成时删除源文件 + if (sourceFlvFile.exists()) { + FileUtil.deleteFile(sourceFlvFile); + logger.info("转换成功,已删除源文件: {}", sourceFlvPath); + } } else { logger.info("进程失败,退出码 {} " ,completedProcess.exitValue()); + // 进程失败时保留源文件 + logger.info("转换失败,保留源文件: {}", sourceFlvPath); + } + } else { + // 超时情况下的处理 + String fileName = recordPath+ File.separator + + flvRecord.getStream().getDayRecord().getDay() + File.separator + + flvRecord.getStream().getStreamId() + File.separator +flvRecord.getStartTime() + ".mp4"; + File file = new File(fileName); + + if(file.exists() && file.length() > 0){ + logger.info("mergeMp4超时但文件已生成,标记为完成-------- Over"); + // 超时但文件已生成,删除源文件 + if (sourceFlvFile.exists()) { + FileUtil.deleteFile(sourceFlvFile); + logger.info("超时但转换成功,已删除源文件: {}", sourceFlvPath); + } + } else { + logger.error("mergeMp4超时且文件未生成,强制终止进程-------- Over"); + // 超时且文件未生成,保留源文件 + logger.info("超时且转换失败,保留源文件: {}", sourceFlvPath); } } @@ -126,7 +163,12 @@ public class ProcessService { List listCommand = new ArrayList<>(); listCommand.add(ffmpeg); // ffmpeg 路径 - listCommand.add(" -timeout 3000000 -rw_timeout 5000000 -i "); +// listCommand.add("-timeout"); +// listCommand.add("3000000"); +// listCommand.add("-rw_timeout"); +// listCommand.add("5000000"); + listCommand.add("-i"); + // listCommand.add(" -timeout 3000000 -rw_timeout 5000000 -i "); listCommand.add(streamUrl); // 流地址 listCommand.add("-vf"); listCommand.add("fps=1"); @@ -140,6 +182,14 @@ public class ProcessService { ProcessBuilder pb = new ProcessBuilder(listCommand); pb.redirectErrorStream(true); Process process = pb.start(); + try { + if (!process.waitFor(30, TimeUnit.SECONDS)) { + process.destroyForcibly(); + // 处理超时逻辑 + logger.info("takePic {} 超时", listCommand); + } + }catch (Exception ignore) { + } loggingService.execute(new Runnable() { @Override diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index e356c1d..9852e9d 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -1,14 +1,14 @@ #公司环境 -#spring.application.name=stream_server -#server.port = 9011 -#srs.splitPath=/data/java/srs/stream_server/temp -#srs.targetPath=/data/java/srs/srs/trunk/objs/nginx/html/recording -#ffmpeg=ffmpeg -#recordPath=/data/java/srs/srs/trunk/objs/nginx/html/record -#livedates=8 -#cangneiwai=false -#srs.domain = "" -#srs.name = "" +spring.application.name=stream_server +server.port = 9011 +srs.splitPath=/data/java/srs/stream_server/temp +srs.targetPath=/data/java/srs/srs/trunk/objs/nginx/html/recording +ffmpeg=ffmpeg +recordPath=/data/java/srs/srs/trunk/objs/nginx/html/record +livedates=1 +cangneiwai=true +srs.domain="stream.t-aaron.com" +srs.name="stream.t-aaron.com" # #大数据局 #spring.application.name=stream_server @@ -36,17 +36,17 @@ ##容器化部署 #通过注入 -srs.domain = STREAM.t-aaron.com -#通过注入 -srs.name = STREAM -spring.application.name=stream_server -server.port = 8080 -#零时文件 -srs.splitPath=/data/temp -#拍照 + 录像 -srs.targetPath=/data/recording -ffmpeg=ffmpeg -# -recordPath=/data/record -livedates=8 -cangneiwai=true \ No newline at end of file +#srs.domain = STREAM.t-aaron.com +##通过注入 +#srs.name = STREAM +#spring.application.name=stream_server +#server.port = 8080 +##零时文件 +#srs.splitPath=/data/temp +##拍照 + 录像 +#srs.targetPath=/data/recording +#ffmpeg=ffmpeg +## +#recordPath=/data/record +#livedates=8 +#cangneiwai=true \ No newline at end of file