PHP通过调用ffmpeg实现视频HLS切片(生成.ts分段和.m3u8索引),再批量上传至对象存储;需确保ffmpeg可用、权限正确、命令安全,并考虑异步处理与断点续传。

一、前提准备:安装 ffmpeg 并确认 PHP 可执行
确保服务器已安装 ffmpeg(Linux 常用:sudo apt install ffmpeg 或从官网编译),并能被 PHP 的 exec()、shell_exec() 调用:
- 在 PHP 中运行
echo shell_exec('ffmpeg -version 2>&1');,有输出说明可用 - 若报错“command not found”,需配置 ffmpeg 全路径(如
/usr/local/bin/ffmpeg) - 确保 PHP 运行用户(如 www-data)有读取源视频、写入切片目录的权限
二、用 ffmpeg 将视频按时间或大小切片(常用 HLS 方式)
推荐使用 HLS(HTTP Live Streaming)标准切片,生成 .ts 分段 + .m3u8 索引文件,兼容性好、适合上传和后续播放:
- 基础命令示例(每 10 秒切一个 .ts):
/usr/local/bin/ffmpeg -i input.mp4 -c:v libx264 -c:a aac -f hls -hls_time 10 -hls_list_size 0 -hls_segment_filename "seg_%03d.ts" index.m3u8 - 生成结果:
index.m3u8(索引)+seg_001.ts、seg_002.ts…(分段文件) - PHP 中安全执行(避免 shell 注入):
$input = escapeshellarg('/path/to/input.mp4');<br> $outputDir = escapeshellarg('/path/to/output/');<br> $cmd = "/usr/local/bin/ffmpeg -i {$input} -c:v libx264 -c:a aac -f hls -hls_time 10 -hls_list_size 0 -hls_segment_filename {$outputDir}seg_%03d.ts {$outputDir}index.m3u8 2>&1";<br> $result = shell_exec($cmd);
三、PHP 批量上传分段文件(如到对象存储)
切片完成后,PHP 读取 index.m3u8 或扫描 seg_*.ts 文件列表,逐个上传:
- 以阿里云 OSS 为例(需安装
aliyun/oss-sdk-php):
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);<br> $bucket = 'your-bucket';<br> $files = glob("/path/to/output/seg_*.ts");<br> foreach ($files as $file) {<br> $key = 'videos/2024/' . basename($file);<br> $ossClient->putObject($bucket, $key, file_get_contents($file));<br> } - 大文件建议用分片上传(
initiateMultipartUpload+uploadPart),但 .ts 通常较小(几 MB),直传更简单 - 别忘了上传
index.m3u8,它是播放入口
四、注意事项与优化建议
实际部署中需关注稳定性与体验:
立即学习“PHP免费学习笔记(深入)”;
- ffmpeg 执行耗时长,务必设置超时(
set_time_limit(0))并考虑异步处理(如队列、Worker 进程) - 切片前建议先探测视频信息:
ffprobe -v quiet -print_format json -show_entries format=duration,input_frames video.mp4,用于预估分段数或校验 - 上传失败需重试机制,记录已上传的分段,支持断点续传(可结合 Redis 记录状态)
- 生产环境禁用
shell_exec?可用 Supervisor 管理独立切片服务,PHP 仅发任务指令(如通过 Redis 或 API)



















