如何为通过 MediaMTX 代理的多个 RTSP 流设置 MP4 文件的回退?

问题描述 投票:0回答:1

在尝试使用带有 runOnInit 指令的 FFmpeg 启动回退流时,我的 MediaMTX 设置遇到了障碍。当 runOnInit 触发命令时,环境变量 $RTSP_PORT 和 $MTX_PATH 似乎没有初始化。

我的目标是让 MediaMTX 管理 RTSP 流并通过 FFmpeg 建立后备流,该流在 MediaMTX 启动时自动启动。目的是在任何主要流遇到问题时无缝切换到后备流。

预期行为:

  1. MediaMTX 提供主要 RTSP 流(流 1 和流 2)。
  2. 如果主要流发生故障,RTSP 客户端会平滑过渡到后备流 (fallbackpath)。
  3. 使用 FFmpeg 配置的后备流应利用环境变量($RTSP_PORT 和 $MTX_PATH)动态形成 RTSP URL。
  4. RTSP 客户端通过在主流和后备流之间自动交替来享受不间断的播放。

这是我的 YAML 配置的简化版本:

fallbackpath:
    runOnInit: ffmpeg -re -stream_loop -1 -i "/path/to/fallback/video.mp4" -c:v copy -an -f rtsp "rtsp://127.0.0.1:$RTSP_PORT/$MTX_PATH"
    runOnInitRestart: yes
paths:
    # Primary streams
    stream1:
        source: rtsp://example.com/stream1
        fallback: fallbackpath
    stream2:
        source: rtsp://example.com/stream2
        fallback: fallbackpath
    # More streams...

但是触发runOnInit时似乎$RTSP_PORT和$MTX_PATH不可用,导致错误。

我尝试使用 runOnDemand 指令作为替代方案,但我不确定它是否适合我的场景。不幸的是,runOnInit 和 runOnDemand 配置都失败,导致 MediaMTX 中止。

我希望得到有关确保启动回退流时正确初始化环境变量的指导。

感谢您的协助!

yaml rtsp rtsp-server
1个回答
0
投票

可能不是最干净的选项,可能应该使用“后备:”中内置的 MediaMTX,只是不知道如何,所以使用 Bash 脚本 FFMpeg 和 FFProbe 编写了我自己的版本,我认为它是否在每个 cron 上2-5秒就可以了:

#!/bin/bash

# Function to extract specific variables from .env file
extractEnvVariable() {
    local envFile="${1}"
    local variableName="${2}"
    local variableValue=$(grep "^${variableName}=" "$envFile" | cut -d'=' -f2- | tr -d '"' | tr -d "'")
    echo "$variableValue"
}

# Absolute path to the script directory
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

# Paths to the .env and .env-secrets files
ENV_FILE="$SCRIPT_DIR/../.env"

# Define paths and variables
pathsConfigPath="$SCRIPT_DIR/../config/paths_config.yml"
mediamtxConfigPath="/usr/local/etc/mediamtx.yml"
streamsDirectory="$SCRIPT_DIR/../config/customers/"
LOG_FILE="/var/log/stream_conductor.log"

# Get FFProbe path, ffmpeg path, fallback URL, and stream URI from .env
FFPROBE=$(extractEnvVariable "$ENV_FILE" "FFMPEG_FFPROBE_PATH")
FFMPEG=$(extractEnvVariable "$ENV_FILE" "FFMPEG_FFMPEG_PATH")
FALLBACK=$(extractEnvVariable "$ENV_FILE" "MEDIAMTX_FALLBACK")
STREAM_URI=$(extractEnvVariable "$ENV_FILE" "MEDIAMTX_URL")
STREAM_URI=${STREAM_URI%/}  # Trim trailing forward slash

# Trim trailing forward slash from STREAM_URI
STREAM_URI=${STREAM_URI%/}

# Clear log file
> "$LOG_FILE"

# Check if streams directory exists and is a directory
if [ -d "$streamsDirectory" ]; then
    configContent=""
    # Iterate through customer directories
    customerDirectories=$(ls "$streamsDirectory")
    for customerDirectory in $customerDirectories; do
        if [ "$customerDirectory" != "." ] && [ "$customerDirectory" != ".." ]; then
            customerPath="$streamsDirectory/$customerDirectory"
            # Check if customer directory exists and is a directory
            if [ -d "$customerPath" ]; then
                streamPath="$customerPath/streams/"
                # Check if streams directory exists and is a directory
                if [ -d "$streamPath" ]; then
                    # Loop through stream files
                    for streamFile in "$streamPath"/*; do
                        if [ "$streamFile" != "$streamPath/*" ]; then
                            UUID=$(basename "$streamFile" | cut -c7-) # Assuming stream directory names start with "stream"
                            rtspUrlFile="$streamFile/rtsp_url_$UUID.txt"
                            if [ -f "$rtspUrlFile" ]; then
                                rtspUrl=$(<"$rtspUrlFile")

                                # Check if RTSP stream is active using FFProbe
                                if $FFPROBE -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 "$rtspUrl" >/dev/null 2>&1; then
                                    # Stream is active, use original RTSP URL
                                    configContent+="    $UUID:\n"
                                    configContent+="        source: $rtspUrl\n"
                                else
                                    # Stream is not active, fallback to tsdkfallback
                                    configContent+="    $UUID:\n"
                                    configContent+="        source: $STREAM_URI/tsdkfallback\n"
                                fi
                            fi
                        fi
                    done
                else
                    echo "Streams directory not found or is not a directory: $streamPath" >> "$LOG_FILE"
                fi
            else
                echo "Customer directory not found or is not a directory: $customerPath" >> "$LOG_FILE"
            fi
        fi
    done
    # Add indentation for tsdkfallback entry
    configContent+="    tsdkfallback:\n"
else
    echo "Streams directory not found or is not a directory: $streamsDirectory" >> "$LOG_FILE"
fi

# Write the updated content to paths_config.yml
echo -e "$configContent" > "$pathsConfigPath"

# Load original configuration from mediamtx.yml
mediamtxConfig=$(<"$mediamtxConfigPath")

# Combine mediamtx.yml and configContent
combinedConfig="$mediamtxConfig\npaths:\n$configContent"

# Write the combined configuration to config.yml
outputFilePath="/usr/local/etc/config.yml"
echo -e "$combinedConfig" > "$outputFilePath"

# Check if MediaMTX process is not already running
if ! pgrep -x "mediamtx" >/dev/null; then
    # Start MediaMTX
    /usr/local/bin/mediamtx "$outputFilePath" &
fi

# Check if ffmpeg process is not already running
if ! pgrep -x "ffmpeg" >/dev/null; then
    # Execute ffmpeg command as a standalone process
    "$FFMPEG" -re -stream_loop -1 -i "$FALLBACK" -c:v copy -an -f rtsp "$STREAM_URI/tsdkfallback" &
fi

然后将其输出到 config.yml 中,假设在此特定实例中没有摄像机在进行流传输,因此它已将所有流源默认为后备:

paths:
    71fc528a-a65d-473e-ac9f-ff4751576cce:
        source: rtsp://localhost:8554/tsdkfallback
    a34dd062-087d-4a68-99d0-612bc4478910:
        source: rtsp://localhost:8554/tsdkfallback
    ab1ac337-e137-4ea1-a4a8-34843abeeffe:
        source: rtsp://localhost:8554/tsdkfallback
    add118ab-1f19-45ce-913d-59e242de3e08:
        source: rtsp://localhost:8554/tsdkfallback
    c5908bd6-9da6-44b2-8ffa-57af78ed01bd:
        source: rtsp://localhost:8554/tsdkfallback
    dda7a9cb-e348-44ce-98f7-cb224c8e4a9d:
        source: rtsp://localhost:8554/tsdkfallback
    tsdkfallback:
© www.soinside.com 2019 - 2024. All rights reserved.