严重修复:图片压缩参数被应用到了视频上,导致视频播不了 (#56)
用户报(2026-11-05):「你好像把 .mp4 后面也带上了问号,写成了 1600
这样的参数…你刚才没有进行图片压缩的时候,我自己播放好像还是好的。
是你更新了这个功能之后,出了这个问题。」
用户完全正确,这是我的错。
根因:media.php 只看 $imgW,没判是不是图片:
Storage::read($familyId, $key, $imgW > 0 ? $OssSizes[$imgW] : );
⇒ 视频 URL 带 ?w=1600 后,给 .mp4 对象传了
x-oss-process=image/resize,l_1600
⇒ OSS 图片处理服务对非图片返回错误内容
⇒ <video> 拿不到有效数据 ⇒ 播不了
三道防线:
1. _attachments.php(直接触发点)
原来对所有附件都传 w=1600。改为 $attKind === image 才传。
视频只传 v(版本号,破缓存用)。
2. media.php(核心防线)
$imgW 与 $isImageKey 绑定,只有图片才允许压缩。
$isImageKey 判定提前到 Storage::read 之前,
并扩到扩展名兜底(jpg/png/webp...),
视频/文档扩展名强制 false。
3. media_url()(前置防线)
生成 URL 时按扩展名过滤:非图片自动去掉 w。
这样即使调用方传错,URL 里也不会出现无效参数。
验证(模拟事故场景,URL 带 ?w=1600 请求 .mp4):
HTTP 206,Content-Type: video/mp4
无 hvc1,含 avc1
ffprobe: h264/yuv420p,2.19MB ✅ 正常
media_url 生成视频 URL:...mp4&v=2295119(无 w)
media_url 生成图片 URL:...jpg&w=1600&v=609017(有 w)
This commit is contained in:
@@ -123,6 +123,26 @@ function media_url(?string $key, array $extra = [], int $ver = 0): string
|
||||
return $key;
|
||||
}
|
||||
$q = array_merge(['k' => ltrim($key, '/')], $extra);
|
||||
|
||||
/* 🔴🔴 #56 严重修复(用户 2026-11-05:「你好像把 .mp4 后面也带上了问号,
|
||||
写成了 1600 这样的参数…是你更新了这个功能之后,出了这个问题」):
|
||||
|
||||
**`w`(压缩档位)只允许给图片。** 给视频传
|
||||
`x-oss-process=image/resize,l_1600` 会让 OSS 图片处理服务
|
||||
对非图片返回错误内容 ⇒ `<video>` 播不了。
|
||||
|
||||
这里用扩展名判断(只有 key、没有 MIME):
|
||||
· 图片扩展名 → 保留 w
|
||||
· 其它(mp4/pdf…) → **去掉 w**
|
||||
⚠️ `v` 版本号**所有类型都保留**:视频转码后也要靠它破缓存。
|
||||
它只是查询串,不参与 OSS 签名。 */
|
||||
if (isset($q['w'])) {
|
||||
$isImg = (bool)preg_match('#\.(jpe?g|png|gif|webp|bmp|avif|heic)$#i', $key);
|
||||
if (!$isImg) {
|
||||
unset($q['w']);
|
||||
}
|
||||
}
|
||||
|
||||
if ($ver > 0) {
|
||||
$q['v'] = $ver;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user