You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

mediaDevices.getUserMedia在部分设备返回横屏视频的问题求助

getUserMedia 竖屏视频采集跨设备兼容问题

问题核心

使用getUserMedia获取后置摄像头视频流时,部分设备(如iPhone XR、Redmi Note 12)能返回预期的竖屏视频,但iPhone 14 Pro、Google Pixel 6等设备返回横屏视频;调整宽高约束后,画面会被放大填充而非原生竖屏采集,设置aspectRatio: {exact: 1.5}也会出现同样的拉伸问题。

问题原因

  1. 硬件与系统差异:多数旗舰设备的后置摄像头传感器为横置设计,系统会根据设备方向自动添加旋转元数据,但不同浏览器/系统对getUserMedia约束的解析逻辑不一致,导致部分设备忽略竖屏宽高比要求,返回原生横屏分辨率。
  2. 约束参数冲突:强制指定exact级别的宽高比或分辨率时,若设备硬件不支持该参数,会自动拉伸/裁剪画面以匹配约束,导致画面放大变形。

解决方案

1. 优化约束参数,避免强制匹配

优先使用ideal级别的宽高约束,引导设备返回接近竖屏的原生分辨率,不强制exact宽高比:

const getVideo = () => {
  if (!navigator.mediaDevices) return;

  navigator.mediaDevices.getUserMedia({
    video: {
      facingMode: "environment",
      height: { ideal: 4096, max: 4096 }, // 优先高分辨率竖屏高度
      width: { ideal: 2160, max: 2160 },  // 对应竖屏宽度
      aspectRatio: { ideal: 9/16 }        // 竖屏宽高比(宽/高)
    }
  })
  .then((stream) => {
    const video = videoRef;
    video.srcObject = stream;

    // 监听元数据加载,处理视频旋转
    video.onloadedmetadata = () => {
      const videoTrack = stream.getVideoTracks()[0];
      const trackSettings = videoTrack.getSettings();
      // 获取视频原生旋转角度(部分设备返回90/270表示需要旋转)
      const orientation = trackSettings.videoOrientation || 0;

      // 根据旋转角度调整视频显示
      if (orientation === 90 || orientation === 270) {
        // 旋转视频并修正宽高,避免拉伸
        video.style.transform = `rotate(${orientation}deg)`;
        video.style.transformOrigin = 'center center';
        // 交换视频的宽高设置,匹配旋转后的显示
        video.style.width = `${video.videoHeight}px`;
        video.style.height = `${video.videoWidth}px`;
      }
    };
  })
  .catch((err) => {
    console.error(`[Event] Error: ${err}`);
  });
};

2. 动态处理视频旋转元数据

部分设备返回的视频帧本身是横屏的,但带有videoOrientation元数据(表示需要旋转90/270度才能正确显示竖屏)。通过读取该元数据,对video元素应用旋转变换,即可得到正确的竖屏画面,同时避免强制约束导致的拉伸。

3. 兼容低版本设备

若部分设备不支持videoOrientation,可通过对比视频的实际宽高判断是否需要旋转:

video.onloadedmetadata = () => {
  // 若视频实际宽度大于高度,说明是横屏采集,需要旋转90度
  if (video.videoWidth > video.videoHeight) {
    video.style.transform = 'rotate(90deg)';
    video.style.transformOrigin = 'center center';
    video.style.width = `${video.videoHeight}px`;
    video.style.height = `${video.videoWidth}px`;
  }
};

关键注意点

  • 不要依赖屏幕宽高比判断采集方向:设备屏幕方向可能与摄像头采集方向不一致(比如用户旋转设备但锁定屏幕)。
  • 避免使用exact约束:除非明确知道目标设备支持该分辨率/宽高比,否则会触发设备的拉伸逻辑。
  • 必须在loadedmetadata事件中处理旋转:视频元数据加载完成后才能获取到正确的宽高和旋转信息。

内容的提问来源于stack exchange,提问作者MercurialG

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 03:26:21