PHP 8需通过shell_exec调用已安装的FFmpeg来合并音频;混音用amix滤镜,多轨输出用-map指定音轨并选MP4/MKV容器;务必escapeshellarg处理路径、校验文件、异步执行防超时。

PHP 8 本身不能直接“调用 FFmpeg 合并音频轨道”,它只是通过执行系统命令来调用外部的 ffmpeg 工具。关键在于:确保服务器已安装 FFmpeg,且 PHP 有权限执行命令,并使用正确的 FFmpeg 命令语法合并多个音频文件(如多轨配音、背景音+人声等)。
确认 FFmpeg 已安装并可被 PHP 调用
在 PHP 中运行以下代码检查是否能找到 ffmpeg:
<?php
$output = shell_exec('which ffmpeg 2>&1');
if (empty($output)) {
die('FFmpeg 未安装或不在 PATH 中');
}
echo "FFmpeg 路径:", $output;
?>
若返回空或报错,请先在服务器上安装 FFmpeg(如 Ubuntu:`sudo apt install ffmpeg`),并确保 PHP 运行用户(如 www-data)有执行权限。
用 FFmpeg 合并多个音频为单轨(混音)
这是最常见需求:把多个 WAV/MP3 等音频文件按时间对齐后混合成一个立体声或单声道输出。PHP 中调用示例:
立即学习“PHP免费学习笔记(深入)”;
- 准备音频路径数组(确保路径安全,无空格或特殊字符,或用 escapeshellarg() 处理)
- 构造命令:用
-i指定每个输入,-filter_complex amix=inputs=N:duration=longest混音 - 添加
-y自动覆盖输出文件,避免交互阻塞
示例代码:
<?php
$audioFiles = [
'/path/to/vocal.mp3',
'/path/to/music.mp3',
'/path/to/sfx.wav'
];
$inputs = '';
foreach ($audioFiles as $file) {
$inputs .= '-i ' . escapeshellarg($file) . ' ';
}
$outputFile = '/tmp/merged_output.mp3';
// 构建命令:3 个输入 → amix=inputs=3
$cmd = "ffmpeg -y $inputs -filter_complex \"amix=inputs=" . count($audioFiles) . ":duration=longest\" " . escapeshellarg($outputFile) . " 2>&1";
$result = shell_exec($cmd);
if (file_exists($outputFile) && filesize($outputFile) > 0) {
echo "合并成功,输出:" . $outputFile;
} else {
echo "失败,FFmpeg 输出:\n" . $result;
}
?>
合并为多轨音频(保留独立声道/轨道)
若需生成含多个音频流的文件(例如 AAC + AC3 双音轨 MP4,或 WAV 中不同声道对应不同音源),需用 -map 显式指定每路输入,并设置对应编码器:
- 每个
-i输入后,用-map X:a:0提取第 X 个文件的第 0 个音频流 - 用
-c:a:0 aac -c:a:1 libmp3lame分别指定各音轨编码器 - 输出格式建议用 MP4 或 MKV(支持多音轨);WAV 不支持多音轨
示例命令(PHP 中拼接):
$cmd = 'ffmpeg -y ' .
'-i ' . escapeshellarg($vocal) . ' ' .
'-i ' . escapeshellarg($music) . ' ' .
'-map 0:a:0 -c:a:0 aac ' .
'-map 1:a:0 -c:a:1 aac ' .
'-shortest ' .
escapeshellarg('/tmp/output_with_dual_audio.mp4');
安全与稳定性注意事项
生产环境必须重视:
- 所有文件路径必须经过
escapeshellarg()处理,防止命令注入 - 避免传入用户可控的原始文件名;应先校验扩展名、MIME 类型、时长(可用 ffprobe 预检)
- 设置超时:用
proc_open()更好控制进程生命周期和资源限制 - 大文件合并建议异步处理(如写入队列,由后台 worker 执行),避免 Web 请求超时
不复杂但容易忽略。



















