php实现多进程并发转码的核心做法是:使用pcntl_fork()创建子进程,每个子进程独立调用ffmpeg命令行工具处理一个视频文件,父进程通过pcntl_waitpid()等待所有子进程结束并收集退出状态。具体操作时,需限制最大并发数(如5个),将待转码任务放入队列,子进程执行完毕后返回结果,父进程根据结果决定继续派发新任务或终止。这样做能充分利用cpu多核资源,显著提升批量转码效率。

如何控制并发数量避免系统过载
通过维护一个活跃子进程计数器和任务队列来实现并发控制。当活跃进程数达到上限时,父进程暂停派发新任务,等待任一子进程完成;一旦有子进程退出,计数器减一,立即从队列取出下一个任务派发给新子进程。这种机制确保系统负载稳定,防止因同时启动过多FFmpeg进程导致内存溢出或CPU争用。

$max_concurrent = 5;
$task_queue = ['video1.mp4', 'video2.mp4', 'video3.mp4'];
$active_pids = [];
while (!empty($task_queue) || !empty($active_pids)) {
// 如果还有空闲槽位且队列不为空,则派新任务
while (count($active_pids) 0) {
unset($active_pids[$pid]);
} elseif ($pid == 0) {
usleep(100000); // 短暂休眠避免忙等
}
}
echo "All tasks completed.\n";
预期输出:程序依次处理三个视频文件,最终打印“All tasks completed.”。实际行为中,若某个FFmpeg命令失败,$return_var非零,但当前代码未做错误处理,仅继续执行。可通过检查$return_var并在子进程中exit(1)来区分成功与失败。
如何处理子进程退出状态以判断转码成败
在pcntl_wait()获取的$status变量中,使用pcntl_wexitstatus()提取子进程的退出码。FFmpeg正常完成通常返回0,错误时返回非零值。父进程可根据退出码记录日志或重试失败任务。例如,若某子进程返回1,表示输入文件损坏或参数错误,可将其加入失败队列供后续人工干预。

// 修改前文wait部分
$pid = pcntl_wait($status, WNOHANG);
if ($pid > 0) {
$exit_code = pcntl_wexitstatus($status);
if ($exit_code === 0) {
echo "Success: {$active_pids[$pid]}\n";
} else {
echo "Failed: {$active_pids[$pid]} with code $exit_code\n";
// 可加入失败重试逻辑
}
unset($active_pids[$pid]);
}
预期输出:对每个完成的视频,打印“Success: videoX.mp4”或“Failed: videoY.mp4 with code Z”。实际验证中,若传入无效文件名,FFmpeg会报错并返回非零码,此代码能准确捕获并报告。
当某个视频文件路径不存在时会发生什么
若传入的文件路径不存在,FFmpeg命令会立即失败并返回非零退出码(通常为1)。子进程执行exec()后,该非零码会被pcntl_wexitstatus()捕获,父进程打印“Failed: invalid_path.mp4 with code 1”。程序不会崩溃,而是继续处理其他任务,因为错误被隔离在子进程中。这是健壮性设计的关键:单个任务失败不影响整体流程。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











