var thumbnails = [];
var thumbnailWidth = 158;
var thumbnailHeight = 90;
var horizontalItemCount = 5;
var verticalItemCount = 5;
var init = function () {
videojs('video').ready(function() {
var that = this;
var videoSource = this.player_.children_[0];
var video = $(videoSource).clone().css('display', 'none').appendTo('body')[0];
var root = $(videoSource).closest('.video-js');
var controlBar = root.find('.vjs-control-bar');
controlBar.append('<div class="vjs-thumbnail"></div>');
controlBar.on('mousemove', '.vjs-progress-control', function() {
var time = $(this).find('.vjs-mouse-display .vjs-time-tooltip').text();
var temp = null;
if (/^\d+$/.test(time)) {
time = '0:0:' + time;
}
else if (/^\d+:\d+$/.test(time)) {
time = '0:' + time;
}
temp = time.split(':');
time = (+temp[0]) * 60 * 60 + (+temp[1]) * 60 + (+temp[2]);
for (var item of thumbnails) {
var data = item.sec.find(x => x.index === time);
if (data) {
var position = controlBar.find('.vjs-mouse-display').position();
controlBar.find('.vjs-thumbnail').css({
'background-image': 'url(' + item.data + ')',
'background-position-x': data.backgroundPositionX,
'background-position-y': data.backgroundPositionY,
'left': position.left + 10,
'display': 'block'
});
return;
}
}
});
controlBar.on('mouseout', '.vjs-progress-control', function() {
controlBar.find('.vjs-thumbnail').css('display', 'none');
});
video.addEventListener('loadeddata', async function() {
video.pause();
var count = 1;
var id = 1;
var x = 0, y = 0;
var array = [];
var duration = parseInt(that.duration());
for (var i = 1; i <= duration; i++) {
array.push(i);
}
var canvas;
var i, j;
for (i = 0, j = array.length; i < j; i += horizontalItemCount) {
for (var startIndex of array.slice(i, i + horizontalItemCount)) {
var backgroundPositionX = x * thumbnailWidth;
var backgroundPositionY = y * thumbnailHeight;
var item = thumbnails.find(x => x.id === id);
if (!item) {
canvas = document.createElement('canvas');
canvas.width = thumbnailWidth * horizontalItemCount;
canvas.height = thumbnailHeight * verticalItemCount;
thumbnails.push({
id: id,
canvas: canvas,
sec: [{
index: startIndex,
backgroundPositionX: -backgroundPositionX,
backgroundPositionY: -backgroundPositionY
}]
});
} else {
canvas = item.canvas;
item.sec.push({
index: startIndex,
backgroundPositionX: -backgroundPositionX,
backgroundPositionY: -backgroundPositionY
});
}
var context = canvas.getContext('2d');
video.currentTime = startIndex;
await new Promise(function(resolve) {
var event = function() {
context.drawImage(video, backgroundPositionX, backgroundPositionY,
thumbnailWidth, thumbnailHeight);
x++;
video.removeEventListener('canplay', event);
resolve();
};
video.addEventListener('canplay', event);
});
count++;
}
x = 0;
y++;
if (count > horizontalItemCount * verticalItemCount) {
count = 1;
x = 0;
y = 0;
id++;
}
}
thumbnails.forEach(function(item) {
item.canvas.toBlob(blob => item.data = URL.createObjectURL(blob), 'image/jpeg');
delete item.canvas;
});
console.log('done...');
});
video.play();
});
};
$('[type=file]').on('change', function() {
var file = this.files[0];
$('video source').prop('src', URL.createObjectURL(file));
init();
});
.vjs-control-bar .vjs-thumbnail {
position: absolute;
width: 158px;
height: 90px;
top: -100px;
background-color: #000;
display: none;
}
<link rel="stylesheet" href="https://vjs.zencdn.net/7.5.5/video-js.css" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="https://vjs.zencdn.net/7.5.5/video.js"></script>
<input type="file" accept=".mp4" />
<video id="video" class="video-js vjs-default-skin" width="500" height="250" controls>
<source src="" type='video/mp4'>
</video>