我正在尝试生成视频的屏幕截图。目标是生成与视频的第一帧相同的图像。但是,我遇到的问题是生成的图像被拉伸。
此图像显示左侧的视频,一开始时暂停 - 右侧生成的图像:
注意底部的灰色区域?它被拉伸到比视频更高的高度。
我使用以下代码生成屏幕截图:
示例标记:
<video id="video" height="300" width="320" preload="auto">
<source src="http://domain.com/video.mp4">
</video>
<canvas id="canvas" height="300" width="320"></canvas>
脚本:
// Grab an existing video element, 300px tall, 320px wide.
var video = document.getElementById('video');
// Grab existing canvas, 300px tall, 320px wide.
var canvas = document.getElementById('canvas');
// Wait until video has loaded
video.addEventListener('loadeddata', function() {
var context = canvas.getContext('2d');
// Render using same dimensions.
context.drawImage(video, 0, 0, 320, 300);
}, false);
有人可以告诉我如何避免这种拉伸吗?
答案 0 :(得分:0)
就像<img>
元素一样,<video>
元素的width
和height
属性会调整容器的大小。另一方面,drawImage
方法确实使用了内容。
然后,您必须使用videoElement.videoWidth
和videoElement.videoHeight
属性来检索媒体的宽度和高度(图像元素的或img.naturalWidth
和img.naturalHeight
)。
所以你有两种可能性:
要么以实际尺寸拍摄视频:
var ctx = canvas.getContext('2d');
btn.onclick = function(){
// set your canvas width and height to the media's ones
canvas.width = vid.videoWidth;
canvas.height = vid.videoHeight;
ctx.drawImage(vid, 0,0);
};
<video src="http://vjs.zencdn.net/v/oceans.mp4" width="200" height="100" autoplay controls muted loop id="vid"></video><button id="btn">take a screenshot</button>
<canvas id="canvas"></canvas>
或者,如果您想截取视频元素的屏幕截图,您将面临更多
复杂性,因为您必须伪造默认的object-fit: contain;
CSS属性。这可以通过ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
属性来完成。
您可以找到一种方式here,以及一种更完整的方式here,因此我不会将其包含在此答案中,只需记住使用video.videoWidth
和{{1} } attribute为sourceWidth和sourceHeight。