Search code examples
jquerytwitter-bootstrap-3bootstrap-modalvideo.js

Bootstrap 3 modal and video.js video isn't resized properly


The following page displays a thumbnail image, that when clicked, brings up a Bootstrap 3 modal with the video. It works, but if the video is too tall for the window, it extends below the window, and the user can't see the entire video (and has to scroll). I've tried various resizing strategies, but nothing seems to work. Suggestions appreciated. URLs obscured, sorry. And I'm required to use Bootstrap 3.

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
        <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
        <script src="https://vjs.zencdn.net/7.8.4/video.js"></script>
        <link href="https://vjs.zencdn.net/7.8.4/video-js.css" rel="stylesheet">
    </head>
    <body>
        <a href="#" data-toggle="modal" data-target="#viewVideoModal" data-video-url="https://VIDEOFILE" class="video-link">
            <img id="img-401" src="https://VIDEOFILE?thumb=1" height="280" width="157">
        </a>
        <div class="modal fade" id="viewVideoModal" tabindex="-1" role="dialog" aria-labelledby="viewVideoModalLabel">
            <div class="modal-dialog" role="document" style="margin-top:50px;">
                <div class="modal-content">
                    <div class="modal-header">
                        <button type="button" class="close" data-dismiss="modal">
                            <span aria-hidden="true">
                                &times;
                            </span>
                            <span class="sr-only">
                                Close
                            </span>
                        </button>
                    </div>
                    <div class="modal-body" id="viewVideoBody"></div>
                </div>
            </div>
        </div>
        <script>
    var player;
    $('#viewVideoModal').on('show.bs.modal', function (event) {
        var button = $(event.relatedTarget); // Button that triggered the modal
        var videoSrc = button.data('video-url');
        var videoTag = document.createElement('video');
        videoTag.setAttribute('class', 'video-js vjs-fluid center-block vjs-default-skin');
        videoTag.setAttribute('controls', '');
        videoTag.setAttribute('preload', 'auto');
        videoTag.setAttribute('data-setup', '{}');

        // Create a new source tag
        var sourceTag = document.createElement('source');
        sourceTag.setAttribute('src', videoSrc);
        sourceTag.setAttribute('type', 'video/mp4');

        // Append the source tag to the video tag
        videoTag.appendChild(sourceTag);

        // Get the modal body and clear its contents
        var modalBody = document.getElementById('viewVideoBody');
        modalBody.innerHTML = '';

        // Append the video tag to the modal body
        modalBody.appendChild(videoTag);

        // Initialize the video player
        player = videojs(videoTag);
    });
        </script>
    </body>
</html>

Solution

  • I've settled on the following solution. It's not perfect, because, depending on the aspect ratio of the video, there are black bars either on the sides of the video or above and below the video. But otherwise, it works.

    I made 3 changes to the original code I posted.

    • I manually set the width/height of the modal-dialog, to width:80vw; height: 80vh
    • I changed the vjs-fluid class to vjs-fill
    • I manually set the width and height of videoModalBody every time that a video is instantiated, to width:80vw; height: 80vh

    Here is the modified code:

    <!DOCTYPE html>
    <html>
        <head>
            <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
            <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
            <script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
            <script src="https://vjs.zencdn.net/7.8.4/video.js"></script>
            <link href="https://vjs.zencdn.net/7.8.4/video-js.css" rel="stylesheet">
        </head>
        <body>
            <a href="#" data-toggle="modal" data-target="#viewVideoModal" data-video-url="https://VIDEOFILE" class="video-link">
                <img id="img-401" src="https://VIDEOFILE?thumb=1" height="280" width="157">
            </a>
            <div class="modal fade" id="viewVideoModal" tabindex="-1" role="dialog" aria-labelledby="viewVideoModalLabel">
                <div class="modal-dialog" role="document" style="width:80vw;height:80vh">
                    <div class="modal-content">
                        <div class="modal-header">
                            <button type="button" class="close" data-dismiss="modal">
                                <span aria-hidden="true">
                                    &times;
                                </span>
                                <span class="sr-only">
                                    Close
                                </span>
                            </button>
                        </div>
                        <div class="modal-body" id="viewVideoBody"></div>
                    </div>
                </div>
            </div>
            <script>
        var player;
        $('#viewVideoModal').on('show.bs.modal', function (event) {
            var button = $(event.relatedTarget); // Button that triggered the modal
            var videoSrc = button.data('video-url');
            var videoTag = document.createElement('video');
            videoTag.setAttribute('class', 'video-js vjs-fill center-block vjs-default-skin');
            videoTag.setAttribute('controls', '');
            videoTag.setAttribute('preload', 'auto');
            videoTag.setAttribute('data-setup', '{}');
    
            // Create a new source tag
            var sourceTag = document.createElement('source');
            sourceTag.setAttribute('src', videoSrc);
            sourceTag.setAttribute('type', 'video/mp4');
    
            // Append the source tag to the video tag
            videoTag.appendChild(sourceTag);
    
            // Get the modal body and clear its contents
            var modalBody = document.getElementById('viewVideoBody');
            modalBody.setAttribute('style', 'height:80vh;width:80vw');
            modalBody.innerHTML = '';
    
            // Append the video tag to the modal body
            modalBody.appendChild(videoTag);
    
            // Initialize the video player
            player = videojs(videoTag);
        });
            </script>
        </body>
    </html>