admin管理员组

文章数量:1424910

I have a responsive site that contains html5 video. I have some javascript that checks if the size of the video elements are below a certain threshold. If so, it removes the controls, places a video play button overlay image on top of the video element then adds a click event to the container holding the video element. When the container is clicked on, it copies the video into a modal dialog box and plays the video.

Here's the quandary:

  • The webm version has no problems whatsoever.
  • The mp4 version of the modal view has no problems in Safari.
  • If the mp4 plays in place (i.e. is large enough to not need a modal window) it plays fine.
  • The mp4 version of the modal view won't play in Chrome or IE.
  • However, it will work in Chrome or IE if I have their built-in DOM inspectors open (e.g. IE's F12 tools).

This can be seen here.

Here's the HTML:

<div class="video modal-trigger col-lg-4 col-md-4 col-sm-4">
    <canvas></canvas>
    <video preload="auto" controls="controls" poster="img/why-autologel-poster.png">
        <source src="media/why-autologel.m4v" type='video/mp4'>
        <source src="media/why-autologel.webm" type='video/webm'>
    </video>
</div>
<div class="col-lg-8 col-md-8 col-sm-7">
    <h2 class="modal-heading">
        Why AutoloGel?
    </h2>
    <p class="modal-copy">
        See what AutoloGel offers to your patients.
    </p>
</div>

<!-- Modal Window -->
<div class="modal fade" id="modal-window" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                <h4 class="modal-title" id="myModalLabel"></h4>
            </div>
            <div class="modal-body">
                <div class="media"></div>
                <div class="copy"></div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>

Here's the javascript:

$(document).ready(function() {

    // Play very small videos in modal box
    if ( $(window).width() > 750 ) {
        var modalvideo = document.getElementsByTagName('video');

        // Hide controls for very small videos
        for (var i = 0; i < modalvideo.length; i++) {
            if ( $(modalvideo[i]).width() < 470 ) {
                $(modalvideo[i]).removeAttr('controls');
                if ( $('html').hasClass('IE-9') ) {
                    $(modalvideo[i]).after('<img class="poster-overlay" src="img/poster-overlay-ie9.png" alt="play video">');
                } else {
                    $(modalvideo[i]).after('<img class="poster-overlay" src="img/poster-overlay.png" alt="play video">');
                }
            }
        }

        // Add click event to video container that brings up video in a modal window
        $('.modal-trigger').on("click", function() {
            if ( $(this).width() < 470 ) {
                // Get video, title and any copy text
                var media = $(this).html();
                var title = $(this).next().children('.modal-heading').text();
                var copy = $(this).next().children('.modal-copy').text();

                // Insert video, title and copy text into modal window
                $('.modal-title').html(title);
                $('.modal-body > .media').html(media);
                $('.modal-body > .copy').text(copy);
                $('#modal-window .poster-overlay').remove('');
                $('#modal-window').modal('show');

                // Autoplay video after modal window has rendered
                $('#modal-window').on('shown.bs.modal', function() {
                    modalvideo[modalvideo.length - 1].setAttribute('controls', 'controls');
                    modalvideo[modalvideo.length - 1].play();
                });

                // Stop play video when modal window is closed
                $('#modal-window').on('hide.bs.modal', function() {
                    modalvideo[modalvideo.length - 1].pause();
                });
            }
        });
    }
});

Thanks for your help!

I have a responsive site that contains html5 video. I have some javascript that checks if the size of the video elements are below a certain threshold. If so, it removes the controls, places a video play button overlay image on top of the video element then adds a click event to the container holding the video element. When the container is clicked on, it copies the video into a modal dialog box and plays the video.

Here's the quandary:

  • The webm version has no problems whatsoever.
  • The mp4 version of the modal view has no problems in Safari.
  • If the mp4 plays in place (i.e. is large enough to not need a modal window) it plays fine.
  • The mp4 version of the modal view won't play in Chrome or IE.
  • However, it will work in Chrome or IE if I have their built-in DOM inspectors open (e.g. IE's F12 tools).

This can be seen here.

Here's the HTML:

<div class="video modal-trigger col-lg-4 col-md-4 col-sm-4">
    <canvas></canvas>
    <video preload="auto" controls="controls" poster="img/why-autologel-poster.png">
        <source src="media/why-autologel.m4v" type='video/mp4'>
        <source src="media/why-autologel.webm" type='video/webm'>
    </video>
</div>
<div class="col-lg-8 col-md-8 col-sm-7">
    <h2 class="modal-heading">
        Why AutoloGel?
    </h2>
    <p class="modal-copy">
        See what AutoloGel offers to your patients.
    </p>
</div>

<!-- Modal Window -->
<div class="modal fade" id="modal-window" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
    <div class="modal-dialog">
        <div class="modal-content">
            <div class="modal-header">
                <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
                <h4 class="modal-title" id="myModalLabel"></h4>
            </div>
            <div class="modal-body">
                <div class="media"></div>
                <div class="copy"></div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
            </div>
        </div>
    </div>
</div>

Here's the javascript:

$(document).ready(function() {

    // Play very small videos in modal box
    if ( $(window).width() > 750 ) {
        var modalvideo = document.getElementsByTagName('video');

        // Hide controls for very small videos
        for (var i = 0; i < modalvideo.length; i++) {
            if ( $(modalvideo[i]).width() < 470 ) {
                $(modalvideo[i]).removeAttr('controls');
                if ( $('html').hasClass('IE-9') ) {
                    $(modalvideo[i]).after('<img class="poster-overlay" src="img/poster-overlay-ie9.png" alt="play video">');
                } else {
                    $(modalvideo[i]).after('<img class="poster-overlay" src="img/poster-overlay.png" alt="play video">');
                }
            }
        }

        // Add click event to video container that brings up video in a modal window
        $('.modal-trigger').on("click", function() {
            if ( $(this).width() < 470 ) {
                // Get video, title and any copy text
                var media = $(this).html();
                var title = $(this).next().children('.modal-heading').text();
                var copy = $(this).next().children('.modal-copy').text();

                // Insert video, title and copy text into modal window
                $('.modal-title').html(title);
                $('.modal-body > .media').html(media);
                $('.modal-body > .copy').text(copy);
                $('#modal-window .poster-overlay').remove('');
                $('#modal-window').modal('show');

                // Autoplay video after modal window has rendered
                $('#modal-window').on('shown.bs.modal', function() {
                    modalvideo[modalvideo.length - 1].setAttribute('controls', 'controls');
                    modalvideo[modalvideo.length - 1].play();
                });

                // Stop play video when modal window is closed
                $('#modal-window').on('hide.bs.modal', function() {
                    modalvideo[modalvideo.length - 1].pause();
                });
            }
        });
    }
});

Thanks for your help!

Share Improve this question edited Nov 22, 2013 at 12:09 Chris Boerger asked Nov 22, 2013 at 1:19 Chris BoergerChris Boerger 831 silver badge7 bronze badges 4
  • weird. What's with the canvas tag? – Jeff Commented Nov 22, 2013 at 1:36
  • It is odd but it helps size the video in iOS 6. Removing the canvas doesn't change the problem. – Chris Boerger Commented Nov 22, 2013 at 12:27
  • Yeah, I didn't think it would, just curious. I'm at a loss as to why it would play when the debugging tools are open... – Jeff Commented Nov 22, 2013 at 13:36
  • That's what I'm struggling with. Why work then? – Chris Boerger Commented Nov 22, 2013 at 14:54
Add a ment  | 

2 Answers 2

Reset to default 1

Figured it out.

The problem was in two parts. For Chrome, there’s some quirk with its cache and copied DOM elements. I figured it was working when the developer tools were open because the cache is disabled. Simply applying a random GET variable at the end of the src attribute for the copied video element to flag it as a different file than the one cached solved the problem.

With IE it was (is) a little different. HubSpot uses Amazon S3 as its CDN and when I looked at the header for the video file its content type was set as application/octet-stream which Internet Explorer doesn’t support. AWS allows this to be set when the file is uploaded but HubSpot is doing this behind the scenes with no user ability to set this that I’m aware of. They're working on a fix.

The solution that ended up working:

$(document).ready(function() {
    // Play very small videos in modal box
    if ( $(window).width() > 750 ) {
        var allvideos = $('video');

        // Hide controls for very small videos
        for (var i = 0; i < allvideos.length; i++) {
            if ( $(allvideos[i]).width() < 470 ) {
                $(allvideos[i]).removeAttr('controls');
                if ( $('html').hasClass('IE-9') ) {
                    $(allvideos[i]).after('<img class="poster-overlay" src="img/poster-overlay.png" alt="play video">');
                } else {
                    $(allvideos[i]).after('<img class="poster-overlay" src="img/poster-overlay.png" alt="play video">');
                }
            }
        }

        // Add click event to video container that brings up video in a modal window
        $('.modal-trigger').on('click', function() {
            if ( $(this).width() < 470 ) {
                // Get video/img, title and any copy text
                var media = $(this).html();
                var title = $(this).next().children('.modal-heading').text();
                var copy = $(this).next().children('.modal-copy').text();
                if (! title.length) { title = '<br>'; }

                // Insert video, title and copy text into modal window
                var modalsrc = [];
                var modaltype = [];
                $(media).children('source').each(function() {
                    modalsrc.push( $(this).attr('src') );
                    modaltype.push( $(this).attr('type') );
                });
                $('.modal-title').html(title);
                $('.modal-body > .media').html(media);
                $('.modal-body > .copy').text(copy);
                $('#modal-window .poster-overlay').remove('');

                // Assign a random version to video src to bypass cache
                var modalsources = $('#modal-window source');
                var nocachesrc = '';
                for (var i = 0; i < modalsources.length; i++) {
                    nocachesrc = modalsrc[i] + '?rnd=' + Math.random()*Math.random();
                    modalsources[i].setAttribute('src', nocachesrc);
                    modalsources[i].setAttribute('type', modaltype[i]);
                }

                var modalvideo = $('#modal-window video');
                modalvideo[0].setAttribute('controls', 'controls');

                // Reveal modal window and play video
                $('#modal-window').modal('show');
                $('#modal-window').on('shown.bs.modal', function() {
                    modalvideo[0].play();
                });

                // Stop playing video when modal window is closed
                $('#modal-window').on('hide.bs.modal', function() {
                    modalvideo[0].pause();
                });
            }
        });
    }
});

Remove the semicolon from the type attribute of the source nodes, should be: type="video/mp4", other browsers are probably just being forgiving of this.

本文标签: internet explorerPlay mp4 video via javascriptStack Overflow