#!/bin/bash # 快速RTSP连接测试脚本 # 专门针对Docker环境中的RTSP连接问题 set -e # 颜色定义 RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' print_info() { echo -e "${GREEN}[INFO]${NC} $1" } print_warn() { echo -e "${YELLOW}[WARN]${NC} $1" } print_error() { echo -e "${RED}[ERROR]${NC} $1" } print_debug() { echo -e "${BLUE}[DEBUG]${NC} $1" } # 从配置文件读取RTSP URLs get_rtsp_urls() { if [[ -f "config.json" ]]; then grep -o '"rtsp://[^"]*"' config.json | sed 's/"//g' else echo "rtsp://218.94.57.146:40007/rtp/44010200492000000074_34020000001320000001" echo "rtsp://218.94.57.146:40007/rtp/44010200492000000164_34020000001320000001" fi } # 快速测试单个RTSP地址 quick_test_rtsp() { local url=$1 local host=$(echo $url | sed -n 's|rtsp://\([^:]*\):\([0-9]*\)/.*|\1|p') local port=$(echo $url | sed -n 's|rtsp://\([^:]*\):\([0-9]*\)/.*|\2|p') echo "" print_info "🔍 快速测试: $url" print_debug "主机: $host, 端口: $port" # 检查是否为IP地址 local is_ip=false if [[ $host =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then is_ip=true print_debug "检测到IP地址,跳过DNS解析" fi # 1. ping测试 echo -n " Ping测试: " if ping -c 1 -W 3 $host >/dev/null 2>&1; then echo -e "${GREEN}✅ 成功${NC}" else echo -e "${RED}❌ 失败${NC}" fi # 2. DNS解析(仅对域名进行) if [[ "$is_ip" == "false" ]]; then echo -n " DNS解析: " local ip=$(nslookup $host 2>/dev/null | grep -A 1 "Name:" | grep "Address:" | awk '{print $2}' | head -1) if [[ -z "$ip" ]]; then ip=$(dig +short $host 2>/dev/null | head -1) fi if [[ -n "$ip" ]]; then echo -e "${GREEN}✅ $ip${NC}" else echo -e "${RED}❌ 失败${NC}" return 1 fi else echo -e " IP地址: ${GREEN}✅ $host(无需DNS解析)${NC}" fi # 3. 端口连通性 (多种方法) echo -n " 端口连通: " local port_ok=false # 方法1: nc if command -v nc >/dev/null 2>&1 && timeout 5 nc -z $host $port 2>/dev/null; then port_ok=true # 方法2: telnet elif command -v telnet >/dev/null 2>&1 && timeout 5 bash -c "echo '' | telnet $host $port" 2>/dev/null | grep -q "Connected"; then port_ok=true # 方法3: bash内置 elif timeout 5 bash -c "exec 3<>/dev/tcp/$host/$port && exec 3<&-" 2>/dev/null; then port_ok=true fi if [[ "$port_ok" == "true" ]]; then echo -e "${GREEN}✅ 端口$port可达${NC}" else echo -e "${RED}❌ 端口$port不可达${NC}" return 1 fi # 4. RTSP协议测试 echo -n " RTSP协议: " if command -v nc >/dev/null 2>&1; then local rtsp_response=$(timeout 3 bash -c "echo -e 'OPTIONS $url RTSP/1.0\r\nCSeq: 1\r\nUser-Agent: QuickTest\r\n\r\n' | nc $host $port 2>/dev/null" || echo "") if [[ "$rtsp_response" == *"RTSP/1.0"* ]]; then echo -e "${GREEN}✅ RTSP服务正常${NC}" local status=$(echo "$rtsp_response" | head -1 | awk '{print $2}') print_debug " 响应状态: $status" elif [[ -n "$rtsp_response" ]]; then echo -e "${YELLOW}⚠️ 非标准响应${NC}" print_debug " 响应内容: $(echo "$rtsp_response" | head -1 | tr -d '\r\n')" else echo -e "${YELLOW}⚠️ 无响应(可能需要认证)${NC}" fi else echo -e "${BLUE}ℹ️ 跳过(缺少nc工具)${NC}" fi return 0 } # 测试Docker容器内的连接 test_in_docker() { print_info "🐳 测试Docker容器内连接..." if ! docker ps | grep -q jtjai_media; then print_warn "jtjai_media容器未运行" return 1 fi local urls=($(get_rtsp_urls)) for url in "${urls[@]}"; do local host=$(echo $url | sed -n 's|rtsp://\([^:]*\):\([0-9]*\)/.*|\1|p') local port=$(echo $url | sed -n 's|rtsp://\([^:]*\):\([0-9]*\)/.*|\2|p') echo "" print_info "容器内测试: $url" # 检查是否为IP地址 local is_ip=false if [[ $host =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then is_ip=true fi # 容器内DNS测试(仅对域名) if [[ "$is_ip" == "false" ]]; then echo -n " 容器DNS: " if docker exec jtjai_media nslookup $host >/dev/null 2>&1; then local container_ip=$(docker exec jtjai_media nslookup $host 2>/dev/null | grep -A 1 "Name:" | grep "Address:" | awk '{print $2}' | head -1) echo -e "${GREEN}✅ $container_ip${NC}" else echo -e "${RED}❌ 失败${NC}" fi else echo -e " IP地址: ${GREEN}✅ $host(无需DNS解析)${NC}" fi # 容器内端口测试 echo -n " 容器端口: " if docker exec jtjai_media timeout 5 nc -z $host $port 2>/dev/null; then echo -e "${GREEN}✅ 可达${NC}" else echo -e "${RED}❌ 不可达${NC}" fi done } # 主函数 main() { clear echo "" print_info "================================================" print_info "🚀 RTSP连接快速诊断工具" print_info "================================================" # 显示系统信息 echo "" print_info "📋 系统信息:" echo " 主机名: $(hostname)" echo " 操作系统: $(uname -s) $(uname -r)" echo " 当前用户: $(whoami)" echo " 工作目录: $(pwd)" # 显示网络信息 echo "" print_info "🌐 网络信息:" echo " 外网IP: $(timeout 3 curl -s ifconfig.me 2>/dev/null || echo '获取失败')" echo " 默认网关: $(ip route | grep default | awk '{print $3}' | head -1)" echo " DNS服务器: $(cat /etc/resolv.conf | grep nameserver | awk '{print $2}' | head -3 | tr '\n' ' ')" # 获取RTSP URLs local urls=($(get_rtsp_urls)) print_info "📡 发现 ${#urls[@]} 个RTSP流地址" # 测试宿主机连接 echo "" print_info "🖥️ 宿主机连接测试:" local success_count=0 for url in "${urls[@]}"; do if quick_test_rtsp "$url"; then ((success_count++)) fi done echo "" print_info "📊 测试结果: ${success_count}/${#urls[@]} 成功" # 根据结果给出建议 if [[ $success_count -gt 0 ]]; then print_info "🎉 基本连接正常!现在可以启动Docker服务了" echo "" read -p "是否立即启动Docker服务? (y/n) " -n 1 -r echo "" if [[ $REPLY =~ ^[Yy]$ ]]; then print_info "启动Docker服务..." exec ./docker-start.sh fi fi # 测试Docker容器连接 echo "" test_in_docker # 显示建议 echo "" print_info "💡 IP直连优化建议:" if [[ $success_count -gt 0 ]]; then echo " ✅ 宿主机连接正常" echo " 🔧 Docker环境优化:" echo " 1. 使用host网络模式 (--network host)" echo " 2. 增加连接超时设置 (connection_timeout_seconds: 15)" echo " 3. 启用IP直连模式 (-e USE_IP_DIRECT=1)" echo " 4. 启用调试模式 (-e RTSP_DEBUG=1)" else echo " ❌ 宿主机连接存在问题" echo " 🔧 建议检查:" echo " 1. 网络连接状态" echo " 2. 防火墙设置 (端口40007)" echo " 3. RTSP服务器状态" echo " 4. 本地路由配置" fi echo "" print_info "🛠️ IP直连优化命令:" echo " 启动优化的Docker服务: ./docker-start.sh" echo " 手动运行容器:" echo " docker run -d --name jtjai_media --network host \\" echo " -e RTSP_DEBUG=1 -e USE_IP_DIRECT=1 \\" echo " -v \"\$(pwd)/output:/app/output\" \\" echo " -v \"\$(pwd)/config.json:/app/config.json:ro\" jtjai_media:latest" echo " 查看容器日志: docker logs -f jtjai_media" echo " 停止容器: docker stop jtjai_media" echo "" print_info "✅ 诊断完成!" } # 执行主函数 main