To output a single frame from ffmpeg I can do:
ffmpeg -i input.flv -ss 00:00:14.435 -vframes 1 out.png
And to output an image every second, I can do:
ffmpeg -i input.flv -vf fps=1 out%d.png
Would there be a way to create a thumbnail sprite from these outputs to help with the creation of a vtt file for thumbs on seek position?
Here is an example to create jpeg files (280x180) from mp4 video, using ffmpeg, and then assembling this thumbnails into a sprite (png format) using PHP gd2 + writing a VTT file for the video player.
First create 1 image per second with ffmpeg:
ffmpeg -i sprite/MyVideoFile.mp4 -r 1 -s 280x180 -f image2 sprite/thumbs/thumb-%%d.jpg
Then create sprite file + vtt file (example with PHP):
$dirToScan = 'thumbs/';
$filePrefix = 'thumb-';
$fileSuffix = '.jpg';
$thumbWidth = 280;
$thumbHeight = 180;
$imageFiles = array();
$spriteFile = 'sprite.png';
$imageLine = 20;
$vttFile = 'sprite.vtt';
$dst_x = 0;
$dst_y = 0;
# read the directory with thumbnails, file name in array
foreach (glob($dirToScan.$filePrefix.'*'.$fileSuffix) as $filename) {
array_push($imageFiles,$filename);
}
natsort($imageFiles);
#calculate dimension for the sprite
$spriteWidth = $thumbWidth*$imageLine;
$spriteHeight = $thumbHeight*(floor(count($imageFiles)/$imageLine)+1);
# create png file for sprite
$png = imagecreatetruecolor($spriteWidth,$spriteHeight);
# open vtt file
$handle = fopen($vttFile,'wb+');
fwrite($handle,'WEBVTT'."\n");
# insert thumbs in sprite and write the vtt file
foreach($imageFiles AS $file) {
$counter = str_replace($filePrefix,'',str_replace($fileSuffix,'',str_replace($dirToScan,'',$file)));
$imageSrc = imagecreatefromjpeg($file);
imagecopyresized ($png, $imageSrc, $dst_x , $dst_y , 0, 0, $thumbWidth, $thumbHeight, $thumbWidth,$thumbHeight);
$varTCstart = gmdate("H:i:s", $counter-1).'.000';
$varTCend = gmdate("H:i:s", $counter).'.000';
$varSprite = $spriteFile.'#xywh='.$dst_x.','.$dst_y.','.$thumbWidth.','.$thumbHeight;
fwrite($handle,$counter."\n".$varTCstart.' --> '.$varTCend."\n".$varSprite."\n\n");
create new line after 20 images
if ($counter % $imageLine == 0) {
$dst_x=0;
$dst_y+=$thumbHeight;
}
else {
$dst_x+=$thumbWidth;
}
}
imagepng($png,$spriteFile);
fclose($handle);
VTT file looks like:
WEBVTT
1
00:00:00.000 --> 00:00:01.000
sprite.png#xywh=0,0,280,180
2
00:00:01.000 --> 00:00:02.000
sprite.png#xywh=280,0,280,180
3
00:00:02.000 --> 00:00:03.000
sprite.png#xywh=560,0,280,180
...
I am not completely sure what you need/mean with sprite for a vtt file, but there is a nice tool that allows you to combine single images into a big overview picture:
ImageMagick comes with a handy tool called montage
montage - create a composite image by combining several separate images. The images are tiled on the composite image optionally adorned with a border, frame, image name, and more.
You can put the thumbnails together on one or more images with the following command:
montage *.png -tile 4x4 overview.png
It will automatically generate the number of needed pictures to give you an overview.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With