thinkphp接入七牛云音视频转码与切片必须通过服务端persistentfop发起异步持久化处理,因uploadtoken不支持fops指令,前端js sdk也不解析该参数;avthumb、m3u8等属资源处理操作,需后端调用sdk并显式指定pipeline、校验回调签名,否则静默失败。

ThinkPHP 接入七牛云音视频转码与切片,核心在于「不直传转码参数到前端」,而必须通过服务端调用 PersistentFop 发起异步持久化处理(pfop),否则无法触发 m3u8 切片或 avthumb 转码。所有关键操作都得走后端 SDK,前端只负责上传原始文件。
为什么不能在 uploadToken 里配转码参数?
因为七牛的 uploadToken 支持的 callbackBody 和 saveKey 只管上传归档,不支持音视频处理指令;所谓「上传即转码」是常见误解——实际是上传完成后,再由服务端调用 PersistentFop 触发处理流程。
-
avthumb、m3u8、vframe等操作属于「资源处理(fop)」,不是上传策略的一部分 - 若强行把
fops塞进uploadToken的policy,SDK 会静默忽略,无报错但无效果 - 前端 JS SDK(如
qiniu-js)根本不解析或传递 fops 字段
如何用 ThinkPHP 调用 PersistentFop 实现 m3u8 切片?
关键点:源文件 $key 必须是七牛云上已存在的文件名(不含域名),且需显式指定 pipeline(处理队列名),否则返回 no pipeline specified 错误。
- 先确保已安装官方 SDK:
composer require qiniu/php-sdk - 确认七牛后台已开通并配置好处理队列(如
default或自定义名),在「多媒体处理 > 处理队列」中可见 -
$key示例应为video/123456/20260501/test.mp4,不是https://xxx.com/video/... - fops 字符串示例:
avthumb/m3u8/noDomain/1/segtime/10/vb/500k(注意斜杠不能 URL 编码) - 调用代码片段:
use Qiniu\Auth;
use Qiniu\Processing\PersistentFop;
$auth = new Auth($accessKey, $secretKey);
$persistentFop = new PersistentFop($auth, $bucket);
$fops = 'avthumb/m3u8/noDomain/1/segtime/10/vb/500k';
$notifyUrl = 'https://yourdomain.com/qiniu/pfop-callback';
$force = true;
list($ret, $err) = $persistentFop->execute($key, $fops, $notifyUrl, 'default', $force);
if ($err !== null) {
// 记录 $err->message,常见如 "no pipeline specified" 或 "invalid fops"
}
// $ret['persistentId'] 是后续轮询或回调验证的唯一标识
回调接收与安全验证怎么做?
七牛完成 pfop 后会 POST 到你配置的 notifyUrl,但该请求**不带鉴权头**,必须靠签名验证防伪造——否则攻击者可伪造成功回调,注入脏数据。
- 回调 body 是 JSON,含
code、desc、inputBucket、inputKey、items等字段 - 七牛会在 header 中附带
X-Qiniu-Callback-Signature,格式为AccessKey:base64(hmac-sha1(signingStr, SecretKey)) -
signingStr= 请求 body 原始字符串(非 JSON 解析后) + "\n" + 请求 path(如/qiniu/pfop-callback) - 务必校验
$ret['code'] === 0且签名有效,再更新数据库状态
常见失败原因和调试建议
pfop 失败往往不报具体错误,只返回空或 failed,需要逐层排查。
- 源文件
$key不存在或拼写错误(大小写敏感,路径中多余空格也会导致 404) -
pipeline名字填错或未启用(控制台「处理队列」页确认状态为「运行中」) - fops 参数顺序或值非法,例如
segtime必须是整数秒,vb单位是 k 不是 kb - 目标 bucket 未开启「私有空间」或「镜像回源」等依赖功能(m3u8 切片默认需要公开读)
- 回调地址不可达(用
curl -v模拟 POST 测试,确认能收到请求)
最易被忽略的是:七牛处理结果回调的 inputKey 是原始文件名,而 items[0].key 才是生成的 m3u8 文件名(如 xxx.m3u8),别直接拿 inputKey 当播放地址用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











