From: softworkz <softwo...@hotmail.com> Signed-off-by: softworkz <softwo...@hotmail.com> --- 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 "<!-- FFmpeg Graph Placeholder -->" > "$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 >/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-requ...@ffmpeg.org with subject "unsubscribe".