Pergunta

Wrestling this for days now. The simplest way to reproduce the problem is to use Yeoman and call yo webapp. After installation is complete run bower install mediaelement --save. Throw a video on the index page:

    <div class="hero-unit">
      <h1>'Allo, 'Allo!</h1>
      <p>You now have</p>
      <ul>
        <li>HTML5 Boilerplate</li>

      </ul>
        <video src="bower_components/mediaelement/media/echo-hereweare.mp4" controls></video>
    </div>

Add the dependency after jquery:

    <!-- build:js scripts/vendor.js -->
    <!-- bower:js -->
    <script src="bower_components/jquery/dist/jquery.js"></script>
    <script src="bower_components/mediaelement/build/mediaelement-and-player.js"></script>
    <!-- endbower -->
    <!-- endbuild -->

And grunt serve.

So far so good, but when you run $('video,audio').mediaelementplayer(); in the console... BOOM. It seems to be entering an infinite loop somewhere. But I don't know where or why.

You can even call the mediaelement-and-player.js file outside of the build tags and it still hangs.

I've got the entire thing on github if anyone would like to see what I mean. Assuming you already have npm, grunt, and bower available from terminal/command prompt, you should just be able to run bower install from the root directory, then grunt serve to get the page in your browser.

UPDATE 4/8/2014:

I think I have managed to locate the source of the infinite loop. The do while loop at the bottom of this bit of code seems to run forever. For some reason, the usedWidth is getting set to 2400 (way bigger than even my browser... ). Not sure yet why, but for some reason the element that it is checking for (lastControlPosition.top) never pops into the correct position. So it keeps shrinking the railWidth (even though it starts at -2400).

    setControlsSize: function() {
        var t = this,
            usedWidth = 0,
            railWidth = 0,
            rail = t.controls.find('.mejs-time-rail'),
            total = t.controls.find('.mejs-time-total'),
            current = t.controls.find('.mejs-time-current'),
            loaded = t.controls.find('.mejs-time-loaded'),
            others = rail.siblings(),
            lastControl = others.last(),
            lastControlPosition;


        // allow the size to come from custom CSS
        if (t.options && !t.options.autosizeProgress) {
            // Also, frontends devs can be more flexible
            // due the opportunity of absolute positioning.
            railWidth = parseInt(rail.css('width'));
        }

        // attempt to autosize
        if (railWidth === 0 || !railWidth) {

            // find the size of all the other controls besides the rail
            others.each(function() {
                var $this = $(this);
                if ($this.css('position') != 'absolute' && $this.is(':visible')) {
                    usedWidth += $(this).outerWidth(true);
                }
            });

            // fit the rail into the remaining space
            railWidth = t.controls.width() - usedWidth - (rail.outerWidth(true) - rail.width());
        }

        // resize the rail,
        // but then check if the last control (say, the fullscreen button) got pushed down
        // this often happens when zoomed
        do {                
            // outer area
            rail.width(railWidth);
            // dark space
            total.width(railWidth - (total.outerWidth(true) - total.width()));              

            lastControlPosition = lastControl.position();

            railWidth--;                
        } while (lastControlPosition.top > 0)

        if (t.setProgressRail)
            t.setProgressRail();
        if (t.setCurrentRail)
            t.setCurrentRail();
    },

I still don't exactly know if using bower/grunt to get the thing rolling has ANYTHING to do with it, but I can get it to work in other instances.

UPDATE I have changed the name of this question to reflect the answer I found below. It used to be called "Mediaelement.js infinite loop when implemented with bower and served with grunt"

Foi útil?

Solução

The answer, as always, is frustratingly simple. Using mediaelement-and-player.js depends on the css file that comes with it. That file is not merely for looks. It sets the widths of certain elements, and without those widths, the js function used to figure out the width of the playhead track fails.

So be sure to include mediaelementplayer.css or the minified version. Even if, like me, you were unconcerned with the look of the player because you were adding your own styles later.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top