phloxic / videojs-sprite-thumbnails Goto Github PK
View Code? Open in Web Editor NEWVideo.js plugin to display thumbnails from a sprite image when hovering over the progress bar
Home Page: https://lastshiphome.de/en/movie
License: MIT License
Video.js plugin to display thumbnails from a sprite image when hovering over the progress bar
Home Page: https://lastshiphome.de/en/movie
License: MIT License
I'm using videojs version 7.20.2 and followed approximately this tutorial
https://giriaakula.medium.com/videojs-how-to-create-preview-thumbnails-8ce273974529.
I added the plug-in using CDN
<script src="https://unpkg.com/[email protected]/dist/videojs-sprite-thumbnails.min.js"></script>
and added it to the player like this
player.spriteThumbnails({ interval:1, url: thumbnailpreviewurl, width: 160, height: 90 }).log.level('debug');
I'm not getting any indication that the plugin is working other than vjs-sprite-thumbnails
show up as a class name in on of the video divs and it doesn't seem like I'm getting any console error messages. Do you have any directions for debugging?
Can't really find the real point where a video is a "long" one, but when video length exceeds a certain time, the tooltip usually containing the thumbnail is empty.
When inspecting the element, one can see that the image resource is correctly loaded, and that the expected size of the background is correct, but the background position is not updated at all when moving the mouse over the progress bar.
With the exact same usage of this plugin for shorter videos, there is no issue, and everything works like a charm.
Hereafter, with a "long" video and a "normal" one:
I'm using the latest [email protected]
along with [email protected]
from npm.
A working video: https://radiom.fr/s/v38
... and a failing one: https://radiom.fr/s/v39
Hi there!
I was wondering if there is a recommended method for generating the sprite image to work best with this plugin? Something like https://askubuntu.com/questions/377579/how-can-i-use-ffmpeg-to-output-a-screenshot-gallery-mosaic/377630#377630 perhaps?
Thanks
Thanks for the awesome plugin.
In my experience the latest version is no longer displaying thumbnails in Safari and Firefox.
I've put together a very rough example which should work correctly in Chrome but not in the others:
https://jsfiddle.net/s2da0goh/
Downgrading to v2.1.1 will work.
HI, is there a way to import the plugin in a React v18 app using TS?.
I'm using video.js 8.2.0, jQuery 3.6.4 and the most recent version of videojs-sprite-thumbnails. I'm receiving the following error message on Chrome, Brave and Edge:
videojs-sprite-thumbnails.js:291 Uncaught TypeError: Class constructor Plugin cannot be invoked without 'new'
at new SpriteThumbnails (videojs-sprite-thumbnails.js:291:22)
at Player.spriteThumbnails (video.js:27222:24)
at Player.onPlayerReady (playersetup.js:32:8)
at Player. (video.js:4318:16)
at Array.forEach ()
at Player. (video.js:4317:22)
at video.js:4951:9
This is my index.html:
<body>
<script>
const videoData = {
"thumbsheet" : "thumbs/earth.png",
"videoCover" : "images/earth.png",
"videoSource-240p" : "",
"videoSource-320p" : "",
"videoSource-480p" : "",
"videoSource-720p" : "",
"videoSource-1080p" : "videos/earth-1080p.mp4",
"videoSource-4k" : "",
};
</script>
<div id="video_container">
<video-js id="main_video_player" class="video-js"></video-js>
</div>
<script src="videojs/8.2.0/video.min.js"></script>
<script src="jquery/jquery-3.6.4.min.js"></script>
<script src="videojs/plugins/theater-mode-1.1.0/videojs.theaterMode.js"></script>
<script src="videojs/plugins/sprite-thumbnails-0.6.0/videojs-sprite-thumbnails.js"></script>
<script src="playersetup.js"></script>
</body>
My playersetup.js:
videojs(
'main_video_player',
{
controls: true,
autoplay: false,
preload: 'metadata',
playbackRates: [0.5, 1, 1.5, 2, 3],
},
function onPlayerReady() {
this.src([{
src: videoData["videoSource-1080p"],
type: 'video/mp4'
}]);
// PLUGIN: videojs-sprite-thumbnails
// Setup 256 x 144 thumbnails with an interval of five seconds
this.spriteThumbnails({
url: videoData["thumbsheet"],
width: 256,
height: 144,
interval: 5
});
}
);
I can't figure out what I've done wrong. I'd appreciate any help. Thanks!
Since Video.js version 7.9.4 the time tooltips can go out of bounds on the right side of the player.
See e.g. videojs/video.js#7248 and not accepted fix videojs/video.js#7308 et.al.
This affects the plugin because it hijacks the tooltip in the mouse time display to display the preview thumbnails. Especially with widescreen movies and/or few/none buttons/menus to the right of the progressbar, the thumbnail might go (partially) out of bounds on the right side.
A nasty emergency fix would be to set overflow: hidden
on the player container.
Hello,
as your plug does currently not respect videojs.Vhs.xhr.beforeRequest to set a Token for authorization, I tried to use a signed s3 link instead. But as soon as I pass the link to your script it seems that all "&" are swapped out for an ";" which again breaks the signed link as it has changed.
The funny fact here is that If I directly set the string (hard-coded) it works, If I pass it into the script via a call from my Framework I get this mess.
I already validated that the generated link I pass is valid, as I can display it normally in my template where I also use VideoJS and your plugin. So the issue has to be at your plugin I guess.
My application generates the link to download the sprites.png, which looks like this:
https://localhost/vod/Movies/test/sprites.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=2PsuWGctH4UQmGvEQYjTDsZ2HqGM%2F20220601%2Fminio%2Fs3%2Faws4_request&X-Amz-Date=20220601T153759Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host&X-Amz-Signature=cd575bd79883f1fec4e50cb14b2973bac7305f14517b7ca2a39f3f419b672b92
As soon as I call the template and the player starts, I can see that your plugin tries to download the sprites.png, but the link has changed for some reason, all & are swapped for an ";". This is the link that get s called instead:
https://localhost/vod/Movies/test/sprites.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=2PsuWGctH4UQmGvEQYjTDsZ2HqGM%2F20220601%2Fminio%2Fs3%2Faws4_request&X-Amz-Date=20220601T153759Z&X-Amz-Expires=300&X-Amz-SignedHeaders=host&X-Amz-Signature=cd575bd79883f1fec4e50cb14b2973bac7305f14517b7ca2a39f3f419b672b92
Any Idea?
Kind regards
Hi, quick question..
When you call the following code for a second time (say the video changed sources) with dynamic data as variables it doesn't seem to update the thumbnail images with the new image source which is passed in. It works first time round so fine there, just wondered if this was by design or if there was something I could do to fix it?
videoPlayer.spriteThumbnails({
url: "" + my_image_url + "",
interval: my_interval,
width: my_width,
height: my_height
});
Hello,
this plugin cannot work in the browser of the mobile device, the touchmove event does not work.
Could you please make this plugin support the mobile device?
Thank you.
Hello again,
I've now got your plugin running (Yeah!), but I sadly cannot pull the sprites image from my backend, as it does not respect videojs.Vhs.xhr.beforeRequest. Result in 401 Unauthorized at my browser.
The Video Playback itself works fine as the header gets set but without, I practically cannot pull any data from my backend servers
videojs.Vhs.xhr.beforeRequest = function (options) {
options.headers = options.headers || {};
options.headers.Authorization = "{{ access_token }}";
};
Is it possible to add compatibility to your code for beforeRequest to set an Authorization header? Would be Awesome!
Many Thanks in advance.
I'm using videojs-sprite-thumbnails
plugin with https://github.com/surmon-china/videojs-player
.
I'm trying to update interval for plugin dynamically based on some json data, but it doesn't seem to work.
<video-player controls :src="src" :poster="poster" :loop="true" :volume="0.6" :plugins="{ spriteThumbnails: { interval: spriteInfo.interval, width: 160, height: 90, url: spriteUrl, }, }" :height="380" :width="680" />
It only works if I pass hardcoded value like interval: 2
.
Any solutions?
I'm trying to integrate your plugin to my VideoJS setup.
Currently, my player simply does not load at all, if I take a look at the Developer console of my browser I see:
Uncaught TypeError: player.spriteThumbnails is not a function
Why that?
This is how my VideoJS Setup currently look like:
<video-js autoplay id=player class="vjs-fluid" controls="true">
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'videojs/video.js' %}"></script>
<script src="{% static 'videojs/videojs-sprite-thumbnails.js' %}"></script>
<script src="{% static 'videojs/videojs-http-streaming.js' %}"></script>
<script>
videojs.Vhs.xhr.beforeRequest = function (options) {
options.headers = options.headers || {};
options.headers.Authorization = "{{ access_token }}";
};
var player = videojs('player', function () {
}, {
fill: true,
autoplay: true,
responsive: true,
fluid: true,
preferFullWindow: true,
preload: "auto",
enableLowInitialPlaylist: true,
html5: {
nativeControlsForTouch: false,
nativeAudioTracks: false,
nativeVideoTracks: false,
vhs: {
enableLowInitialPlaylist: true,
limitRenditionByPlayerDimensions: true,
smoothQualityChange: true,
overrideNative: false,
handleManifestRedirects: true,
useNetworkInformationApi: true,
}},
plugins: {
// default thumbnail settings for this player
spriteThumbnails: {
width: 192,
height: 108
}
},
function() {
this.on('error', function (event) {
const time = this.currentTime();
if (this.error().code === 3) {
this.error(null).pause().load().currentTime(time).play();
}
if (this.error().code === 2) {
this.error(null).pause().load().currentTime(time).play();
}
if (this.error().code === 1) {
this.error(null).pause().load().currentTime(time).play();
}
});
}
});
player.spriteThumbnails({
url: '{{ sprites_url }}',
width: 192,
height: 108,
interval: 30,
}).log.level('debug');
player.src({
src: '{{ playlist_url }}',
type: 'application/vnd.apple.mpegurl m3u8',
Authorization: true
});
player.play();
</script>
</video-js>
Does somebody have a hint for me here?
I also have to mention that I have literally no knowledge on JS, so I'm not really sure where to look at.
VideoJs Version is 7.19.2
http-streaming version is: 2.14.2
Please also see: https://stackoverflow.com/questions/72450465/videojs-uncaught-typeerror-player-spritethumbnails-is-not-a-function
seems I'm not the only person with this issue
Many thanks in advance
My production environment: Nuxt3 (Vue), videojs 7.21.5, videojs-sprite-thumbnails 1.0.0.
I recently switched my SPA application to an SSR application. Since Nuxt3 does not support "require," I wrote a component in the plugins directory to import this plugin. The plugin loads successfully, but the thumbnails are not being displayed.
I've been struggling with this issue for two days. Can you help me identify what the problem might be?
Note: It was working fine with the "require" import in the SPA application. But ssr application not working.
thank you.
EDIT :
When I switch to a higher version(@1.1.1) I get the following error:
VIDEOJS: ERROR: TypeError: Cannot read properties of undefined (reading 'off')
at SpriteThumbnails. (videojs-sprite-thumbnails.js:156:18)
at Be.o.dispatcher.o.dispatcher (video.min.js:12:13653)
at je (video.min.js:12:14437)
at e.trigger (video.min.js:20:184444)
at SpriteThumbnails.setState (video.min.js:12:19867)
at init (videojs-sprite-thumbnails.js:133:14)
at spriteThumbs (videojs-sprite-thumbnails.js:176:5)
at o. (videojs-sprite-thumbnails.js:232:9)
at video.min.js:12:30486
/plugins/vjs.js
export default async function(context) {
//if (process.client) {
const loadScript = (src) => {
return new Promise((resolve, reject) => {
const script = document.createElement("script");
script.src = src;
script.addEventListener("load", resolve);
script.addEventListener("error", reject);
document.body.appendChild(script);
});
};
try {
await loadScript(
"https://cdn.jsdelivr.net/npm/[email protected]/dist/video.min.js"
);
await loadScript(
"https://cdn.jsdelivr.net/npm/[email protected]/dist/videojs-plus.umd.min.js"
);
await loadScript(
"https://cdn.jsdelivr.net/npm/[email protected]/dist/videojs-sprite-thumbnails.js"
);
await loadScript(
"https://cdn.jsdelivr.net/npm/[email protected]/dist/videojs-seek-buttons.min.js"
);
} catch (error) {
console.error("Failed to load script:", error);
}
}
component page.vue
var myPlayer = videojs('myvideo') myPlayer.spriteThumbnails({ interval: 3, url: http://demo.com/path/preview_120.jpg', downlink: 0, width: 120, height: 68, }).log.level('debug');
Hello,
I really would like to use your plugin but for some reason I don't get the plugin initialized it seems, can you help?
Currently, I get the following error: TypeError: player.spriteThumbnails is not a function
This is how my HTML page looks:
...
<script src="{% static 'js/jquery-3.6.0.min.js' %}"></script>
<script src="{% static 'videojs/video.js' %}"></script>
<script src="{% static 'videojs/videojs-sprite-thumbnails.js' %}"></script>
<script src="{% static 'videojs/videojs-http-streaming.js' %}"></script>
<script>
videojs.Vhs.xhr.beforeRequest = function (options) {
options.headers = options.headers || {};
options.headers.Authorization = "{{ access_token }}";
};
const player = videojs('player', function () {
}, {
plugins: {
// default thumbnail settings for this player
spriteThumbnails: {
width: 160,
height: 90
}
},
fill: true,
autoplay: true,
responsive: true,
fluid: true,
preferFullWindow: true,
preload: "auto",
enableLowInitialPlaylist: true,
html5: {
nativeControlsForTouch: false,
nativeAudioTracks: false,
nativeVideoTracks: false,
vhs: {
enableLowInitialPlaylist: true,
limitRenditionByPlayerDimensions: true,
smoothQualityChange: true,
overrideNative: false,
handleManifestRedirects: true,
useNetworkInformationApi: true,
}
}, function() {
this.on('error', function (event) {
const time = this.currentTime();
if (this.error().code === 3) {
this.error(null).pause().load().currentTime(time).play();
}
if (this.error().code === 2) {
this.error(null).pause().load().currentTime(time).play();
}
if (this.error().code === 1) {
this.error(null).pause().load().currentTime(time).play();
}
});
}
});
player.src({
src: '{{ playlist_url }}',
type: 'application/vnd.apple.mpegurl m3u8',
Authorization: true
});
player.spriteThumbnails({
url: '{{ sprites_url }}',
width: 192,
height: 108,
interval: 30,
}).log.level('debug');
player.play();
</script>
...
Thanks in advance
If NetworkInformation.downlink is available, optionally use it to prevent costly sprite downloads over slow connections.
Hi team
I can't sure that this is issue or not, but i need help, so that raise this ticket.
Currently i am using videojs on react and i want to use sprite-thumbnail.
What i have done is
const player = (playerRef.current = videojs(
videoElement,
options,
() => {
player.spriteThumbnails({
interval: 2,
url: `/assets/preview_01.jpg`,
width: 160,
height: 90,
})
},
))
But on timeline, thumbnail is not showing, just time is displayed.
When i check player on console, player.spriteThumbnails
is a function not object.
Did i something wrong?
Kindly update me.
Regard.
Hello,
I would like to know why I don't see any sprites in chrome, where Firefox seems to work fine!?
Is this already a known issue?
Thanks in advance
At the moment the initial check for the presence and order of components does not behave well on failure.
The plugin should bail out cleanly if the required components are not detected.
Loading of thumbnails will only happen if needed and interfere less with video loading and playback. This fundamentally changes the approach chosen in #17 because it seems that explicitly preloading a new Image
is more dominant than to trigger the load via setting backgroundImage
property.
Mouse time display tooltip style properties will change immediately without waiting for the image to load. Therefore introduce a new mandatory plugin option columns
which will allow to determine backgroundPosition
before naturalWidth
and naturalHeight
properties of the image are available.
Hi,
first of all this plugin works like a charm. My problem is that I want to use one url with basic auth.
I've tried to pass the image as a Blob object (calling the http service before your plugin) but it is not working, would you recommend me another approach?
Thanks in advance,
Jorge
Loading the image on loadeddata or loadedmetadata can make the video stutter at the the beginning when connection is slow.
By using loadstart (unless single image is preloaded on setup) the delay happens before the movie starts running.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.