To optimize the loading speed of your video content, you can enhance it by utilizing preload="metadata"
in your video tag and specifying the start time of the first frame as #t=0.1
in the video source:
<video preload="metadata">
<source src="https://example.com/foo.mp4#t=0.1" type="video/mp4">
Your browser does not support the video tag.
</video>
If the above method doesn't yield desirable results, an alternative approach is to extract the initial frame using JavaScript:
async function captureThumbnailVideo(videoURL) {
const video = document.createElement('video');
video.crossOrigin = 'anonymous';
video.src = videoURL;
video.autoplay = true;
video.preload = 'metadata';
// Load video in Safari / IE11
video.muted = true;
video.playsInline = true;
const canvas = document.createElement('canvas');
let thumbnail = '';
try {
await video.play();
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
const context = canvas.getContext('2d');
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
const thumbnailBlob = (await new Promise((resolve) =>
canvas.toBlob(resolve, 'image/jpeg')
)) as Blob;
thumbnail = URL.createObjectURL(thumbnailBlob);
} catch (e) {
await new Promise<void>((resolve) => {
video.onloadedmetadata = () => {
video.currentTime = 1; //? seek to 1 second to ensure enough video data for capture
video.onseeked = () => {
const context = canvas.getContext('2d');
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
context.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); //? draw the video frame to canvas
video.pause();
resolve();
};
};
});
thumbnail = canvas.toDataURL('image/png');
}
const duration = video.duration;
// Destroy the video once we are done with it.
video.pause(); // pause the video before removing it
video.src = ''; // empty the video source to release any resources associated with it
video.load(); // force the browser to release resources used by the video element
video.remove();
// Destroy the canvas once we are done with it.
canvas.remove();
return { thumbnail, duration };
}
const thumnail = await captureThumbnailVideo(url).then(({ thumbnail }) => {
document.querySelector('video').setAttribute('poster', thumbnail)
})
If you already have a custom thumbnail image, you can easily incorporate it by adding the poster attribute to your video tag:
<video poster="/example.jpg">