vThumb.js - The smallest library to generate video thumbnails on client side.

Overview

The smallest library to generate video thumbnails on client side.

About

Generate n numbers of Image thumbnails of a video file.

A full working `React.js` sample code is in `./example` folder.

code sandbox example

This package can be used with any JS framework or in vanila js.

NPM

Purpose?

This module will generate n numbers of image thumbnails of a given video file.

By default the thumbnail's file format will be the base64.

Usage

generateVideoThumbnails(selectedFile, numberOfThumbnails)

Async/Await (Typescript & ES7)

{ console.error(err); })">
generateVideoThumbnails(videoFile, numberOfThumbnails).then((thumbnailArray) => {
    // output will be arry of base64 Images
    // example - ["img1", "imgN"]

    // @todo - implement your logic here
}).catch((err) => {
    console.error(err);
})

Using promises and dynamic Import (Html5)

{ res.generateVideoThumbnails(videoFile, noThumb).then((thumbArray) => { thumbArray.map((item) => { // type of item is base64 image // @todo - your logic here }) }) }); ">
// please change the location of index.js as needed

import("./index.js").then((res) => {
    res.generateVideoThumbnails(videoFile, noThumb).then((thumbArray) => {
        thumbArray.map((item) => {
            // type of item is base64 image

            // @todo - your logic here
        })              
    })
});

Examples

From File Input

complete working example is in the index.html file or you can visit the demo link

{ res.importFileandPreview(e.target.files[0]).then((url) => { source.setAttribute('src', url); source.setAttribute('type', e.target.files[0]?.type); res.generateVideoThumbnails(e.target.files[0], 1).then((thumbnails) => { // video operations // video.setAttribute("poster", thumbnails[1]) // video.setAttribute("src", url) video.style.width = "auto"; video.style.height = "auto" video.style.transform = "scale(1)" }) // numberInput numberWrapper.style.display = "block"; buttonWrapper.style.display = "block"; video.style.transform = "scale(1)" video.innerHTML = ""; video.appendChild(source); }); }) } }); thumbButton.addEventListener("click", function () { thumbnaislWrapper.innerHTML = ""; loader.style.display = "block"; import("./index.js").then((res) => { res.generateVideoThumbnails(selectedFile, parseInt(numberInput.value)).then((thumbArray) => { let thumbnailsImg = thumbArray.map((item) => { let img = document.createElement('img'); img.src = item; img.alt = ""; img.style.width = "200px"; img.style.objectFit = "cover"; img.style.margin = "10px"; img.style.cursor = "pointer"; img.addEventListener("click", function () { video.setAttribute("poster", item); }) return img; }) thumbnaislWrapper.innerHTML = ""; loader.style.display = "none"; thumbnailsImg.forEach((item) => { thumbnaislWrapper.appendChild(item); }) }) }); }) ">
 let video = document.getElementById("video");
        let inputFile = document.getElementById("inputfile");
        let numberInput = document.getElementById("numberofthumbnails");
        let numberWrapper = document.getElementById("numberWrapper");
        let buttonWrapper = document.getElementById("buttonWrapper");
        let thumbButton = document.getElementById("generatethumbnails");
        let thumbnaislWrapper = document.getElementById("thumbnails");
        let loader = document.getElementById("loader");
        let selectedFile = "";

        inputFile.addEventListener("change", function (e) {
            if (e.target.files?.length) {
                selectedFile = e.target.files[0];

                var source = document.createElement('source');
                import("./index.js").then((res) => {
                    res.importFileandPreview(e.target.files[0]).then((url) => {

                        source.setAttribute('src', url);
                        source.setAttribute('type', e.target.files[0]?.type);

                        res.generateVideoThumbnails(e.target.files[0], 1).then((thumbnails) => {
                            // video operations
                            // video.setAttribute("poster", thumbnails[1])
                            // video.setAttribute("src", url)
                            video.style.width = "auto";
                            video.style.height = "auto"
                            video.style.transform = "scale(1)"
                        })
                        // numberInput
                        numberWrapper.style.display = "block";
                        buttonWrapper.style.display = "block";
                        video.style.transform = "scale(1)"
                        video.innerHTML = "";
                        video.appendChild(source);
                    });
                })
            }
        });
        thumbButton.addEventListener("click", function () {
            thumbnaislWrapper.innerHTML = "";
            loader.style.display = "block";
            import("./index.js").then((res) => {
                res.generateVideoThumbnails(selectedFile, parseInt(numberInput.value)).then((thumbArray) => {
                    let thumbnailsImg = thumbArray.map((item) => {
                        let img = document.createElement('img');
                        img.src = item;
                        img.alt = "";
                        img.style.width = "200px";
                        img.style.objectFit = "cover";
                        img.style.margin = "10px";
                        img.style.cursor = "pointer";
                        img.addEventListener("click", function () {
                            video.setAttribute("poster", item);
                        })
                        return img;
                    })
                    thumbnaislWrapper.innerHTML = "";
                    loader.style.display = "none";
                    thumbnailsImg.forEach((item) => {
                        thumbnaislWrapper.appendChild(item);
                    })
                })
            });

        })

Your contributions are more than welcome 😀


ROADMAP 🗺

  1. Lib roubstness and accuracy increment.

License

This project is licensed under the MIT License - see the LICENSE.md file for details.

Comments
  • New callback for async generation

    New callback for async generation

    Added new callback option that will be called at each thumb generated. This allow users to have large videos and large number of thumbs without breaking the UI.

    feature 
    opened by quantodaniel 2
  • Generate thumbnails asynchronously.

    Generate thumbnails asynchronously.

    Added a new callback option that will be called at each thumb generated. This allows users to have large videos and a large number of thumbs without breaking the UI.

    async generation 4.webm

    feature 
    opened by Rajesh-Royal 1
  • thumbnails not getting generated for videos created by iphone 12 or higher mobile devices

    thumbnails not getting generated for videos created by iphone 12 or higher mobile devices

    I have a case scenario in a website where i have to upload a video a get a thumbnail of that video , the library seems to work perfectly for the web as well as for video made by android devices . But for the videos created by iphone 11 pro, 11 proMax and 12 , and higher devices , black thumbnails are getting generated , couldn't seem to understand this issue , so creating this issue , I seem to have run out for options now. Please check this issue.

    opened by techdevelopers08 1
  • Cannot generate thumbnails from a Url.

    Cannot generate thumbnails from a Url.

    A user is not able to generate thumbnails from a video file URL.

    Error:

    Access to video at 'https://xyz.com/file_example_MP4_640_3MG.mp4' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
    

    Acceptance criteria It should generate thumbnails from a video file URL

    bug 
    opened by Rajesh-Royal 0
  • Error: remove the loaders on error:

    Error: remove the loaders on error:

    While generating thumbnails from a video file or from a URL if an error occurs to access the file or from a remote origin the loaders keep loading and the error state is not shown.

    expected: The loaders should be replaced with the error details.

    Preview:

    image

    bug 
    opened by Rajesh-Royal 0
Releases(1.0.0)
Owner
Rajesh Royal
Your code's boyfriend                              Have 🔥 to learn new things, do experiments, fix 🕷️, and write about it.
Rajesh Royal
nextjs-image-generation is a POC on how to do server-side image generation.

nextjs-image-generation is a POC on how to do server-side image generation.

Keisuke Nakayama 9 Nov 22, 2022
react library for generating avatar

react library for generating avatar

Chill Lab 769 Dec 30, 2022
Vue library for generating nice user avatar. (Inspired by react-nice-avatar)

holiday-avatar Vue library for generating nice user avatar. (Inspired by react-nice-avatar)

炽翎 60 Nov 16, 2022
React library to support easy zoom, pan, pinch on various html dom elements like images and divs

react-zoom-pan-pinch Super fast and light react npm package for zooming, panning and pinching html elements in easy way Demo Docs Features ?? Fast and

Maciej Pyrc 763 Dec 30, 2022
A React library for zooming images like Medium

react-medium-zoom A React library for zooming images like Medium Install npm install --save react-medium-zoom Usage import React, { Component } from '

Shahen Hovhannisyan 17 Jul 24, 2021
⚡️The Fullstack React Framework — built on Next.js

⚡️The Fullstack React Framework — built on Next.js

⚡️Blitz 12.5k Jan 9, 2023
⚡️The Fullstack React Framework — built on Next.js — Inspired by Ruby on Rails

⚡️The Fullstack React Framework — built on Next.js — Inspired by Ruby on Rails

⚡️Blitz 9.4k Oct 12, 2021
A simple Hooks wrapper over Motion One, An animation library, built on the Web Animations API for the smallest filesize and the fastest performance.

A simple Hooks wrapper over Motion One, An animation library, built on the Web Animations API for the smallest filesize and the fastest performance.

Tanvesh Sarve 95 Dec 30, 2022
A wrapper over Motion One, An animation library, built on the Web Animations API for the smallest filesize and the fastest performance

A wrapper over Motion One, An animation library, built on the Web Animations API for the smallest filesize and the fastest performance. Works with solid-js

Tanvesh Sarve 48 Dec 27, 2022
This plugin allows side-by-side notetaking with videos. Annotate your notes with timestamps to directly control the video and remember where each note comes from.

This plugin allows side-by-side notetaking with videos. Annotate your notes with timestamps to directly control the video and remember where each note comes from.

null 74 Jan 2, 2023
Mobile-friendly gallery carousel 🎠🎠🎠 with batteries included (touch, mouse emulation, lazy loading, thumbnails, fullscreen, RTL, keyboard navigation and customisations).

react-gallery-carousel Mobile-friendly Carousel with batteries included (supporting touch, mouse emulation, lazy loading, thumbnails, fullscreen, RTL,

Yifan Ai 189 Nov 18, 2022
React Native Image Gallery with Thumbnails

React Native Image Gallery with Thumbnails Features Image gallery with thumbnails Made with PanResponder, no external dependencies Written in Typescri

null 56 Dec 20, 2022
Broprint.js - The world's easiest, smallest and powerful visitor identifier for browsers

This package generates a unique ID/String for different browsers. Like chrome, Firefox or any other browsers which support `canvas` and `audio` fingerprinting. You can easily do the browser fingerprinting with this library. Its small and minimal.

Rajesh Royal 69 Jan 1, 2023
The most complete React Library Component for drag’n’drop files. Image and video previews. File validation. Multilanguage. Server side support.

?? Spanish README Dropzone UI The best, most complete and easy to use, React file upload library. ⚡ Live demo and code generator : dropzone-ui.com ❤️

dropzone-ui 177 Dec 21, 2022
The easiest way to move your React application to Server-Side Rendering. Handles Side Effects and synchronizes State.

The easiest way to move your React application to Server-Side Rendering. Handles Side Effects and synchronizes State. Table of Contents Articles Featu

Sergey 94 Dec 4, 2022
A Web library to simply integrate Agora Video Calling or Live Video Streaming to your website with just a few lines of code

Agora React Web UIKit Instantly integrate Agora video calling or streaming into your web application using a React based UIKit for the Agora Web SDK.

Agora.io Community 29 Dec 21, 2022
Redux bindings for client-side search

redux-search Higher-order Redux library for searching collections of objects. Search algorithms powered by js-worker-search. Check out the live demo a

Brian Vaughn 1.4k Jan 2, 2023
HTML meta tags for React-based apps. Works for both client- and server-side rendering, and has a strict but flexible API.

React Document Meta HTML meta tags for React-based apps. Works for both client- and server-side rendering, and has a strict but flexible API. Built wi

kodyl 320 Nov 18, 2022
Redux bindings for client-side search

redux-search Higher-order Redux library for searching collections of objects. Search algorithms powered by js-worker-search. Check out the live demo a

Brian Vaughn 1.4k Dec 16, 2022