我正在尝试从表单中的视频文件(mp4,3gp)创建缩略图预览input type='file'
。许多人说这只能在服务器端完成。我发现这很难相信,因为我最近才使用 HTML5 Canvas 和 Javascript 遇到了这个 Fiddle。
唯一的问题是这需要视频存在并且用户在单击按钮以捕获缩略图之前单击播放。我想知道是否有一种方法可以在没有玩家在场且用户单击按钮的情况下获得相同的结果。例如:用户点击文件上传,选择视频文件,生成缩略图。欢迎任何帮助/想法!
我正在尝试从表单中的视频文件(mp4,3gp)创建缩略图预览input type='file'
。许多人说这只能在服务器端完成。我发现这很难相信,因为我最近才使用 HTML5 Canvas 和 Javascript 遇到了这个 Fiddle。
唯一的问题是这需要视频存在并且用户在单击按钮以捕获缩略图之前单击播放。我想知道是否有一种方法可以在没有玩家在场且用户单击按钮的情况下获得相同的结果。例如:用户点击文件上传,选择视频文件,生成缩略图。欢迎任何帮助/想法!
Canvas.drawImage 必须基于 html 内容。
//and code
function capture(){
var canvas = document.getElementById('canvas');
var video = document.getElementById('video');
canvas.getContext('2d').drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
}
这个方案的好处是可以根据视频的时间选择自己想要的缩略图。
最近需要这个,所以我写了一个函数,接收一个视频file
和一个期望的timestamp
,并返回image blob
视频当时的一个。
样品用法:
try {
// get the frame at 1.5 seconds of the video file
const cover = await getVideoCover(file, 1.5);
// print out the result image blob
console.log(cover);
} catch (ex) {
console.log("ERROR: ", ex);
}
功能:
function getVideoCover(file, seekTo = 0.0) {
console.log("getting video cover for file: ", file);
return new Promise((resolve, reject) => {
// load the file to a video player
const videoPlayer = document.createElement('video');
videoPlayer.setAttribute('src', URL.createObjectURL(file));
videoPlayer.load();
videoPlayer.addEventListener('error', (ex) => {
reject("error when loading video file", ex);
});
// load metadata of the video to get video duration and dimensions
videoPlayer.addEventListener('loadedmetadata', () => {
// seek to user defined timestamp (in seconds) if possible
if (videoPlayer.duration < seekTo) {
reject("video is too short.");
return;
}
// delay seeking or else 'seeked' event won't fire on Safari
setTimeout(() => {
videoPlayer.currentTime = seekTo;
}, 200);
// extract video thumbnail once seeking is complete
videoPlayer.addEventListener('seeked', () => {
console.log('video is now paused at %ss.', seekTo);
// define a canvas to have the same dimension as the video
const canvas = document.createElement("canvas");
canvas.width = videoPlayer.videoWidth;
canvas.height = videoPlayer.videoHeight;
// draw the video frame to canvas
const ctx = canvas.getContext("2d");
ctx.drawImage(videoPlayer, 0, 0, canvas.width, canvas.height);
// return the canvas image as a blob
ctx.canvas.toBlob(
blob => {
resolve(blob);
},
"image/jpeg",
0.75 /* quality */
);
});
});
});
}
最近需要这个并做了一些测试并将其降到最低限度,请参阅https://codepen.io/aertmann/pen/mAVaPx
它的工作存在一些限制,但目前的浏览器支持相当不错:Chrome、Firefox、Safari、Opera、IE10、IE11、Android (Chrome)、iOS Safari (10+)。
video.preload = 'metadata';
video.src = url;
// Load video in Safari / IE11
video.muted = true;
video.playsInline = true;
video.play();
显示缩略图的最简单方法是使用<video>
标签本身。
<video src="http://www.w3schools.com/html/mov_bbb.mp4"></video>
#t
如果您想要 x 秒的缩略图,请在 URL 中使用。
例如:
<video src="http://www.w3schools.com/html/mov_bbb.mp4#t=5"></video>
确保它不包含任何类似autoplay
or的属性,controls
并且它不应该有一个source
标签作为子元素。
你可以使用我写的这个函数。您只需要将视频文件作为参数传递给它。它将返回该视频的缩略图(即图像预览)的 dataURL。您可以根据需要修改返回类型。
const generateVideoThumbnail = (file: File) => {
return new Promise((resolve) => {
const canvas = document.createElement("canvas");
const video = document.createElement("video");
// this is important
video.autoplay = true;
video.muted = true;
video.src = URL.createObjectURL(file);
video.onloadeddata = () => {
let ctx = canvas.getContext("2d");
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
ctx.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
video.pause();
return resolve(canvas.toDataURL("image/png"));
};
});
};
请记住,这是一个异步函数。因此,请确保相应地使用它。
例如:
const handleFileUpload = async (e) => {
const thumbnail = await generateVideoThumbnail(e.target.files[0]);
console.log(thumbnail)
}
使用 jQuery Lib,您可以在此处使用我的代码。$video 是一个 Video 元素。此函数将返回一个字符串
function createPoster($video) {
//here you can set anytime you want
$video.currentTime = 5;
var canvas = document.createElement("canvas");
canvas.width = 350;
canvas.height = 200;
canvas.getContext("2d").drawImage($video, 0, 0, canvas.width, canvas.height);
return canvas.toDataURL("image/jpeg");;
}
示例用法:
$video.setAttribute("poster", createPoster($video));