【问题标题】:Play HTML5 video from JSON file using next and prev buttons使用下一个和上一个按钮从 JSON 文件播放 HTML5 视频
【发布时间】:2019-04-13 22:36:30
【问题描述】:

我有 JSON 文件,其中包含视频数据,例如视频标题和视频链接。

这里是 jsffiddle:demo

这是一个 JSON 文件示例:

[{

        "title": "How to create video?",
        "link": "https://storage.googleapis.com/coverr-main/mp4/Sunset-Desert-Run.mp4"
    },

    {
        "title": "How to add audio?",
        "link": "https://app.coverr.co/s3/mp4/Sand-Slow-Walk.mp4"
    },
    {
        "title": "How to add music?",
        "link": "https://app.coverr.co/s3/mp4/Steaming-Yellowstone.mp4"
    },
    {
        "title": "How to add scene?",
        "link": "https://app.coverr.co/s3/mp4/Skater-in-the-Park.mp4"
    },
    {
        "title": "How to preview a video?",
        "link": "https://app.coverr.co/s3/mp4/Stop-Sign.mp4"
    },
    {
        "title": "How to delete video?",
        "link": "https://app.coverr.co/s3/mp4/RV-Park.mp4"
    }
]*

我希望当用户单击上一个按钮时,它应该播放上一个视频并显示视频标题,如果用户单击下一个按钮,它应该播放下一个视频并显示视频标题。这是它的外观。

这是我迄今为止尝试过的。

HTML

        <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

<div id="video-container">

<h1 class="movie-title">Movie title</h1>

   <video class="videoplayer" id="video-player_transformed"
                            playsinline autoplay muted>
 <source src="https://app.coverr.co/s3/mp4/Sand-Slow-Walk.mp4"
                                type="video/mp4">

   </video>

</div>

<div class="btns">
    <div class="prev">
           Prev
   </div>

   <div class="next">
           next
   </div>
 </div>

这里是 CSS

body{
  background: gray;
}
#video-container{
position: relative;
  height: 314px;
  width: 800px;
  display: flex;
  justify-content: center;
   align-self: center;
   overflow: hidden;
}
.movie-title{
position: absolute;
top: 0px;
}

.btns{
  display: flex;
  justify-content: center;
}
.prev, .next{
  display: flex;
  width: 100px;
  height: 50px;
  background: red;
  margin: 20px;
    justify-content: center;
    align-items: center;
    color: white;
    cursor: pointer;
}
video{
height: 400px;
width: 400px;
}

这里是JS

$(document).ready(function () {

      var myData;

            $.ajax({
              dataType: 'json',
              url: 'https://videomill-bot.audiencevideo.com/videoexplainer/videoexplainer/data/video.json',
              data: myData,
              success: function(data) {
                console.log($('.videoplayer').append(myData));
        myData = myData;

              },
            })


var player = document.querySelector('#videoplayer');
var i = 0;
var prev = document.querySelector('.prev');
var next = document.querySelector('.next');

prev.addEventListener('click',function(){
    player.src = myData[i == 0 ? myData.length-- : i--];
    video.play();
},false);

next.addEventListener('click',function(){
    player.src = myData[i ==myData.length-- ? 0 : i++];
    video.play();
},false);

player.src = myData[i];
player.play(); //init the video player


});

很遗憾,单击下一步或上一个按钮后出现以下错误。

Uncaught TypeError: Cannot read property 'length' of undefined

我需要改变什么才能得到我想要的?任何帮助或建议将不胜感激。

【问题讨论】:

    标签: javascript jquery html css html5-video


    【解决方案1】:

    您的问题是因为.ajax() 请求之后的代码在请求完成之前运行,这意味着myData 变量没有可访问的数据。

    要解决这个问题,您可以尝试以下修改后的示例。

    (function($) {
        'use strict';
    
        /**
         * Ajax response data will be stored in this local variable
         * @var    {Array}
         */
        var myData = [];
    
        /**
         * jQuery video element
         * @var    {Object}
         */
        var $player = $('video.videoplayer');
    
        /**
         * jQuery movie title element
         * @var    {Object}
         */
        var $title = $('.movie-title');
    
        /**
         * jQuery previous button element
         * @var    {Object}
         */
        var $prev = $('.prev');
    
        /**
         * jQuery next button element
         * @var    {Object}
         */
        var $next = $('.next');
    
        /**
         * Custom jQuery function to add sources to a media element
         * @param    {Array|String}    sources
         */
        $.fn.setSource = function(sources) {
    
            // Get the media tag (video/audio)
            var tag = this.prop('tagName').toLowerCase();
    
            // Clear any existing sources
            this.empty();
    
            // Check if sources paramater is an array
            if (Array.isArray(sources)) {
    
                // Loop through each source
                for (let i = 0; i < sources.length; i++) {
                    var src = sources[i];
                    var type = /(?:\.([^.]+))?$/.exec(src); // Get file extention (.mp4, .ogv, .webm etc)
    
                    if (type[0]) {
                        type = type[0].replace('.', '');
                    }
                    // Create and append a source tag
                    this.append($('<source>', {
                        src: src,
                        type: tag + '/' + type
                    }));
                }
            } else {
                this.attr('src', sources);
            }
        };
    
        /**
         * Reusable function to update player element
         * @param    {Object}    data    Expects an object with `link` and `title` attributes
         */
        function updatePlayer(data) {
            $player.setSource(data.link); // Set the video source
            $title.text(data.title); // Add the title
        }
    
        // Disable actions because we have no data
        $prev.prop('disabled', true);
        $next.prop('disabled', true);
    
        // Send request to server to recieve data
        $.ajax({
            dataType: 'json',
            url: 'https://videomill-bot.audiencevideo.com/videoexplainer/videoexplainer/data/video.json'
        }).then(function(data) {
            myData = data; // replace `myData` with the ajax response data
    
            // Check if we have data
            if (myData && myData.length) {
    
                // Re-enable actions because we have data
                $prev.prop('disabled', false);
                $next.prop('disabled', false);
    
                updatePlayer(data); // Set the video source (see functions above)
                $player.get(0).play(); // Play the html5 video*
                // *Most browsers will not allow playing without any user interaction
            }
    
        }).fail(function(error) {
            // Request failed, inform user
            alert('There was an error downloading videos, please refresh and try again.');
            console.warn(error);
        });
    
        // On click set video element to PREVIOUS video in myData
        $prev.on('click', function() {
    
            // Check if we have data before attempting to access it
            if (myData && myData.length) {
                updatePlayer(myData[i === 0 ? myData.length - 1 : --i]);
                $player.get(0).play();
            }
    
            // Prevent default click action
            return false;
        });
    
        // On click set video element to NEXT video in myData
        $next.on('click', function() {
    
            // Check if we have data before attempting to access it
            if (myData && myData.length) {
                updatePlayer(myData[i === myData.length - 1 ? 0 : ++i]);
                $player.get(0).play();
            }
    
            // Prevent default click action
            return false;
        });
    
    })(jQuery || window.jQuery);
    

    (这还没有经过测试,有很多方法可以实现你的目标,但它应该让你知道从哪里开始。)

    需要注意的几点:

    • 您使用的是 jQuery,因此我更新了元素选择器以充分利用它。
    • 在您的 ajax 成功函数中,我们将 myData 重新定义为其自身,而不是响应数据(myData = myData 更改为 myData = data
    • 我创建了函数来尝试减少代码重复。
    • 最后,由于存在浏览器限制,请小心使用 javascript 自动播放媒体元素。

    【讨论】:

      猜你喜欢
      • 2012-11-02
      • 1970-01-01
      • 1970-01-01
      • 2013-11-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多