窗口resize时,如何更新navigator.mediaDevices.getUserMedia流的宽高约束?
Dynamic Video Stream Resizing Without Stretching Using getUserMedia
Great question! You absolutely can update the media constraints after the initial stream is set up to adjust video dimensions and avoid stretching. Here's a step-by-step solution tailored to your code:
1. Save a Reference to the Video Track
First, you need to grab the video track from your initial stream—this is what we'll modify later when the window resizes:
let videoTrack; // Store the video track for later updates navigator.mediaDevices.getUserMedia({ audio: false, video: { facingMode: 'user', width: window.innerWidth / 2, height: window.innerHeight / 2 } }) .then(stream => { video.srcObject = stream; // Get the first (and only) video track from the stream videoTrack = stream.getVideoTracks()[0]; });
2. Update Constraints on Window Resize
Use the applyConstraints() method on the video track to dynamically adjust its dimensions when the window resizes. This tells the browser to renegotiate the stream with the new constraints, no need to restart the stream:
window.addEventListener('resize', async () => { if (!videoTrack) return; // Exit if the track isn't initialized yet try { // Apply the new width/height constraints await videoTrack.applyConstraints({ width: window.innerWidth / 2, height: window.innerHeight / 2 }); // Optional: Match the video element's display size to the stream's new dimensions // This ensures the video doesn't stretch even if the element was sized differently before video.style.width = `${window.innerWidth / 2}px`; video.style.height = `${window.innerHeight / 2}px`; } catch (error) { console.error('Failed to update video constraints:', error); // Handle cases where the browser can't meet the new constraints (e.g., device limits) } });
Key Notes to Avoid Stretching
applyConstraints()is the standard way: This API is designed for dynamic constraint updates—it won't break the existing stream, just adjust it to fit the new parameters.- Sync video element size with stream constraints: Even if the stream's resolution changes, if your
<video>element's CSS dimensions don't match, you'll still get stretching. Keeping them in sync fixes this. - Preserve aspect ratio (optional): If you want to maintain the video's natural aspect ratio instead of forcing exact window-based dimensions, use
aspectRatioin your constraints:
This lets the browser pick the best resolution that fits your ideal dimensions while maintaining the correct ratio, eliminating stretching entirely.// Initial constraints with aspect ratio lock video: { facingMode: 'user', aspectRatio: 1.777, // 16:9 width: { ideal: window.innerWidth / 2 }, height: { ideal: window.innerHeight / 2 } } // Resize update with aspect ratio preserved await videoTrack.applyConstraints({ aspectRatio: 1.777, width: { ideal: window.innerWidth / 2 }, height: { ideal: window.innerHeight / 2 } });
内容的提问来源于stack exchange,提问作者Samantha
相关产品推荐
相关产品推荐

