The Dead Man
The Dead Man

Reputation: 5576

How to generate video preview thumbnails using nodejs and ffmpeg?

I am creating a custom video player, I would like to add a video preview when the user hovers a progress bar.

I am able to generate thumbnails using FFmpeg as follows.

ffmpeg -i input -filter_complex \
    "select='not(mod(n,60))',scale=240:-1,tile=layout=4x8" \
    -vframes 1 -q:v 2 outputfile.jpg

PROBLEM

To use the above-created sprite image(combined thumbnails), I need to generate a WEBVTT which contains thumbnails and frames time interval like this below.

WEBVTT

00:00:00.000 --> 00:00:03.000
thumbnails.jpg#xywh=0,0,120,68

00:00:03.000 --> 00:00:06.000
thumbnails.jpg#xywh=120,0,120,68

00:00:06.000 --> 00:00:09.000
thumbnails.jpg#xywh=240,0,120,68

I am not able to find any FFmpeg command or tutorial on how to create such WEBVTT file using node-js and FFmpeg.

Maybe someone here knows the solution to this problem? any help will be appreciated.

Upvotes: 6

Views: 1506

Answers (1)

Primata Lógico
Primata Lógico

Reputation: 745

You will have to make your own tool for creating the WEBVTT file. And it's a simple process, you just need to get the information you need and fill it in the following format:

00:00:00.000 --> 00:00:03.000
thumbnails.jpg#xywh=0,0,120,68

and then save the file.

Example:

Let's say you have a video that's 60 seconds long. You use ffmpeg to generate 10 thumbnails.

You write a short program (in this case Node.js) that loops based on the number of thumbnails following the above format a manner similar to this:

const fs = require('fs')
const moment = require('moment')

let video_length = 60
let number_of_thumbnails = 10
let thumb_interval = video_length/number_of_thumbnails // so 6 seconds per thumbnail

let sprite_width = 600 // Values are assumed based each thumbnail having
let sprite_height = 340 //a width of 120 and a height of 68 with a total of 10

let start_time = moment('00:00:00', "HH:mm:ss.SSS")
let end_time = moment('00:00:00', "HH:mm:ss.SSS").add(thumb_interval , 'seconds')

let thumb_output = "WEBVTT\n\n"

for(let i=0;i<=(sprite_height /68);i++){
  for(let j=0;j<=(sprite_width/120);j++){

    thumb_output +=start_time.format("HH:mm:ss.SSS") +" --> "+ end_time.format("HH:mm:ss.SSS")+"\n"

    thumb_output += "thumbnails.jpg#xywh="+(j*120)+","+(i*68)+",120,68\n\n"

    start_time.add(thumb_interval , 'seconds')
    end_time.add(thumb_interval , 'seconds')
  }
}

fs.writeFileSync('thumbnails.vtt', thumb_output)

The library Moment.js was used for simplifying the time incrementation & format

Upvotes: 4

Related Questions