使用自定义控件制作HTML5视频/音频播放列表播放器
making an html5 video/audio playlist player with custom controls
我正在制作一个带有自定义控件的HTML5视频/音频播放列表播放器。
我有适用于单个视频的自定义控件,但我无法将这些控件和当前时间/持续时间属性绑定到用户可能单击的每个视频上。
这里有一个jsfiddle,说明了我的意思。
代码也在这个问题的底部。请不要害怕,JS的底部90%是自定义控件。前 10% 是定义视频对象和on
单击功能以选择所需的视频。
我已将默认值设置为播放"视频 2"(共 3 个)。自定义控件控制"视频 2"。这些按钮切换每个视频的播放/暂停,但您会注意到,无论单击哪个按钮,自定义控件仍控制"视频 2"。
基本上,我只需要找到一种方法,当您单击每个视频按钮时,所有控件和属性(当前时间,持续时间)都会绑定到所选视频。
.HTML:
<button class="icon" data-id="1" >Video 1</button>
<button class="icon" data-id="2">Video 2</button>
<button class="icon" data-id="3">Video 3</button>
<div id="url" data-id="2"></div>
<div class="videoContainer">
<video data-id="1" width="100%" height="80%" poster="http://www.birds.com/wp-content/uploads/home/bird.jpg" >
<source src="http://video-js.zencoder.com/oceans-clip.mp4" type="video/mp4" />
</video>
<video data-id="2" width="100%" height="80%" poster="http://www.logobird.com/wp-content/uploads/2011/03/new-google-chrome-logo.jpg">
<source src="http://www.html5rocks.com/en/tutorials/video/basics/Chrome_ImF.mp4" type="video/mp4" />
</video>
<video data-id="3" width="100%" height="80%" poster="http://cheerioscoupons.info/wp-content/uploads/_Cheerios-Coupons-1-300x283.jpg">
<source src="http://media.jilion.com/videos/demo/midnight_sun_sv1_360p.mp4" type="video/mp4" />
</video>
<div class="progress">
<span class="bufferBar"></span>
<span class="timeBar"></span>
</div>
<div class="control">
<div class="btnPlay btn btn-primary" title="Play/Pause video">PLAY</div>
<div class="time">
<span class="current"></span> /
<span class="duration"></span>
</div>
<div class="sound sound2 btn btn-primary" title="Mute/Unmute sound"></div>
<div class="volume" title="Set volume">VOLUME
<span class="volumeBar"></span>
</div>
<div class="btnFS btn btn-primary" title="Switch to full screen">FULLSCREEN</div>
</div><!--/control-->
</div><!--/videocontainer-->
.JS:
var url=$('#url').data('id');
var $video=$('video[data-id="'+url+'"]');
$('video').not($('video[data-id="'+url+'"]')).hide();
$('.icon').click(function(){
var id=$(this).data('id'),
$video=$("video[data-id='" + id +"']");
$('video').each(function () {
this.pause();
//this.currentTime = 0;
});
$('video').not($video).hide();
$video.show();
$video.get(0).play();
});
//before everything get started
$video.on('loadedmetadata', function() {
//set video properties
$('.current').text(timeFormat(0));
$('.duration').text(timeFormat($video.get(0).duration));
updateVolume(0, 0.7);
//start to get video buffering data
setTimeout(startBuffer, 150);
//bind video events
$('.videoContainer').on('click', function() {
$('.btnPlay').find('i').addClass('icon-pause');
$(this).unbind('click');
$video.get(0).play();
});
});
//display video buffering bar
var startBuffer = function() {
var currentBuffer = $video.get(0).buffered.end(0);
var maxduration = $video.get(0).duration;
var perc = 100 * currentBuffer / maxduration;
$('.bufferBar').css('width',perc+'%');
if(currentBuffer < maxduration) {
setTimeout(startBuffer, 500);
}
};
//display current video play time
$video.on('timeupdate', function() {
var currentPos = $video.get(0).currentTime;
var maxduration = $video.get(0).duration;
var perc = 100 * currentPos / maxduration;
$('.timeBar').css('width',perc+'%');
$('.current').text(timeFormat(currentPos));
});
//CONTROLS EVENTS
//video screen and play button clicked
$video.on('click', function() { playpause(); } );
$('.btnPlay').on('click', function() { playpause(); } );
var playpause = function() {
if($video.get(0).paused || $video.get(0).ended) {
$('.btnPlay').find('i').addClass('icon-pause');
$video.get(0).play();
}
else {
$('.btnPlay').find('i').removeClass('icon-pause');
$video.get(0).pause();
}
};
//fullscreen button clicked
$('.btnFS').on('click', function() {
if($.isFunction($video.get(0).webkitEnterFullscreen)) {
$video.get(0).webkitEnterFullscreen();
}
else if ($.isFunction($video.get(0).mozRequestFullScreen)) {
$video.get(0).mozRequestFullScreen();
}
else {
alert('Your browsers doesn''t support fullscreen');
}
});
//sound button clicked
$('.sound').click(function() {
$video.get(0).muted = !$video.get(0).muted;
$(this).toggleClass('muted');
if($video.get(0).muted) {
$('.volumeBar').css('width',0);
}
else{
$('.volumeBar').css('width', $video.get(0).volume*100+'%');
}
});
//VIDEO EVENTS
//video canplay event
$video.on('canplay', function() {
$('.loading').fadeOut(100);
});
//video canplaythrough event
//solve Chrome cache issue
var completeloaded = false;
$video.on('canplaythrough', function() {
completeloaded = true;
});
//video ended event
$video.on('ended', function() {
$('.btnPlay').removeClass('paused');
$video.get(0).pause();
});
$video.on('ended', function() {
var nextVideo= $(this).next();
if(!$('video').last()){
$(this).hide();
nextVideo.show();
nextVideo.get(0).play();
}
}); //onended
//video seeking event
$video.on('seeking', function() {
//if video fully loaded, ignore loading screen
if(!completeloaded) {
// $('.loading').fadeIn(200);
}
});
//video seeked event
$video.on('seeked', function() { });
//video waiting for more data event
$video.on('waiting', function() {
$('.loading').fadeIn(200);
});
//VIDEO PROGRESS BAR
//when video timebar clicked
var timeDrag = false; /* check for drag event */
$('.progress').on('mousedown', function(e) {
timeDrag = true;
updatebar(e.pageX);
});
$(document).on('mouseup', function(e) {
if(timeDrag) {
timeDrag = false;
updatebar(e.pageX);
}
});
$(document).on('mousemove', function(e) {
if(timeDrag) {
updatebar(e.pageX);
}
});
var updatebar = function(x) {
var progress = $('.progress');
//calculate drag position
//and update video currenttime
//as well as progress bar
var maxduration = $video.get(0).duration;
var position = x - progress.offset().left;
var percentage = 100 * position / progress.width();
if(percentage > 100) {
percentage = 100;
}
if(percentage < 0) {
percentage = 0;
}
$('.timeBar').css('width',percentage+'%');
$video.get(0).currentTime = maxduration * percentage / 100;
};
//VOLUME BAR
//volume bar event
var volumeDrag = false;
$('.volume').on('mousedown', function(e) {
volumeDrag = true;
$video.get(0).muted = false;
$('.sound').removeClass('muted');
updateVolume(e.pageX);
});
$(document).on('mouseup', function(e) {
if(volumeDrag) {
volumeDrag = false;
updateVolume(e.pageX);
}
});
$(document).on('mousemove', function(e) {
if(volumeDrag) {
updateVolume(e.pageX);
}
});
var updateVolume = function(x, vol) {
var volume = $('.volume');
var percentage;
//if only volume have specificed
//then direct update volume
if(vol) {
percentage = vol * 100;
}
else {
var position = x - volume.offset().left;
percentage = 100 * position / volume.width();
}
if(percentage > 100) {
percentage = 100;
}
if(percentage < 0) {
percentage = 0;
}
//update volume bar and video volume
$('.volumeBar').css('width',percentage+'%');
$video.get(0).volume = percentage / 100;
//change sound icon based on volume
if($video.get(0).volume == 0){
$('.sound').removeClass('sound2').addClass('muted');
}
else if($video.get(0).volume > 0.5){
$('.sound').removeClass('muted').addClass('sound2');
}
else{
$('.sound').removeClass('muted').removeClass('sound2');
}
};
//Time format converter - 00:00
var timeFormat = function(seconds){
var m = Math.floor(seconds/60)<10 ? Math.floor(seconds/60) : Math.floor(seconds/60);
var s = Math.floor(seconds-(m*60))<10 ? "0"+Math.floor(seconds-(m*60)) : Math.floor(seconds-(m*60));
return m+":"+s;
};
.CSS:
/* video container */
.videoContainer{
width:97.8%;
height:250px;
overflow:hidden;
background:#ccc;
color:#ccc;
}
/*** VIDEO CONTROLS CSS ***/
/* control holder */
.control{
background:#333;
color:#ccc;
width:100%;
z-index:5;
}
.control >div{
display:inline-block;
}
.control div.btn {
cursor:pointer;
}
.control div.text{
font-size:18px;
line-height:30px;
text-align:center;
width:20px;
}
.control div.selected{
font-size:18px;
color:#ccc;
}
.control div.sound{
background:url(/assets/img/video/control.png) no-repeat -88px -30px;
border:none;
}
.control div.sound2{
background:url(/assets/img/video/control.png) no-repeat -88px -60px !important;
}
.control div.muted{
background:url(/assets/img/video/control.png) no-repeat -88px 0 !important;
}
.control div.btnFS{
float:right;
}
/* PROGRESS BAR CSS */
/* Progress bar */
.progress {
width:100%;
height:24px;
position:relative;
float:left;
cursor:pointer;
background: gray; /* fallback */
background:-moz-linear-gradient(top,#666,#333);
background:-webkit-linear-gradient(top,#666,#333);
background:-o-linear-gradient(top,#666,#333);
box-shadow:0 2px 3px #333 inset;
-moz-box-shadow:0 2px 3px #333 inset;
-webkit-box-shadow:0 2px 3px #333 inset;
border-radius:5px;
-moz-border-radius:5px;
-webkit-border-radius:5px;
}
.progress span {
height:100%;
position:relative;
top:0;
left:0;
display:inline-block;
height:100%;
position:absolute;
top:0;
left:0;
display:block;
border-radius:5px;
-moz-border-radius:5px;
-webkit-border-radius:5px;
}
.timeBar{
position:absolute;
left:0px;
top:0px;
z-index:10;
width:0;
background: #006DCC; /* fallback */
background:-moz-linear-gradient(top,#A0DCFF 50%,#3FB7FC 50%,#16A9FF 100%);
background:-webkit-linear-gradient(top,#A0DCFF 50%,#3FB7FC 50%,#16A9FF 100%);
background:-o-linear-gradient(top,#A0DCFF 50%,#3FB7FC 50%,#16A9FF 100%);
box-shadow:0 0 1px #fff;
-moz-box-shadow:0 0 1px #fff;
-webkit-box-shadow:0 0 1px #fff;
}
.bufferBar{
z-index:5;
width:0;
background: #777;
background:-moz-linear-gradient(top,#999,#666);
background:-webkit-linear-gradient(top,#999,#666);
background:-o-linear-gradient(top,#999,#666);
box-shadow:2px 0 5px #333;
-moz-box-shadow:2px 0 5px #333;
-webkit-box-shadow:2px 0 5px #333;
}
/* time and duration */
/* VOLUME BAR CSS */
/* volume bar */
.volume{
position:relative;
cursor:pointer;
width:100px;
height:24px;
}
.volumeBar{
display:block;
height:100%;
position:absolute;
top:0;
left:0;
background-color:#006DCC;
z-index:10;
border-radius:5px;
-moz-border-radius:5px;
-webkit-border-radius:5px;
}
/* OTHERS CSS */
/* video screen cover */
.loading, #init{
width:100%;
height:100%;
z-index:2;
}
#init{
cursor:pointer;
}
试试这个
我已经在图标单击上添加了此类
$("video[data-id='" + id +"']").addClass("active");
$video = $('video.active');
因此,这里尝试根据活动类选择视频,它工作正常。 当单击另一个视频时,请删除以前的活动类并将其添加到新选择的视频中。
相关文章:
- Javascript::通过HTML5音频播放器播放列表播放多个音频文件
- 创建一个只有播放和暂停的Javascript音频播放列表
- 需要帮助修复我的javascript"对于循环“;播放音频播放列表
- JS音频播放器,点击列表项即可播放
- 自动播放音频播放列表SoundManager2 bar ui
- 制作一个html5音频播放列表,自动播放一首又一首歌曲
- 使用自定义控件制作HTML5视频/音频播放列表播放器
- HTML5音频播放列表-如何在第一个音频文件结束后播放第二个音频文件
- 如何从<ul>播放列表到相同的<音频>标签
- 我怎么能在一个页面上有两个这样的音频播放器,而不点击其中一个,另一个播放或显示隐藏播放列表
- HTML5 web应用程序中的音频文件播放列表
- 创建HTML下拉列表的音乐,可以在一个音频播放器内播放
- Javascript音频与播放列表
- HTML5/JavaScript/jQuery音频播放列表
- 如何连锁播放几个HTML5音频文件像一个流畅的播放列表
- HTML5音频播放器不工作的播放列表
- 自动播放WordPress音频播放列表(MediaElement.js)
- 使用ngCordova media / onic / firebase创建一个音频播放列表
- Knockout音频播放列表
- HTML5/JavaScript音频播放列表