如何拍摄基于 HTML5-JavaScript 的视频播放器的快照?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13760805/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to take a snapshot of HTML5-JavaScript-based video player?
提问by Ahmed MEZRI
Actually, i have a HTML5 page with JavaScript function that allow me to play a wmv video file. I need to take a snapshot when the video is playing (with pause or without) and saved in any image format JPG or BMP whatever. Any help will appreciate. Thank you.
实际上,我有一个带有 JavaScript 功能的 HTML5 页面,它允许我播放 wmv 视频文件。我需要在视频播放时(有暂停或没有暂停)拍摄快照并以任何图像格式 JPG 或 BMP 保存。任何帮助将不胜感激。谢谢你。
<!DOCTYPE HTML>
<html>
<head>
<title>HTML5 video</title>
<script type="text/javascript">
function checkPlay() {
var myVideo = document.getElementById("myVid");
var ytStr = '<iframe width="500" height="500" src="C:\XA0002.wmv" frameborder="0" allowfullscreen></iframe>';
try {
var canPlay = document.getElementsByTagName('video')[0].canPlayType("video/wmv");
if ((canPlay == "no") || (canPlay == "")) {
myVideo.innerHTML = ytStr;
}
new MediaElement(v, { success: function (media) { media.play(); } });
} catch (err) {
myVideo.innerHTML = ytStr;
}
}
</script>
</head>
<body onload="checkPlay()">
<div id="myVid"/>
</body>
</html>
回答by brianchirls
To copy an video frame to an image file involves properly loading the video, copying the image to a canvas and exporting it to a file. This is totally possible, but there are a few places where you can run into trouble, so let's take it one step at a time.
要将视频帧复制到图像文件涉及正确加载视频、将图像复制到画布并将其导出到文件。这是完全可能的,但是有一些地方可能会遇到麻烦,所以让我们一步一步来。
1) Loading the video
1) 加载视频
To capture the pixels, you need to load the video into a <video>tag, not an iframeor objector embed. And the file needs to come from a web server, which is the same one the web page itself is on (unless you use cross-origin headers, which is complicated and may not work in your browser. This is restricted by the browser for security reasons. Your code loads the video from the local file system, which won't work.
为了捕捉像素,您需要将视频加载到一个<video>标签,而不是一个iframe或object或embed。并且该文件需要来自网络服务器,该服务器与网页本身所在的服务器相同(除非您使用跨域标头,这很复杂并且可能无法在您的浏览器中运行。这是浏览器出于安全考虑而限制的)原因。您的代码从本地文件系统加载视频,这不起作用。
You also need to load the right file format. IE9+ may play WMV, but it's unlikely that any other browser will. If you can, load up multiple sources, using webm, mp4 and ideally ogg/theora.
您还需要加载正确的文件格式。IE9+ 可以播放 WMV,但其他浏览器不太可能播放。如果可以,请使用 webm、mp4 和理想的 ogg/theora加载多个源。
var container = document.getElementById("myVid"),
video = document.createElement('video'),
canCapture = true;
if (!video.canPlayType('video/wmv')) {
/* If you don't have multiple sources, you can load up a Flash fallback here
(like jPlayer), but you won't be able to capture frames */
canCapture = false;
return;
}
video.src = 'myvideo.wmv';
container.appendChild(video);
video.play(); //or put this in a button click handler if you want your own controls
2) Next, create the canvas and a drawing context. You actually don't need to even attach it to the DOM, but you do need to set it to the size at which you want to save the resulting image. For this example, we'll assume you have a fixed dimension in mind, but if you want, you can set it to a multiple of the video size. Just make sure you run that inside a 'loadedmetadata' event on the video, because the video dimensions won't be available right away.
2) 接下来,创建画布和绘图上下文。您实际上甚至不需要将其附加到 DOM,但您确实需要将其设置为要保存结果图像的大小。对于此示例,我们假设您有一个固定的尺寸,但如果您愿意,您可以将其设置为视频尺寸的倍数。只要确保在视频的“loadedmetadata”事件中运行它,因为视频尺寸不会立即可用。
var canvas = document.createElement('canvas');
canvas.width = 640;
canvas.height = 480;
var ctx = canvas.getContext('2d');
// if you want to preview the captured image,
// attach the canvas to the DOM somewhere you can see it.
3) Capture the image to the canvas and save it to a file. Put this code in an onclickevent on a button or inside a timer - however you want to decided when the image gets captured. Use the drawImage method. ([This article] provides a good explanation, including the security concerns. It's the same for video as for an image.)
3) 将图像捕获到画布并将其保存到文件中。将此代码onclick放在按钮上或计时器内的事件中 - 但是您想决定何时捕获图像。使用 drawImage 方法。([本文] 提供了很好的解释,包括安全问题。视频和图像相同。)
//draw image to canvas. scale to target dimensions
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
//convert to desired file format
var dataURI = canvas.toDataURL('image/jpeg'); // can also use 'image/png'
4) Exporting the image file
4) 导出图像文件
The jpg file is now saved as a Data URI, which is a long javascript string representing an encoded version of the full binary file. It's up to you what to do with it. You can place it directly into an imgelement by just setting it to the src: myImage.src = dataUri;.
jpg 文件现在保存为数据 URI,这是一个长 javascript 字符串,表示完整二进制文件的编码版本。这取决于你如何处理它。您只需将其img设置为 src:即可将其直接放入元素中myImage.src = dataUri;。
If you want to save it to a file, you pretty much need to upload it to a server. Here is a good tutorialon how to do that.
如果要将其保存为文件,则几乎需要将其上传到服务器。这是一个关于如何做到这一点的好教程。
As usual, all of the above are restricted to browsers that support it. If you're going to stick to wmv video, you're pretty much limited to Internet Explorer 9+. 6-8 don't support either the video tag or the canvas. If you can add more video formats, you can use Firefox (3.5+) and Chrome.
像往常一样,以上所有内容都仅限于支持它的浏览器。如果您要坚持使用 wmv 视频,那么您几乎只能使用 Internet Explorer 9+。6-8 不支持视频标签或画布。如果您可以添加更多视频格式,则可以使用 Firefox (3.5+) 和 Chrome。
回答by Sijin Parambath
<html>
<body>
<video controls>
<source src="C:/Users/ganesha/Desktop/Aararum.mp4" type="video/mp4"></source>
</video>
<canvas id="canvas" width="640" height="480"></canvas>
<button id="snap" onclick="snap()">Snap Photo</button>
<!-- start the script ... within that declare variables as follows... -->
<script>
var video=document.querySelector('video');
var canvas=document.querySelector('canvas');
var context=canvas.getContext('2d');
var w,h,ratio;
//add loadedmetadata which will helps to identify video attributes
video.addEventListener('loadedmetadata', function() {
ratio = video.videoWidth/video.videoHeight;
w = video.videoWidth-100;
h = parseInt(w/ratio,10);
canvas.width = w;
canvas.height = h;
},false);
function snap() {
context.fillRect(0,0,w,h);
context.drawImage(video,0,0,w,h);
}
</script>
</body>
</html>
回答by Ian Devlin
You can take a copy of the current video and store it in a canvas element using the drawImage()function.
您可以使用该drawImage()函数获取当前视频的副本并将其存储在画布元素中。
I have a complete example whose code you can view at Video/canvas screenshotwhich should set you on the right track.
我有一个完整的示例,您可以在Video/canvas 屏幕截图中查看其代码,这将使您走上正确的轨道。
回答by Chirag Patel
Sample code:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js">
</script>
</head>
<body>
<h2>Upload,Save and Download video </h2>
<form method="POST" action="" enctype="multipart/form-data">
<input type="file" name="video" id="upload"/>
</...>
<script>
var input = document.getElementById('upload');
input.addEventListener('change', function(event){
var file = this.files[0];
var url = URL.createObjectURL(file);
var video = document.createElement('video');
video.src = url;
var snapshot = function(){
var canvas = document.createElement('canvas');
var ctx = canvas.getContext('2d');
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
var img_data = canvas.toDataURL('image/jpg');
var filename = file.name;
var filename = filename.split('.').slice(0, -1).join('.');
document.getElementById("thumb").value = filename;
$.post("thumb-saver.php", {
base:img_data,
output:"thumbnails/"+ filename + '.jpg'
}, function( data ) {
//alert(data);
});
video.removeEventListener('canplay', snapshot);
};
video.addEventListener('canplay', snapshot);
});
</script>
回答by yuanganteng
video mush contained in canvas tag first.
首先包含在画布标签中的视频糊。
like this;
像这样;
<canvas id="target-canvas">
<video id="video-for-thumbs" autoplay src="http://.....></video>
</canvas>
and js like this
和这样的js
setTimeout(function(){
var canvas=$('#target-canvas')[0];
canvas.getContext('2d').drawImage($('#video-for-thumbs')[0],0,0,1000,300);
var f=canvas.toDataURL();
console.log(f);
},200);
data will rendered in base64
数据将以 base64 格式呈现
and if you want get frame in the middle of video, you can increase delay time to run js.
如果你想在视频中间获得帧,你可以增加运行js的延迟时间。
in additional
另外的
you can add play back rate to increase speed of videos to cut waiting time to screenshot just for thumbnail
您可以添加播放速率以提高视频速度以减少等待时间以截取缩略图
$('#video-for-thumbs')[0].playbackRate=9;

