通过文件输入从视频文件创建缩略图

rya*_*yan 35 javascript video html5 thumbnails video-thumbnails

我正在尝试从表单中创建视频文件(mp4,3gp)的缩略图预览input type='file'.许多人说这只能在服务器端完成.我发现这很难相信,因为我最近刚刚使用HTML5 Canvas和Javascript遇到了这个小提琴.

缩略图小提琴

唯一的问题是这需要视频存在并且用户在单击按钮以捕获缩略图之前单击播放.我想知道是否有办法在没有玩家在场且用户点击按钮的情况下获得相同的结果.例如:用户单击文件上载并选择视频文件,然后生成缩略图.欢迎任何帮助/想法!

Giu*_*Giu 60

Canvas.drawImage必须基于html内容.

资源

这是一个简单的jsfiddle

//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);
}
Run Code Online (Sandbox Code Playgroud)

此解决方案的优点是您可以根据视频的时间选择所需的缩略图.

  • 他们是否可以在不加载文档视频的情况下执行此操作 (4认同)
  • 我只能得到视频大小0 0和白色图像. (2认同)

use*_*613 24

最近需要这个所以我写了一个函数,接收一个视频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);
}
Run Code Online (Sandbox Code Playgroud)

功能:

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 */
                );
            });
        });
    });
}
Run Code Online (Sandbox Code Playgroud)


Rez*_*ati 21

显示缩略图的最简单方法是使用<video>标签本身。

<video src="http://www.w3schools.com/html/mov_bbb.mp4"></video>
Run Code Online (Sandbox Code Playgroud)

#t如果您想要 x 秒的缩略图,请在 URL 中使用。

例如:

<video src="http://www.w3schools.com/html/mov_bbb.mp4#t=5"></video>
Run Code Online (Sandbox Code Playgroud)

确保它不包含任何类似autoplay或 的属性controls,并且它不应该有source标签作为子元素。

通过一点 JavaScript,您还可以在单​​击缩略图时播放视频。

document.querySelector('video').addEventListener('click', (e) => {
  if (!e.target.controls) { // Proceed, if there are no controls
    e.target.src = e.target.src.replace(/#t=\d+/g, ''); // Remove the time, which is set in the URL
    e.target.play(); // Play the video
    e.target.controls = true; // Enable controls
  }
});
Run Code Online (Sandbox Code Playgroud)
<video src="http://www.w3schools.com/html/mov_bbb.mp4#t=5"></video>
Run Code Online (Sandbox Code Playgroud)

  • 另外,问题是来自文件输入的视频,而不是网址。 (6认同)

Joe*_*mon 16

你可以使用我写的这个函数。您只需将视频文件作为参数传递给它即可。它将返回该视频的缩略图(即图像预览)的 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"));
    };
  });
};
Run Code Online (Sandbox Code Playgroud)

请记住,这是一个异步函数。因此请务必相应地使用它。

例如:

const handleFileUpload = async (e) => {
  const thumbnail =  await generateVideoThumbnail(e.target.files[0]);
  console.log(thumbnail)
}
Run Code Online (Sandbox Code Playgroud)


小智 14

最近需要这个并做了相当多的测试并将其煮至最低限度,请参阅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();
Run Code Online (Sandbox Code Playgroud)