hello guys
its been a while since my last question here :P
am working right now on PHP script to upload and convert video files to several resolutions ( 360 - 720 ),
here a piece of my php code to convert

move_uploaded_file($file_tmp, 'upload/'.$fileName);
add_to_queue($time,"360-".$fileName,$status="pending");
//where add_to_queue is simple function to add these information to queue table
$cmd = 'ffmpeg -i upload/'.$fileName.' -vf scale=480:360 -c:v libx264 -q:v 1 -strict experimental -c:a aac -b:a 160k convert/360-'.$fileName.' >/dev/null 2>/dev/null &';
shell_exec($cmd);

now everything here is ok and working great, but I need to check if the video encoding is completed and update the "status" column in queue table set it to complete and delete original file in "upload" directory.
another thing , I want only 5 videos for example to be encoded at same time to save server resourses.

Dani AI

Generated

A few practical notes that build on 's post and 's suggestion.

Backgrounding ffmpeg and throwing its output away makes it hard to know when a job finished or failed. A cleaner approach is a small PHP CLI worker (run under systemd/supervisor) that atomically claims a pending DB row, runs ffmpeg synchronously, reports progress back to the queue row, and only deletes the original after verifying the encoded file. This turns your web upload into a simple "add to queue" action and moves all monitoring into the worker.

Suggested workflow (safe, simple, scalable):

  • Insert a queue record with status = pending on upload.
  • Worker atomically claims a job (UPDATE ... WHERE status='pending' ORDER BY id LIMIT 1 inside a transaction or SELECT ... FOR UPDATE).
  • Probe input duration with ffprobe before starting so percent = current_time / total_time can be computed. (ffmpeg.org)
  • Run ffmpeg with -progress pipe:1 (or -progress tcp://...) and parse the key=value lines it emits. Use out_time_ms/out_time to calculate percent; note out_time_ms is reported in microseconds (the name is a historical misnomer), so convert appropriately. (ffmpeg.org)
  • Update the DB progress column from the worker as you parse progress updates, and set status to complete/failed after proc exit and verification. Examples of -progress usage (file/pipe/tcp) are common. (stackoverflow.com)

Minimal PHP worker sketch (safe escaping, reads progress via proc_open):

<?php
$job = claim_job(); // atomically claim one pending row
$duration = (float)trim(shell_exec("ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 " . escapeshellarg($job['in'])));
$cmd = ['ffmpeg','-hide_banner','-y','-i',$job['in'],'-progress','pipe:1',$job['out']];
$descriptors = [0=>['pipe','r'],1=>['pipe','w'],2=>['pipe','w']];
$proc = proc_open($cmd, $descriptors, $pipes);
stream_set_blocking($pipes[1], false);
while (!feof($pipes[1])) {
  $line = trim(fgets($pipes[1]));
  if ($line === '') continue;
  [$k,$v] = explode('=', $line, 2);
  if ($k === 'out_time_ms') {
    $pct = ((float)$v) / ($duration * 1000000) * 100;
    update_job_progress($job['id'], min(100, round($pct,1)));
  }
  if ($k === 'progress' && $v === 'end') break;
}
$exit = proc_close($proc);
// verify output with ffprobe, then set status and unlink original if OK

Use a process manager to run exactly N workers (5 in your case) rather than launching background commands from web requests. proc_open is the recommended way to capture realtime output in PHP. (php.net)

Final cautions: never delete the source until you verify output (size/duration/ffprobe), watch CPU/IO when choosing concurrency, and add robust logging and retry/failure paths.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.