Просмотр исходного кода

直接返回mp4格式文件路径-推流失败终止任务

xujunwei 6 месяцев назад
Родитель
Сommit
8c68064fc0
1 измененных файлов с 40 добавлено и 9 удалено
  1. 40 9
      app.py

+ 40 - 9
app.py

@@ -456,6 +456,7 @@ class StreamParams(BaseModel):
     device: str = ""
     save_local: bool = False  # 是否保存到本地文件
     skip_connectivity_test: bool = True  # 是否跳过连通性测试
+    stop_on_stream_error: bool = True  # 推流失败时是否停止任务
     # 可根据需要补充更多参数
 
 def yolov12_stream_worker(params_dict, task_id):
@@ -516,6 +517,7 @@ def yolov12_stream_worker(params_dict, task_id):
     iou = params_dict.get('iou', 0.7)
     imgsz = params_dict.get('imgsz', 640)
     device = params_dict.get('device', '')
+    stop_on_stream_error = params_dict.get('stop_on_stream_error', True)
 
     # 全局变量用于存储进程引用
     ffmpeg_process = None
@@ -562,6 +564,19 @@ def yolov12_stream_worker(params_dict, task_id):
             print(f"任务 {task_id} 启动ffmpeg失败: {e}")
             retry_count += 1
 
+            # 检查是否是严重的推流错误
+            error_msg_lower = str(e).lower()
+            if any(keyword in error_msg_lower for keyword in [
+                "broken pipe", "connection refused", "connection reset", 
+                "network is unreachable", "no route to host", "timeout", "permission denied"
+            ]):
+                print(f"任务 {task_id} 检测到严重推流错误: {e}")
+                if stop_on_stream_error:
+                    print(f"任务 {task_id} 推流失败,停止重试")
+                    return False
+                else:
+                    print(f"任务 {task_id} 推流失败,但继续重试")
+
             # 如果是第一次失败且当前使用的是简单配置,尝试切换到高级配置
             if retry_count == 1 and ffmpeg_cmd == simple_ffmpeg_cmd:
                 print(f"任务 {task_id} 简单配置失败,尝试使用高级配置")
@@ -653,6 +668,8 @@ def yolov12_stream_worker(params_dict, task_id):
                 }
         elif params_dict.get('skip_connectivity_test', False):
             print(f"任务 {task_id} 跳过连通性测试,直接开始推流")
+        else:
+            print(f"任务 {task_id} 非RTMP推流或保存到本地,跳过连通性测试")
         
         model = YOLO(model_path)
         cap = cv2.VideoCapture(source)
@@ -773,6 +790,11 @@ def yolov12_stream_worker(params_dict, task_id):
                         # 检查是否是partial file错误
                         if "partial file" in stderr_output.lower():
                             print(f"任务 {task_id} 检测到partial file错误,这通常表示视频文件写入不完整")
+                            if stop_on_stream_error:
+                                print(f"任务 {task_id} 推流失败,停止任务")
+                                break
+                            else:
+                                print(f"任务 {task_id} 推流失败,但继续尝试重启")
                         
                         # 尝试重启ffmpeg进程
                         print(f"任务 {task_id} 尝试重启ffmpeg进程...")
@@ -805,18 +827,27 @@ def yolov12_stream_worker(params_dict, task_id):
                             # 检查是否是partial file错误
                             if "partial file" in stderr_output.lower():
                                 print(f"任务 {task_id} 检测到partial file错误,这通常表示视频文件写入不完整")
-                                # 对于partial file错误,尝试重启ffmpeg进程
-                                print(f"任务 {task_id} 尝试重启ffmpeg进程...")
-                                cleanup_process()
-                                if start_ffmpeg():
-                                    print(f"任务 {task_id} ffmpeg进程重启成功,继续处理")
-                                    continue
-                                else:
-                                    print(f"任务 {task_id} ffmpeg进程重启失败,停止处理")
+                                if stop_on_stream_error:
+                                    print(f"任务 {task_id} 推流失败,停止任务")
                                     break
+                                else:
+                                    print(f"任务 {task_id} 推流失败,但继续尝试重启")
                     except Exception as stderr_error:
                         print(f"任务 {task_id} 读取ffmpeg错误输出时出错: {stderr_error}")
                     
+                    # 检查是否是严重的推流错误
+                    error_msg_lower = str(e).lower()
+                    if any(keyword in error_msg_lower for keyword in [
+                        "broken pipe", "connection refused", "connection reset", 
+                        "network is unreachable", "no route to host", "timeout"
+                    ]):
+                        print(f"任务 {task_id} 检测到严重推流错误: {e}")
+                        if stop_on_stream_error:
+                            print(f"任务 {task_id} 推流失败,停止任务")
+                            break
+                        else:
+                            print(f"任务 {task_id} 推流失败,但继续尝试重启")
+                    
                     # 尝试重启ffmpeg进程
                     print(f"任务 {task_id} 尝试重启ffmpeg进程...")
                     cleanup_process()
@@ -853,7 +884,7 @@ def yolov12_stream_worker(params_dict, task_id):
         elif "Permission denied" in error_msg:
             error_msg += " - 权限不足,请检查推流地址的访问权限"
         elif "partial file" in error_msg.lower():
-            error_msg += " - 视频文件写入不完整,可能原因:1) 磁盘空间不足 2) 网络中断 3) 推流服务器异常 4) ffmpeg进程被意外终止。建议:1) 检查磁盘空间 2) 检查网络连接 3) 重启推流服务器 4) 使用save_local=true先保存到本地文件测试"
+            error_msg += " - 视频文件写入不完整,可能原因:1) 磁盘空间不足 2) 网络中断 3) 推流服务器异常 4) ffmpeg进程被意外终止。建议:1) 检查磁盘空间 2) 检查网络连接 3) 重启推流服务器 4) 使用save_local=true先保存到本地文件测试 5) 设置stop_on_stream_error=false继续尝试重启"
         
         # 记录详细的调试信息
         print(f"任务 {task_id} 调试信息:")