From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.ffmpeg.org (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTPS id B165E4E3FF for ; Mon, 9 Jun 2025 19:24:19 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTP id 6419968CEEE; Mon, 9 Jun 2025 22:24:08 +0300 (EEST) Received: from mail-pf1-f176.google.com (mail-pf1-f176.google.com [209.85.210.176]) by ffbox0-bg.ffmpeg.org (Postfix) with ESMTPS id 5B5CC68CDF0 for ; Mon, 9 Jun 2025 22:24:02 +0300 (EEST) Received: by mail-pf1-f176.google.com with SMTP id d2e1a72fcca58-7425bd5a83aso4067632b3a.0 for ; Mon, 09 Jun 2025 12:24:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1749497041; x=1750101841; darn=ffmpeg.org; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date :references:in-reply-to:message-id:from:from:to:cc:subject:date :message-id:reply-to; bh=ypcFIs8RC7i4csPIep9Y/3HDHv8bTtLbBeoQ8pt7K14=; b=AvseiQO8GpOvk56bFAVpTm3QEwIbMOKTBCPcvtoOrWmKjHRgK8U5+nrjv5ryi5rItN hYOUSVW349XgFElDT9IgirPwlUeFE1RQz6PAcO3bSiNGDIneQKCF4tshEZbqJSGHbFMm 6V4yRgtFUKWww0PC3mvYD0pJGNigjm8PgT3e7CKPrzXhOF43ES4XxLwkFMMk9hns5w67 qsckotxnC0wizNQfr4er82z4+bKW0EAjVzmbQZZd/8cG+FE9/kk4ZmG0133JcFvpN28u vFhqe9+hJ/LHANGTYyH8tvjsYaYq3Z21iVIEbCa8uwkVUuK/QtVpvniWde2NolaFZsjk hh1A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749497041; x=1750101841; h=cc:to:mime-version:content-transfer-encoding:fcc:subject:date :references:in-reply-to:message-id:from:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=ypcFIs8RC7i4csPIep9Y/3HDHv8bTtLbBeoQ8pt7K14=; b=a1Ny60TbcKOU/Qmn5ZGBIViuAOjfeifKpF/p7wxEUZ3FYvmzCyDy6RbB6rFja58xLi COhmKjChVGd3/i2+mtkag9nEukKBbu5XrejV3AHQ4CJypuGzgjq72h7cB3jfQMHipzxx UZuM2gI/646YI/K4xP2dJtUuQlr6ewpnF8geIwZYhNAd8TBCi/Q3mU2mYjMPn0E/Uf7H ET515oNxeF3vCLMdx/mYKa4tfAe8aMhGW4Gqf2kfalICdUvMs8YRl0qeyAuhfpAAE5Q/ KGwyFq3brJfucWgVRZ9yTtm6dkemQ9DVEnxM2cSw1n8ixnR0SYoeMhlojZ+idAPU7ncn lFCg== X-Gm-Message-State: AOJu0YwTkt3x9npapBDHjd/qHsTt/wpl5PyvosAEx4LXfeYFPQjBTfEE YdwgUlvQ6pzJ8Ex4xH9SnfamNAJOwIcWZ3+3n91rQqhUiYyaXWKnk62seh23OA== X-Gm-Gg: ASbGncsSNFNCmhZzN0g18DKz953U13Qlg+SmsHHgGiJH44xVoJpCcf5WuKSFyFnalJE C2/L9LZRu0+Nu1V0GNvojJhSEA8ApHk4R6/dIEWU+Ak0BsjD65ahiL80egM/U0r/SwllYG7VklB kb/jZlaGfCBGxEpoRLNB/EMi3wTyG6NrJV0d8uSz7O1d/wD9MzQQWalHwFLY5VAX76i4gg/9Ybl Cm53LL9xxu7EtPrYTiUV+XfwAeBRe0GVOWhWZqxnhgqKQrY4b1ITLt5KHlNQKpH5dG/EtjuA6Vi i9Zvi/WaHyl9Oh8KGUwXQ0+fTvBpamKVZGrgSqPMHcf0RWBvWkgq1QVC206yA1mi7NmPCw== X-Google-Smtp-Source: AGHT+IGohGpA1HQ7K4Uxw21W5oIJEja1blTG75IyjOP9fd6dmgtcMwdsaJHU7zNo0lvTYO7eNbTBAw== X-Received: by 2002:a05:6a20:2446:b0:216:5f68:427b with SMTP id adf61e73a8af0-21ee262a0d0mr20284081637.33.1749497040473; Mon, 09 Jun 2025 12:24:00 -0700 (PDT) Received: from [127.0.0.1] (master.gitmailbox.com. [34.83.118.50]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7482b0c87bdsm6243424b3a.140.2025.06.09.12.24.00 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Mon, 09 Jun 2025 12:24:00 -0700 (PDT) From: softworkz X-Google-Original-From: softworkz Message-Id: <6f370ed59c04005e5b12d41bfa6efd153e0c829e.1749497028.git.ffmpegagent@gmail.com> In-Reply-To: References: Date: Mon, 09 Jun 2025 19:23:46 +0000 Fcc: Sent MIME-Version: 1.0 To: ffmpeg-devel@ffmpeg.org Subject: [FFmpeg-devel] [PATCH 1/3] tools/ffmpeg-sg: Add show-graph wrapper script for Linux X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Cc: softworkz Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: From: softworkz Signed-off-by: softworkz --- tools/ffmpeg-sg | 249 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 249 insertions(+) create mode 100755 tools/ffmpeg-sg diff --git a/tools/ffmpeg-sg b/tools/ffmpeg-sg new file mode 100755 index 0000000000..c8c298f8e0 --- /dev/null +++ b/tools/ffmpeg-sg @@ -0,0 +1,249 @@ +#!/bin/bash +# +# ffmpeg-sg - FFmpeg Show-Graph Wrapper (aka killer feature) +# Show the FFmpeg execution graph in default browser +# +# Copyright (c) 2025 softworkz +# +# This file is part of FFmpeg. +# +# FFmpeg is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# FFmpeg is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with FFmpeg; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# + +set -euo pipefail + +# Check for privilege level +check_privileges() { + # Check if running as root (UID 0) + if [ "$(id -u)" -eq 0 ]; then + echo "Error: This script should not be run as root for security reasons." >&2 + echo "Media processing and browser launching do not require root privileges." >&2 + exit 1 + fi + + # Check if running as sudo + if [ -n "${SUDO_USER:-}" ] || [ -n "${SUDO_UID:-}" ]; then + echo "Error: This script should not be run with sudo for security reasons." >&2 + echo "Please run as a regular user: ./ffmpeg-sg [options]" >&2 + exit 1 + fi + + # Check other privilege indicators + if [ -n "${PKEXEC_UID:-}" ]; then + echo "Error: This script should not be run with elevated privileges (pkexec)." >&2 + exit 1 + fi +} + +# Validate path chars +validate_path() { + local path="$1" + case "$path" in + *[!ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789/_.-]*) + echo "Error: Invalid characters in path: $path" >&2 + return 1 + ;; + esac + return 0 +} + +# Get secure temp folder +get_temp_dir() { + local uid=$(id -u) + local temp_bases=("/tmp" "/var/tmp") + + for base in "${temp_bases[@]}"; do + local temp_dir="$base/ffmpeg-$uid" + + if ! validate_path "$temp_dir"; then + continue + fi + + # Verify perms and owner + if [ -d "$temp_dir" ]; then + local perms=$(stat -c %a "$temp_dir" 2>/dev/null || echo "") + if [ "$perms" != "700" ]; then + echo "Error: Temp directory exists with unsafe permissions ($perms). Expected 700." >&2 + exit 1 + fi + + local owner=$(stat -c %u "$temp_dir" 2>/dev/null || echo "") + if [ "$owner" != "$uid" ]; then + echo "Error: Temp directory not owned by current user." >&2 + exit 1 + fi + else + # Create folder + if ! mkdir -m 700 "$temp_dir" 2>/dev/null; then + continue + fi + fi + + echo "$temp_dir" + return 0 + done + + echo "Error: Unable to determine temp directory." >&2 + exit 1 +} + +# Create HTML filename and pre-create file +create_unique_html_file() { + local temp_dir="$1" + local base_timestamp=$(date '+%Y-%m-%d_%H-%M-%S') + local base_milliseconds=$(date '+%3N') + + local filename="ffmpeg_graph_${base_timestamp}_${base_milliseconds}.html" + local full_path="$temp_dir/$filename" + + if ! validate_path "$full_path"; then + echo "Error: Generated invalid file path." >&2 + exit 1 + fi + + if (set -C; echo "" > "$full_path") 2>/dev/null; then + echo "$full_path" + return 0 + fi + + echo "Error: Could not create unique HTML file." >&2 + exit 1 +} + +# Check for xdg-open +check_xdg_open() { + # Accept only standard system locations - no PATH lookup + local xdg_locations=("/usr/bin/xdg-open" "/bin/xdg-open" "/usr/local/bin/xdg-open") + + for location in "${xdg_locations[@]}"; do + if [ -x "$location" ]; then + echo "$location" + return 0 + fi + done + + echo "Error: xdg-open not found in standard system locations." >&2 + echo "Checked: ${xdg_locations[*]}" >&2 + return 1 +} + +# Launch browser +open_html_in_browser() { + local html_path="$1" + + if [ ! -f "$html_path" ]; then + echo "Warning: HTML file not found: $html_path" >&2 + return 1 + fi + + # Validate again + if ! validate_path "$html_path"; then + echo "Error: Invalid file path for browser: $html_path" >&2 + return 1 + fi + + local xdg_open_path + xdg_open_path=$(check_xdg_open) + if [ $? -ne 0 ]; then + return 1 + fi + + # Launch browser + "$xdg_open_path" "$html_path" /dev/null 2>&1 & + + if [ $? -eq 0 ]; then + echo "Execution graph opened in browser: $html_path" >&2 + return 0 + else + echo "Warning: Could not open '$html_path' in a browser." >&2 + return 1 + fi +} + +# Check for conflicting parameters +check_conflicting_params() { + local args=("$@") + + for arg in "${args[@]}"; do + case "$arg" in + -print_graphs_file) + echo "Error: -print_graphs_file parameter already provided. This script manages graph file generation automatically." >&2 + exit 1 + ;; + -print_graphs_format) + echo "Error: -print_graphs_format parameter already provided. This script uses mermaidhtml format automatically." >&2 + exit 1 + ;; + esac + done +} + +# Cleanup temp file on signal +cleanup_on_signal() { + local html_file="$1" + if [ -f "$html_file" ]; then + rm -f "$html_file" 2>/dev/null || true + fi + exit 130 # 128 + SIGINT +} + +main() { + check_privileges + + # Check if ffmpeg exists in current dir + if [ ! -x "./ffmpeg" ]; then + echo "Error: ./ffmpeg not found or not executable in current directory." >&2 + exit 1 + fi + + # Check params + check_conflicting_params "$@" + + local temp_dir + temp_dir=$(get_temp_dir) + + local html_file + html_file=$(create_unique_html_file "$temp_dir") + + trap "cleanup_on_signal '$html_file'" INT TERM + + # Set umask for file creation + umask 077 + + # Execute ffmpeg with graph printing options and all passed arguments + local ffmpeg_exit_code=0 + ./ffmpeg -print_graphs_file "$html_file" -print_graphs_format mermaidhtml "$@" || ffmpeg_exit_code=$? + + trap - INT TERM + + # Open browser + if [ -f "$html_file" ]; then + local file_size=$(stat -c%s "$html_file" 2>/dev/null || echo 0) + local placeholder_size=34 + + if [ "$file_size" -gt "$placeholder_size" ]; then + open_html_in_browser "$html_file" + else + echo "Warning: FFmpeg completed but no graph data was written." >&2 + fi + else + echo "Warning: FFmpeg completed but no graph file was found." >&2 + fi + + # Exit with ffmpeg exit code + exit $ffmpeg_exit_code +} + +main "$@" -- ffmpeg-codebot _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".