Galaxy S20 Chrome浏览器getUserMedia视频流比例异常排查与解决
问题:Galaxy S20 Chrome浏览器中视频流比例异常
问题现象
- 仅搭载Chrome浏览器的Galaxy S20出现视频流比例异常,其余大部分设备显示正常
- 已尝试将
aspectRatio改为9:16、用width/height替代aspectRatio,均未解决问题 - 新版Chrome中裁剪功能失效,无法获取正确的偏移值
相关代码
获取流数据的React代码
useEffect(() => { const getStreamData = async () => { if (videoRef.current) { try { const stream = await navigator.mediaDevices.getUserMedia({ video: { aspectRatio: 3 / 4, facingMode: 'environment', }, }); window.stream = stream; videoRef.current.srcObject = stream; } catch (error) { console.error('Error getStreamData', error); } } }; getStreamData(); return () => { cameraOff(); }; }, []);
样式组件代码
<RootContainer> <Dummy /> <ScanContainer> <StyledVideo playsInline autoPlay controls ref={videoRef}> VideoStream Not Available. </StyledVideo> <StyledCanvas width={1280} height={720} ref={canvasRef} /> </ScanContainer> </RootContainer>
const RootContainer = styled.div` display: flex; flex-direction: column; flex: 1; position: relative; width: 100%; overflow: hidden; color: #363636; z-index: 3; margin-top: 60px; background-color: #001b45 !important; `; const ScanContainer = styled.div` height: 100%; `; const StyledVideo = styled.video` width: 70%; position: absolute; top: 50%; transform: translate(-50%, -50%); left: 50%; `; const StyledCanvas = styled.canvas` width: 70%; position: absolute; top: 50%; transform: translate(-50%, -50%); left: 50%; border: 3px solid silver; `; const Dummy = styled.div` display: block; height: 500px; width: 90%; `;
排查与解决方法
排查步骤
- 确认设备相机支持的参数:在Galaxy S20的Chrome控制台中执行
navigator.mediaDevices.getSupportedConstraints()和enumerateDevices(),查看相机实际支持的宽高比范围——部分设备对aspectRatio单一值的兼容性差,可能返回不符合预期的流。 - 检查视频元素实际渲染尺寸:用浏览器开发者工具查看
StyledVideo的真实宽高,确认是流本身比例异常,还是样式导致的拉伸。 - 测试无约束流:暂时移除
aspectRatio约束,获取原始相机流,判断是否是约束设置引发的问题。
解决方法
- 优化getUserMedia约束:不要指定单一宽高比,改用范围约束搭配理想宽高,让浏览器选择最匹配的流:
video: { facingMode: 'environment', aspectRatio: { ideal: 3/4, min: 0.5, max: 0.8 }, // 3/4=0.75,设置合理范围 width: { ideal: 1280 }, height: { ideal: 960 } // 对应3/4比例的理想分辨率 }
- 强制视频元素保持比例:给
StyledVideo添加固定宽高比样式,避免拉伸变形:
const StyledVideo = styled.video` width: 70%; position: absolute; top: 50%; transform: translate(-50%, -50%); left: 50%; aspect-ratio: 3/4; /* 强制保持设定比例 */ object-fit: contain; /* 保持比例不裁剪,可能留黑边;如需填充容器用cover */ `;
- 同步Canvas与视频比例:Canvas固定1280x720(9/16)和视频3/4比例不匹配,需动态调整:
// 获取流后添加 const track = stream.getVideoTracks()[0]; const settings = track.getSettings(); if (canvasRef.current) { canvasRef.current.width = settings.width; canvasRef.current.height = settings.height; }
同时修改Canvas样式:
const StyledCanvas = styled.canvas` width: 70%; position: absolute; top: 50%; transform: translate(-50%, -50%); left: 50%; border: 3px solid silver; aspect-ratio: auto; /* 跟随自身宽高比 */ object-fit: contain; `;
- 修复Chrome裁剪偏移问题:新版Chrome中绝对定位元素的
offsetLeft/Top不准确,改用getBoundingClientRect()获取真实位置:
const videoRect = videoRef.current.getBoundingClientRect(); // 使用videoRect.left、videoRect.top计算偏移
内容的提问来源于stack exchange,提问作者Daniel Jang
相关产品推荐
相关产品推荐

