Skip to content
This repository has been archived by the owner on Dec 17, 2018. It is now read-only.

Multiple Sprite Sheet Sources #10

Open
losmescaleros opened this issue Oct 29, 2013 · 3 comments
Open

Multiple Sprite Sheet Sources #10

losmescaleros opened this issue Oct 29, 2013 · 3 comments

Comments

@losmescaleros
Copy link

I had originally tried to use the Video.js Thumbnails plugin with multiple sprite sheets (for example, I had a video that was 3 minutes long, and each sprite sheet contained say 60 seconds worth of thumbnsil.) But it seemed to have a problem switching between img src's propertly. I made the following to solve this problem. It assumes that the sprite sheets are in a 1xn fashion (one row and n columns), and it just checks that the necessary sprite (according to the designated time) is equal to the sprite going to be shown.

videojs.plugin('thumbnails_SpriteSheet', function (options, timeInterval, spritesPerSheet) {
    var div, settings, img, player, progressControl, duration;
    settings = extend({}, defaults, options);
    player = this;                

    // create the thumbnail
    div = document.createElement('div');
    div.className = 'vjs-thumbnail-holder';
    img = document.createElement('img');
    div.appendChild(img);
    img.src = settings['0'].src;
    img.className = 'vjs-thumbnail';
    extend(img.style, settings['0'].style);

    // center the thumbnail over the cursor if an offset wasn't provided
    if (!img.style.left && !img.style.right) {
        img.onload = function () {
            img.style.left = -(img.naturalWidth / 2) + 'px';
        }
    };

    // keep track of the duration to calculate correct thumbnail to display
    duration = player.duration();
    player.on('durationchange', function (event) {
        duration = player.duration();
    });

    // add the thumbnail to the player
    progressControl = player.controlBar.progressControl;
    progressControl.el().appendChild(div);

    // update the thumbnail while hovering
    progressControl.el().addEventListener('mousemove', function (event) {
        var mouseTime, time, active, left, setting;

        active = 0;

        // find the page offset of the mouse
        left = event.pageX || (event.clientX + document.body.scrollLeft + document.documentElement.scrollLeft);
        // subtract the page offset of the progress control
        left -= progressControl.el().getBoundingClientRect().left + window.scrollX;
        div.style.left = left + 'px';

        // apply updated styles to the thumbnail if necessary
        // The following fixes bug where hovering over progress slider resets offset to 0:
        // https://github.com/brightcove/videojs-thumbnails/issues/3
        // start fix
        var relativeX = (event.pageX - $(this).parent().offset().left);
        mouseTime = Math.floor(relativeX / progressControl.width() * duration);
        // end fix

        //mouseTime = Math.floor(event.offsetX / progressControl.width() * duration);            

        for (time in settings) {
            if (mouseTime > time) {
                active = Math.max(active, time);
            }
        }
        setting = settings[active];
        // This is not part of the original video.thumbnails.js code. It was added to work around multiple
        // thumbnail sprite sheets. 300 is the number of seconds in one sprite sheet and is hard-coded. The 
        // following code checks the current img.src against the required src, which should be mouseTime / 300
        // (integer division) multiplied by 300 again.
        var secondsPerSheet = timeInterval * spritesPerSheet;
        var x = Math.floor(mouseTime / secondsPerSheet);
        x = x * secondsPerSheet;
        var sourceNeeded = settings[x];

        if (setting.src && (img.src != setting.src)) {

            img.src = setting.src;
        }
        // This check has been added to make sure that img src being used is the one that is needed.
        if (sourceNeeded.src && (img.src != sourceNeeded.src)) {

            img.src = sourceNeeded.src;
        }
        if (setting.style && img.style != setting.style) {
            extend(img.style, setting.style);
        }
    }, false);
});

I just threw this above the original 'thumbnails' function call and use 'thumbnails_SpriteSheet(...)' instead if that is what I need. timeInterval is the time between sprite sheets (it assumes the interval between sprites is the same), and spritesPerSheet is the number of sprites per sprite sheet. These are used to find how many seconds of video each sprite sheet should contain.

Not very complicated, but hopefully it helps someone.

@xbgmsharp
Copy link

Thanks a mix of your solution a+ the original make it work on all browser.
See code Piwigo/piwigo-videojs@c0bc724

@dmlap
Copy link
Contributor

dmlap commented Nov 11, 2013

Can you provide any details on what exactly was going wrong with switching the img src attributes? There's an example of using a sprited img src in the project itself and I haven't seen any issues there.

@losmescaleros
Copy link
Author

It seemed to work fine as long as there was only one source file. However, when I created an object to pass into the thumbnails plugin, I set it up so that different time indices would change src attributes. Scrubbing forward and backward on the seek bar, the src attribute would sometimes get mixed up, so that a sprite from the wrong source would sometimes be shown.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants