使用下一个和上一个按钮播放JSON文件中的HTML5视频 [英] Play HTML5 video from JSON file using next and prev buttons
问题描述
我有一个JSON文件,其中包含视频数据,例如视频标题和视频链接.
这是jsffiddle:演示
这是一个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
我需要更改以获得我想要的东西吗?任何帮助或建议都将不胜感激.
您的问题是因为.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自动播放媒体元素.
I have JSON file which contains video data eg video title and video link.
Here is jsffiddle:demo
Here is a JSON file sample:
[{
"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"
}
]*
I want when the user clicks a prev button it should play the previous video and display video title too if the user clicks next button it should play the next video and display video title too. here is visual how it looks.
here is what I have tried so far.
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>
Here is 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;
}
Here is 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
});
Unfortunately, I am getting the following error after clicking buttons next or prev.
Uncaught TypeError: Cannot read property 'length' of undefined
What do I need to change to get what I want? any help or suggestion will be apreciated thanks.
Your issue is because the code after the .ajax()
request is running before the request has completed, meaning the myData
variable has no accessible data.
To solve this you could try something like the modified example below.
(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);
(this hasn't been tested and there are many ways to achieve what you are aiming to do but it should give you an idea of where to start.)
A few things to note:
- You are using jQuery so I have updated element selectors to make the most out of it.
- In your ajax success function you we're redefining
myData
as its self and not with the response data (myData = myData
changed tomyData = data
) - I have created functions to try and mitigate code duplication.
- Finally, be careful autoplaying media elements with javascript as browser restrictions apply.
这篇关于使用下一个和上一个按钮播放JSON文件中的HTML5视频的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!