wenhongquan преди 1 ден
родител
ревизия
a06d922e05
променени са 4 файла, в които са добавени 179 реда и са изтрити 17 реда
  1. 16 4
      Dockerfile
  2. 98 0
      rtsp-debug.sh
  3. 64 12
      src/rtsp_client.cpp
  4. 1 1
      src/scheduler.cpp

+ 16 - 4
Dockerfile

@@ -6,14 +6,18 @@ ARG BUILDPLATFORM=linux/amd64
 ARG TARGETPLATFORM=linux/amd64
 
 # ============================================
-# 阶段1: 构建环境
+# 阶段1: 构建环境 - 使用国内镜像加速
 # ============================================
-FROM --platform=$BUILDPLATFORM ubuntu:22.04 AS builder
+FROM --platform=$BUILDPLATFORM k8s.device.wenhq.top:8583/docker_r/ubuntu:22.04 AS builder
 
 # 设置环境变量避免交互式提示
 ENV DEBIAN_FRONTEND=noninteractive
 ENV TZ=Asia/Shanghai
 
+# 更换为清华大学镜像源
+RUN sed -i 's@//.*archive.ubuntu.com@//mirrors.tuna.tsinghua.edu.cn@g' /etc/apt/sources.list && \
+    sed -i 's@//.*security.ubuntu.com@//mirrors.tuna.tsinghua.edu.cn@g' /etc/apt/sources.list && apt-get update
+
 # 安装构建依赖
 RUN apt-get update && apt-get install -y \
     build-essential \
@@ -32,7 +36,7 @@ RUN apt-get update && apt-get install -y \
 
 # 使用SourceForge镜像下载Boost 1.82(更稳定的下载源)
 RUN cd /tmp && \
-    wget -q --show-progress https://sourceforge.net/projects/boost/files/boost/1.82.0/boost_1_82_0.tar.bz2/download -O boost_1_82_0.tar.bz2 && \
+    wget -q --show-progress http://thfile.xt.wenhq.top:8083/boost_1_82_0.tar.bz2 -O boost_1_82_0.tar.bz2 && \
     file boost_1_82_0.tar.bz2 && \
     tar -xjf boost_1_82_0.tar.bz2 && \
     cd boost_1_82_0 && \
@@ -61,7 +65,7 @@ RUN mkdir -p build && \
     make -j$(nproc)
 
 # ============================================
-# 阶段2: 运行环境
+# 阶段2: 运行环境 - 使用国内镜像加速
 # ============================================
 FROM ubuntu:22.04
 
@@ -69,6 +73,10 @@ FROM ubuntu:22.04
 ENV DEBIAN_FRONTEND=noninteractive
 ENV TZ=Asia/Shanghai
 
+# 更换为清华大学镜像源
+RUN sed -i 's@//.*archive.ubuntu.com@//mirrors.tuna.tsinghua.edu.cn@g' /etc/apt/sources.list && \
+    sed -i 's@//.*security.ubuntu.com@//mirrors.tuna.tsinghua.edu.cn@g' /etc/apt/sources.list
+
 # 安装运行时依赖
 RUN apt-get update && apt-get install -y \
     libavcodec-dev \
@@ -98,6 +106,10 @@ COPY --from=builder /app/build/jtjai_http_server /app/jtjai_http_server
 COPY --from=builder /app/config.json /app/config.json
 COPY --from=builder /app/video_manager.html /app/video_manager.html
 
+# 复制RTSP调试脚本
+COPY rtsp-debug.sh /app/rtsp-debug.sh
+RUN chmod +x /app/rtsp-debug.sh
+
 # 创建输出目录
 RUN mkdir -p /app/output
 

+ 98 - 0
rtsp-debug.sh

@@ -0,0 +1,98 @@
+#!/bin/bash
+
+# RTSP连接调试脚本
+# 用于诊断Docker环境中的RTSP连接问题
+
+echo "========================================="
+echo "RTSP连接诊断工具"
+echo "========================================="
+
+# RTSP流地址
+RTSP_URL="${1:-rtsp://218.94.57.146:40007/rtp/44010200492000000074_34020000001320000001}"
+echo "测试RTSP流: $RTSP_URL"
+
+# 1. 基础网络连通性测试
+echo ""
+echo "1. 基础网络连通性测试:"
+echo "----------------------------------------"
+HOST=$(echo $RTSP_URL | sed 's/rtsp:\/\///' | cut -d':' -f1)
+PORT=$(echo $RTSP_URL | sed 's/rtsp:\/\///' | cut -d':' -f2 | cut -d'/' -f1)
+
+echo "主机: $HOST"
+echo "端口: $PORT"
+
+# 测试主机可达性
+if ping -c 2 -W 2 $HOST >/dev/null 2>&1; then
+    echo "✓ 主机 $HOST 可达"
+else
+    echo "✗ 主机 $HOST 不可达"
+fi
+
+# 测试端口连通性
+if timeout 5 bash -c "</dev/tcp/$HOST/$PORT" 2>/dev/null; then
+    echo "✓ 端口 $HOST:$PORT 可连接"
+else
+    echo "✗ 端口 $HOST:$PORT 不可连接"
+fi
+
+# 2. 容器网络信息
+echo ""
+echo "2. 容器网络环境:"
+echo "----------------------------------------"
+echo "网络模式: $(if [ -f /.dockerenv ]; then echo 'Docker容器'; else echo '宿主机'; fi)"
+
+if [ -f /.dockerenv ]; then
+    echo "容器网络接口:"
+    ip route show | head -5
+    echo ""
+    echo "DNS配置:"
+    cat /etc/resolv.conf | head -5
+fi
+
+# 3. 环境变量检查
+echo ""
+echo "3. 环境变量:"
+echo "----------------------------------------"
+echo "RTSP_DEBUG: ${RTSP_DEBUG:-未设置}"
+echo "USE_IP_DIRECT: ${USE_IP_DIRECT:-未设置}"
+
+# 4. 使用curl测试RTSP握手
+echo ""
+echo "4. RTSP握手测试:"
+echo "----------------------------------------"
+if command -v curl >/dev/null; then
+    echo "使用curl测试RTSP OPTIONS请求..."
+    timeout 10 curl -v --connect-timeout 5 -X OPTIONS "$RTSP_URL" 2>&1 | head -20
+else
+    echo "curl命令不可用,跳过RTSP握手测试"
+fi
+
+# 5. 使用ffprobe测试
+echo ""
+echo "5. FFmpeg连接测试:"
+echo "----------------------------------------"
+if command -v ffprobe >/dev/null; then
+    echo "使用ffprobe测试流信息获取..."
+    timeout 10 ffprobe -v quiet -print_format json -show_streams \
+        -rtsp_transport tcp \
+        -timeout 5000000 \
+        -stimeout 3000000 \
+        "$RTSP_URL" 2>&1 | head -10
+else
+    echo "ffprobe命令不可用,跳过FFmpeg测试"
+fi
+
+# 6. 网络性能测试
+echo ""
+echo "6. 网络延迟测试:"
+echo "----------------------------------------"
+if ping -c 5 -W 2 $HOST >/dev/null 2>&1; then
+    ping -c 5 $HOST | tail -2
+else
+    echo "无法ping通主机 $HOST"
+fi
+
+echo ""
+echo "========================================="
+echo "诊断完成"
+echo "========================================="

+ 64 - 12
src/rtsp_client.cpp

@@ -154,22 +154,38 @@ bool RTSPClient::initialize_input() {
     
     // 设置RTSP选项(Docker环境优化)
     AVDictionary* options = nullptr;
-    av_dict_set(&options, "rtsp_transport", "tcp", 0);
+    av_dict_set(&options, "rtsp_transport", "tcp", 0);  // 强制使用TCP传输
     
-    // 根据是否为Docker环境调整超时设置
+    // 根据是否为Docker环境调整超时和网络设置
     if (debug_mode) {
-        av_dict_set(&options, "timeout", "15000000", 0);  // Docker环境:15秒连接超时
-        av_dict_set(&options, "stimeout", "10000000", 0);  // 10秒读取超时
-        std::cout << "Docker环境超时配置: 连接15s, 读取50s" << std::endl;
+        // Docker环境专用设置
+        av_dict_set(&options, "timeout", "15000000", 0);  // 15秒连接超时
+        av_dict_set(&options, "stimeout", "20000000", 0);  // 20秒Socket超时
+        av_dict_set(&options, "rw_timeout", "10000000", 0);  // 10秒读写超时
+        av_dict_set(&options, "listen_timeout", "5000000", 0);  // 5秒监听超时
+        
+        // 网络优化参数
+        av_dict_set(&options, "rtsp_flags", "listen", 0);  // 启用监听模式
+        av_dict_set(&options, "fflags", "+discardcorrupt", 0);  // 丢弃损坏的包
+        av_dict_set(&options, "flags", "+low_delay", 0);  // 低延迟模式
+        av_dict_set(&options, "buffer_size", "1048576", 0);  // 1MB缓冲区
+        av_dict_set(&options, "max_delay", "500000", 0);  // 最大延迟500ms
+        
+        // 设置更兼容的User-Agent
+        av_dict_set(&options, "user_agent", "LibVLC/3.0.0 (compatible; RTSP-Client)", 0);
+        
+        std::cout << "Docker环境超时配置: 连接15s, Socket20s, 读写10s" << std::endl;
     } else {
-        av_dict_set(&options, "timeout", "10000000", 0);  // 本地环境:10秒连接超时
-        av_dict_set(&options, "stimeout", "5000000", 0);  // 5秒读取超时
+        // 本地环境设置
+        av_dict_set(&options, "timeout", "10000000", 0);  // 10秒连接超时
+        av_dict_set(&options, "stimeout", "8000000", 0);   // 8秒Socket超时
+        av_dict_set(&options, "user_agent", "RTSP-Client", 0);
     }
     
-    av_dict_set(&options, "max_delay", "1000000", 0);  // 最大延迟1秒
-    av_dict_set(&options, "reorder_queue_size", "10", 0);  // 减小缓冲队列
-    av_dict_set(&options, "buffer_size", "65536", 0);  // 设置缓冲区大小
-    av_dict_set(&options, "user_agent", "RTSP-Client-Docker", 0);  // 设置用户代理
+    // 通用网络优化设置
+    av_dict_set(&options, "reorder_queue_size", "10", 0);  // 减小重排序队列
+    av_dict_set(&options, "analyzeduration", "2000000", 0);  // 分析时长2秒
+    av_dict_set(&options, "probesize", "1048576", 0);  // 探测大小1MB
     
     // 设置超时时间(用于中断回调)
     start_time_us_ = av_gettime();
@@ -184,7 +200,43 @@ bool RTSPClient::initialize_input() {
     if (ret < 0) {
         char error_buf[AV_ERROR_MAX_STRING_SIZE];
         av_strerror(ret, error_buf, sizeof(error_buf));
-        std::cerr << "无法打开RTSP流 " << config_.rtsp_url << ": " << error_buf << std::endl;
+        
+        std::cerr << "===== RTSP连接失败详细信息 =====" << std::endl;
+        std::cerr << "RTSP URL: " << config_.rtsp_url << std::endl;
+        std::cerr << "FFmpeg错误码: " << ret << std::endl;
+        std::cerr << "FFmpeg错误信息: " << error_buf << std::endl;
+        
+        // 根据具体错误类型提供诊断建议
+        switch (ret) {
+            case AVERROR(ECONNREFUSED):
+                std::cerr << "诊断: 连接被拒绝 - RTSP服务可能未运行或端口被防火墙阻止" << std::endl;
+                break;
+            case AVERROR(EHOSTUNREACH):
+                std::cerr << "诊断: 主机不可达 - 检查网络连接和路由配置" << std::endl;
+                break;
+            case AVERROR(ENETUNREACH):
+                std::cerr << "诊断: 网络不可达 - Docker网络配置可能有问题" << std::endl;
+                break;
+            case AVERROR_INVALIDDATA:
+                std::cerr << "诊断: 无效数据 - RTSP流可能不存在或格式不支持" << std::endl;
+                break;
+            case AVERROR(ETIMEDOUT):
+                std::cerr << "诊断: 连接超时 - 网络延迟过高或RTSP服务没有响应" << std::endl;
+                break;
+            default:
+                std::cerr << "诊断: 未知错误 - 请检查RTSP流地址和网络连接" << std::endl;
+                break;
+        }
+        
+        // 添加Docker环境特有的诊断建议
+        if (debug_mode) {
+            std::cerr << "\nDocker环境诊断建议:" << std::endl;
+            std::cerr << "1. 确认使用 network_mode: host" << std::endl;
+            std::cerr << "2. 检查容器内网络访问权限" << std::endl;
+            std::cerr << "3. 尝试在容器内执行: curl -v rtsp://" << config_.rtsp_url.substr(7) << std::endl;
+        }
+        
+        std::cerr << "=====================================" << std::endl;
         
         // 根据错误类型判断是否为快速失败
         if (ret == AVERROR(ECONNREFUSED) || ret == AVERROR(EHOSTUNREACH) || 

+ 1 - 1
src/scheduler.cpp

@@ -460,7 +460,7 @@ void StreamScheduler::task_completion_callback(int stream_index, const RTSPClien
                       << stats.bytes_received << " 字节)";
             break;
         case RTSPClientStatus::STREAM_UNAVAILABLE:
-            std::cout << "流不可用(快速用): " << stats.error_message;
+            std::cout << "流不可用(快速用): " << stats.error_message;
             break;
         case RTSPClientStatus::ERROR_CONNECT:
             std::cout << "连接错误: " << stats.error_message;