PHP实现FFmpeg转码进度百分比获取的技术问询
Let's break this down step by step to enhance your existing scripts and get accurate progress percentages without changing core terminology or code structure.
1. Update ffmpeg.php for Structured Progress Output
Your original command redirects output to progress.txt, but FFmpeg's default console logs aren't ideal for parsing progress. Instead, use FFmpeg's built-in -progress flag to write machine-readable, key-value progress data directly to your log file. This keeps your core execution logic intact while making parsing far simpler:
<?php $image = "input.jpg"; // Replace with your actual image path $music = "audio.mp3"; // Replace with your actual audio path // Modified command to use FFmpeg's progress flag for structured log output $sCmd = "ffmpeg -i ".$image." -i ".$music." -progress progress.txt video.avi"; $proc = popen($sCmd, "r"); // Keep the process running and capture any additional console output if needed while (!feof($proc)) { fgets($proc); } pclose($proc); ?>
Note: The
-progressflag tells FFmpeg to write real-time updates liketotal_durationandout_timeto the specified file in a clean, parsable format—way better than sifting through raw console output.
2. Enhance progress.php to Calculate Progress Percentage
Now we'll read progress.txt, extract the critical timing values, and compute the progress percentage. Here's the refined script:
<?php $progressFile = "progress.txt"; if (file_exists($progressFile)) { $logContent = file_get_contents($progressFile); $lines = explode("\n", $logContent); $totalDuration = 0; $currentTime = 0; // Parse each line to pull total video duration and current processed time foreach ($lines as $line) { $line = trim($line); if (str_starts_with($line, "total_duration=")) { $totalDuration = floatval(str_replace("total_duration=", "", $line)); } elseif (str_starts_with($line, "out_time=")) { // Convert FFmpeg's HH:MM:SS.sss time format to total seconds $timeStr = str_replace("out_time=", "", $line); $currentTime = convertFFmpegTimeToSeconds($timeStr); } } // Calculate and display progress (cap at 100% to avoid edge-case inconsistencies) if ($totalDuration > 0 && $currentTime > 0) { $progressPercentage = min(round(($currentTime / $totalDuration) * 100, 2), 100); echo "Transcode Progress: {$progressPercentage}%"; } else { echo "Transcode starting..."; } } else { echo "Progress file not found. Ensure the FFmpeg process is running."; } // Helper function to convert FFmpeg's time string to a numeric second value function convertFFmpegTimeToSeconds($timeStr) { list($hours, $minutes, $seconds) = explode(":", $timeStr); return ($hours * 3600) + ($minutes * 60) + floatval($seconds); } ?>
Key Details:
- Structured Log Parsing: The
-progressoutput gives us explicittotal_duration(total video length in seconds) andout_time(current processed time in human-readable format). - Time Conversion: The
convertFFmpegTimeToSecondshelper translates FFmpeg's formatted time into a numeric value we can use for percentage calculations. - Safe Calculation: Using
min(..., 100)ensures we never display over 100% progress, even if log data has minor inconsistencies during transcode.
How It Works Together
- When
ffmpeg.phpruns, FFmpeg writes real-time progress updates toprogress.txt. - You can call
progress.php(via AJAX for live updates, or a page refresh loop) to read the log, parse the values, and display the current transcode percentage.
内容的提问来源于stack exchange,提问作者Mr.ZZ

