求助:如何将Agora云录制双文件合并为单屏并存储到AWS S3
解决方案:合并Agora双视频文件并上传至AWS S3
核心思路
借助FFmpeg实现双视频的分屏/画中画合并,通过Laravel后端完成视频下载、处理、上传全流程,具体分为4个关键步骤:
1. 接收Agora回调并下载视频文件
Agora云录制完成后会向你的Laravel接口发送回调,回调数据的fileList字段包含两个MP4文件的下载地址。先将这两个文件下载到服务器临时目录:
use Illuminate\Support\Facades\Http; // 从Agora回调数据中提取视频URL $videoUrl1 = $callbackData['fileList'][0]['url']; $videoUrl2 = $callbackData['fileList'][1]['url']; // 定义临时存储路径 $tempDir = storage_path('app/temp'); if (!file_exists($tempDir)) mkdir($tempDir, 0755, true); $tempPath1 = $tempDir.'/video1.mp4'; $tempPath2 = $tempDir.'/video2.mp4'; // 下载文件到本地 Http::get($videoUrl1)->save($tempPath1); Http::get($videoUrl2)->save($tempPath2);
2. 用FFmpeg合并双视频为单文件
先安装PHP的FFmpeg扩展包:
composer require php-ffmpeg/php-ffmpeg
以下是左右分屏的合并逻辑(若需要画中画可替换滤镜参数):
use FFMpeg\FFMpeg; $ffmpeg = FFMpeg::create([ 'ffmpeg.binaries' => '/usr/bin/ffmpeg', // 替换为服务器上FFmpeg的实际路径 'ffprobe.binaries' => '/usr/bin/ffprobe', ]); // 加载两个视频文件 $video1 = $ffmpeg->open($tempPath1); $video2 = $ffmpeg->open($tempPath2); // 获取视频基础分辨率(默认两视频分辨率一致,若不一致需先统一缩放) $stream = $video1->getStreams()->first(); $width = $stream->getDimensions()->getWidth(); $height = $stream->getDimensions()->getHeight(); // 生成合并后的分屏视频 $mergedPath = $tempDir.'/merged_'.time().'.mp4'; $video1->filters()->custom( "-i {$tempPath2} -filter_complex '[0:v]scale={$width}:{$height}[left];[1:v]scale={$width}:{$height}[right];[left][right]hstack=inputs=2' {$mergedPath}" ); $video1->save(new \FFMpeg\Format\Video\X264(), $mergedPath);
如果需要画中画效果,将filter_complex参数替换为:
"[0:v]scale={$width}:{$height}[main];[1:v]scale=".($width/4).":".($height/4)."[overlay];[main][overlay]overlay=W-w-10:H-h-10"
3. 上传合并视频到AWS S3
确保Laravel已配置好S3存储驱动(在config/filesystems.php中设置s3相关参数),然后执行上传:
use Illuminate\Support\Facades\Storage; // 上传到S3指定目录 $s3Key = 'call-recordings/'.basename($mergedPath); Storage::disk('s3')->put($s3Key, fopen($mergedPath, 'r')); // 获取S3文件的访问URL(可选) $s3Url = Storage::disk('s3')->url($s3Key);
4. 清理临时文件
处理完成后删除服务器上的临时文件,避免占用磁盘空间:
unlink($tempPath1); unlink($tempPath2); unlink($mergedPath);
注意事项
- 确保服务器已安装FFmpeg,可通过
ffmpeg -version命令验证 - 若Agora返回的两个视频分辨率不一致,需先对低分辨率视频进行缩放,避免合成后画面变形
- 处理大体积视频时建议使用Laravel队列异步执行,避免阻塞HTTP请求
内容的提问来源于stack exchange,提问作者Vatsal Shah
相关产品推荐
相关产品推荐

