Ich mache einen HTML5-Video-/Audio-Playlist-Player mit benutzerdefinierten Steuerelementen.Erstellen eines html5 Video/Audio-Playlist-Players mit benutzerdefinierten Steuerelementen
Ich habe die benutzerdefinierten Steuerelemente für ein einzelnes Video arbeiten, aber ich habe Probleme beim Binden dieser Steuerelemente und currentTime/Dauer Eigenschaften auf jedes Video, auf das ein Benutzer klicken könnte.
Hier ist a jsfiddle, die zeigt was ich meine.
Der Code ist auch am Ende dieser Frage. Bitte haben Sie keine Angst, die unteren 90% des JS sind die benutzerdefinierten Steuerelemente. Die oberen 10% definieren das Videoobjekt und die on
Klickfunktion, um das gewünschte Video auszuwählen.
Ich habe die Standardeinstellung "Video 2" von 3 wiedergegeben. Die benutzerdefinierten Steuerelemente steuern "Video 2". Die Schaltflächen schalten die Wiedergabe/Pause jedes Videos um, aber Sie werden feststellen, dass die benutzerdefinierten Steuerelemente immer noch "Video 2" steuern, unabhängig davon, auf welche Schaltfläche geklickt wurde.
Im Grunde muss ich nur einen Weg finden, dass, wenn Sie auf jeden Video-Button klicken, dass alle Steuerelemente und Eigenschaften (currentTime, Dauer) dann an das ausgewählte Video gebunden werden.
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;
}