PHP如何检测浏览器视频支持格式_PHP检测浏览器支持格式技巧【检测】

16次阅读

php无法直接检测浏览器支持的视频格式,因其运行在服务端,无权访问客户端的navigator或video元素;必须由javaScript调用canPlayType()探测后通过ajax将结果传给PHP处理。

PHP如何检测浏览器视频支持格式_PHP检测浏览器支持格式技巧【检测】

PHP 无法直接检测浏览器支持的视频格式——因为这是客户端能力,PHP 运行在服务端,没有访问 navigatorhtmlMediaElement 的权限。

为什么不能用 PHP 直接检测 canPlayType()

常见的误解是想在 PHP 中调用 javascriptcanPlayType() 方法。这不可能:该方法必须在浏览器环境中执行,依赖 video 元素实例和用户代理的实际解码器能力。PHP 没有 dom、没有渲染引擎、不运行在用户设备上。

  • PHP 收到的只是 http 请求头(如 User-Agent),它只反映浏览器型号/版本,不反映编解码器启用状态(比如 chrome 可能因版权策略禁用 H.264)
  • 同一浏览器在不同系统(windows/macos/linux)、不同构建(Chromium vs. official Chrome)、不同插件环境下,支持的格式可能完全不同
  • 现代浏览器还支持通过 MediaCapabilities.decodingInfo() 动态探测,这更无法被 PHP 预知

可行方案:用 JavaScript 探测后回传给 PHP

真正可用的做法是让前端 js 执行探测,再把结果以参数形式发给 PHP(例如 via AJAX 或表单提交)。PHP 负责接收、记录或做后续逻辑(如返回适配的视频 URL)。

典型流程:

立即学习PHP免费学习笔记(深入)”;

  • 页面加载时,JS 创建一个临时 video 元素
  • 对常见 MIME 类型调用 video.canPlayType(type),注意返回值可能是 "probably""maybe" 或空字符串
  • 将结果拼成键值对(如 {"mp4": "probably", "webm": "maybe", "av1": "probably"}
  • 通过 fetch() 发送到 PHP 接口(如 /api/video-capabilities.php
const video = document.createElement('video'); const formats = {   'video/mp4': 'mp4',   'video/webm; codecs="vp9"': 'webm-vp9',   'video/webm; codecs="av1"': 'webm-av1',   'video/quicktime': 'mov' };  const capabilities = {}; for (const [mime, key] of Object.entries(formats)) {   capabilities[key] = video.canPlayType(mime); }  fetch('/api/video-capabilities.php', {   method: 'POST',   headers: { 'Content-Type': 'application/json' },   body: JSON.stringify(capabilities) });

PHP 如何安全接收并使用探测结果

PHP 端只需处理 POST 数据,不做任何“猜测”,只信任前端传来的结果(前提是接口做了基础校验)。

  • 检查 $_SERVER['CONTENT_TYPE'] === 'application/json',再用 json_decode(file_get_contents('php://input'), true) 解析
  • 过滤键名(只允许预设的格式标识如 mp4webm-vp9),避免恶意字段注入
  • 不要把结果存进全局配置或缓存长期复用——用户下次访问可能换了设备或更新了浏览器
  • 典型用途:根据探测结果,在响应 HTML 中选择性输出 标签,或重定向到对应编码的视频流地址
// api/video-capabilities.php if ($_SERVER['REQUEST_METHOD'] !== 'POST' ||      $_SERVER['CONTENT_TYPE'] !== 'application/json') {     http_response_code(400);     exit; }  $data = json_decode(file_get_contents('php://input'), true); if (!is_array($data)) {     http_response_code(400);     exit; }  $allowedKeys = ['mp4', 'webm-vp9', 'webm-av1', 'mov']; $safeCaps = array_intersect_key($data, array_flip($allowedKeys));  // 示例:存入 session(仅本次会话有效) session_start(); $_SESSION['video_capabilities'] = $safeCaps;

替代思路:服务端按 User-Agent 做粗略 fallback

如果完全无法引入前端探测(如纯服务端渲染且不允许加 JS),只能退而求其次,用 $_SERVER['HTTP_USER_AGENT'] 做极简判断——但准确率低,仅适用于兜底。

  • ios safari(含所有 iphone/ipad)几乎只可靠支持 video/mp4(H.264 + AAC)
  • Chrome / edge / firefox 在桌面端通常支持 video/webm(VP9)和 video/mp4;但 android webview 行为不一
  • 不要依赖正则匹配 “Chrome” 就认为支持 AV1——AV1 默认在 Chrome 109+ 启用,且需操作系统支持
  • 这种判断只能用于设置默认格式,绝不能替代前端探测

最可靠的路径永远是:让浏览器自己说它能播什么,而不是你猜它能播什么。JS 探测 + PHP 接收是目前唯一实用闭环,其他全是妥协方案。

text=ZqhQzanResources