欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

小强的HTML5移动开发之路(5)——制作一个漂亮的视频播放器

程序员文章站 2022-07-05 23:13:03
在前面几篇文章中介绍了html5的特点和需要掌握的基础知识,下面我们开始真正的体验一下html5的优势,我们开始制作一个漂亮的视频播放器吧先别急,在开始制作之前先了解一下视频文件的基本知识。 一、视...

在前面几篇文章中介绍了html5的特点和需要掌握的基础知识,下面我们开始真正的体验一下html5的优势,我们开始制作一个漂亮的视频播放器吧小强的HTML5移动开发之路(5)——制作一个漂亮的视频播放器先别急,在开始制作之前先了解一下视频文件的基本知识。

一、视频的格式

目前比较主流和使用比较的的视频格式主要有:avi、rmvb、wmv、mpeg4、ogg、webm。这些视频都是由视频、音频、编码格式三部分组成的。在html5中,根据的不同,目前拥有多套不同的编码器:

h.264(个人不看好):这个编码器是苹果包括苹果手机中的编码器,拥有专利的视频编码器。在编码及传输过程中的任何部分都可能需要收取专利费。因此safari(苹果的浏览器)和intenet explorer支持该编码器,但是在开源已经成为大势的当下,还在浏览器中收取专利费,个人实在是不看好啊。

theora:这是一个不受专利限制的编码格式,并且对所有等级的编码、传输以及回放免费的视频编码器。chrome、firefox以及opera支持该编码器。

vp8:该视频编码器与theora相似,但是其拥有者是google公司,google公司已经开源,因此不需要专利费。chrome、firefox以及opera支持该编码器。

aac:音频编码器,与h.264相同,该音频编码器拥有专利限制,safari、chrome和internet explorer支持该音频编码器。

mp3:也是一个专利技术,safari、chrome和internet explorer支持该音频编码器。

pcm:存储由模拟数字转换器编码的完整数据,在音频cd上存储数据的一种格式。是以中国无损编码器,它的文件大小一般是aac和mp3文件的几倍,safari、firefox和internet explorer支持该音频编码器。

vorbis:文件扩展名为.ogg,有时候也被称为ogg vorbis,该音频编码器不受专利保护,因此版权免费。支持的浏览器包括chrome、firefox和opera.

主流浏览器和设备支持的视频和音频

 

浏览器 容器 视频 音频
apple ios mp4 h.264 acc、mp3、pcm
apple safari mp4 h.264  
google android(pre v.3) -- -- --
google chrome mp4、ogg、webm theora、vp8 acc、mp3、vorbis
microsoft internet explorer mp4 h.264 acc、mp3
mozilla firefox ogg、webm theora、vp8 pcm、vorbis
opera ogg、webm theora、vp8 pcm、vorbis

二、html5中的属性

 

在html5中可以使用

 


 

video标签中有很多属性,例如controls属性可以控制是否有控制台。

 



从上面的视频格式中我们可以看到不同的浏览器支持不同的视频格式,这样我们可以采用标签指定多种格式的视频,默认情况下浏览器会自动启动下载文件来确定其类型。

 

 



三、制作视频播放器

 

index.html

 





<script src=http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js></script><script src=../vendorscript.js></script><script src=video.js></script>

custom html5 video controls with jquery

 

demo 1

custom html5 video controls

your browser does not support the video tag.

this is html5 video with custom controls

 

/

 

vca==" video=""> 

speed:

x1

x3

 

 

 

 

 


style.css

 

 

/* video container */
.videocontainer{
	width:600px;
	height:350px;
	position:relative;
	overflow:hidden;
	background:#000;
	color:#ccc;
}

/* video caption css */
.caption{
	display:none;
	position:absolute;
	top:0;
	left:0;
	width:100%;
	padding:10px;
	color:#ccc;
	font-size:20px;
	font-weight:bold;
	box-sizing: border-box;
	-ms-box-sizing: border-box;
	-webkit-box-sizing: border-box;
	-moz-box-sizing: border-box;
	background: #1f1f1f; /* fallback */
	background:-moz-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);
	background:-webkit-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);
	background:-o-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);
}

/*** video controls css ***/
/* control holder */
.control{
	background:#333;
	color:#ccc;
	position:absolute;
	bottom:0;
	left:0;
	width:100%;
	z-index:5;
	display:none;
}
/* control top part */
.topcontrol{
	height:11px;
	border-bottom:1px solid #404040;
	padding:1px 5px;
	background:#1f1f1f; /* fallback */
	background:-moz-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);
	background:-webkit-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);
	background:-o-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);
}
/* control bottom part */
.btmcontrol{
	clear:both;
	background: #1f1f1f; /* fallback */
	background:-moz-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);
	background:-webkit-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);
	background:-o-linear-gradient(top,#242424 50%,#1f1f1f 50%,#171717 100%);
}
.control p.btn {
	float:left;
	width:34px;
	height:30px;
	padding:0 5px;
	border-right:1px solid #404040;
	cursor:pointer;
}
.control p.text{
	font-size:12px;
	font-weight:bold;
	line-height:30px;
	text-align:center;
	font-family:verdana;
	width:20px;
	border:none;
	color:#777;
}
.control p.btnplay{
	background:url(control.png) no-repeat 0 0;
	border-left:1px solid #404040;
}
.control p.paused{
	background:url(control.png) no-repeat 0 -30px;
}
.control p.btnstop{
	background:url(control.png) no-repeat 0 -60px;
}
.control p.spdtext{
	border:none;
	font-size:14px;
	line-height:30px;
	font-style:italic;
}
.control p.selected{
	font-size:15px;
	color:#ccc;
}
.control p.sound{
	background:url(control.png) no-repeat -88px -30px;
	border:none;
	float:right;
}
.control p.sound2{
	background:url(control.png) no-repeat -88px -60px !important;
}
.control p.muted{
	background:url(control.png) no-repeat -88px 0 !important;
}
.control p.btnfs{
	background:url(control.png) no-repeat -44px 0;
	float:right;
}
.control p.btnlight{
	background:url(control.png) no-repeat -44px -60px;
	border-left:1px solid #404040;
	float:right;
}
.control p.lighton{
	background:url(control.png) no-repeat -44px -30px !important;
}

/* progress bar css */
/* progress bar */
.progress {
	width:85%;
	height:10px;
	position:relative;
	float:left;
	cursor:pointer;
	background: #444; /* 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:10px;
	-moz-border-radius:10px;
	-webkit-border-radius:10px;
}
.progress span {
	height:100%;
	position:absolute;
	top:0;
	left:0;
	display:block;
	border-radius:10px;
	-moz-border-radius:10px;
	-webkit-border-radius:10px;
}
.timebar{
	z-index:10;
	width:0;
	background: #3fb7fc; /* 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 */
.time{
	width:15%;
	float:right;
	text-align:center;
	font-size:11px;
	line-height:12px;
}

/* volume bar css */
/* volume bar */
.volume{
	position:relative;
	cursor:pointer;
	width:70px;
	height:10px;
	float:right;
	margin-top:10px;
	margin-right:10px;
}
.volumebar{
	display:block;
	height:100%;
	position:absolute;
	top:0;
	left:0;
	background-color:#eee;
	z-index:10;
}

/* others css */
/* video screen cover */
.loading, #init{
	position:absolute;
	top:0;
	left:0;
	width:100%;
	height:100%;
	background:url(loading.gif) no-repeat 50% 50%;
	z-index:2;
	display:none;
}
#init{
	background:url(bigplay.png) no-repeat 50% 50% !important;
	cursor:pointer;
}

video.js

 

 

$(document).ready(function(){
	//initialize
	var video = $('#myvideo');
	
	//remove default control when js loaded
	video[0].removeattribute(controls);
	$('.control').show().css({'bottom':-45});
	$('.loading').fadein(500);
	$('.caption').fadein(500);
 
	//before everything get started
	video.on('loadedmetadata', function() {
		$('.caption').animate({'top':-45},300);
			
		//set video properties
		$('.current').text(timeformat(0));
		$('.duration').text(timeformat(video[0].duration));
		updatevolume(0, 0.7);
			
		//start to get video buffering data 
		settimeout(startbuffer, 150);
			
		//bind video events
		$('.videocontainer')
		.append('

 

') .hover(function() { $('.control').stop().animate({'bottom':0}, 500); $('.caption').stop().animate({'top':0}, 500); }, function() { if(!volumedrag && !timedrag){ $('.control').stop().animate({'bottom':-45}, 500); $('.caption').stop().animate({'top':-45}, 500); } }) .on('click', function() { $('#init').remove(); $('.btnplay').addclass('paused'); $(this).unbind('click'); video[0].play(); }); $('#init').fadein(200); }); //display video buffering bar var startbuffer = function() { var currentbuffer = video[0].buffered.end(0); var maxduration = video[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[0].currenttime; var maxduration = video[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[0].paused || video[0].ended) { $('.btnplay').addclass('paused'); video[0].play(); } else { $('.btnplay').removeclass('paused'); video[0].pause(); } }; //speed text clicked $('.btnx1').on('click', function() { fastfowrd(this, 1); }); $('.btnx3').on('click', function() { fastfowrd(this, 3); }); var fastfowrd = function(obj, spd) { $('.text').removeclass('selected'); $(obj).addclass('selected'); video[0].playbackrate = spd; video[0].play(); }; //stop button clicked $('.btnstop').on('click', function() { $('.btnplay').removeclass('paused'); updatebar($('.progress').offset().left); video[0].pause(); }); //fullscreen button clicked $('.btnfs').on('click', function() { if($.isfunction(video[0].webkitenterfullscreen)) { video[0].webkitenterfullscreen(); } else if ($.isfunction(video[0].mozrequestfullscreen)) { video[0].mozrequestfullscreen(); } else { alert('your browsers doesn't support fullscreen'); } }); //light bulb button clicked $('.btnlight').click(function() { $(this).toggleclass('lighton'); //if lightoff, create an overlay if(!$(this).hasclass('lighton')) { $('body').append('

 

'); $('.overlay').css({ 'position':'absolute', 'width':100+'%', 'height':$(document).height(), 'background':'#000', 'opacity':0.9, 'top':0, 'left':0, 'z-index':999 }); $('.videocontainer').css({ 'z-index':1000 }); } //if lighton, remove overlay else { $('.overlay').remove(); } }); //sound button clicked $('.sound').click(function() { video[0].muted = !video[0].muted; $(this).toggleclass('muted'); if(video[0].muted) { $('.volumebar').css('width',0); } else{ $('.volumebar').css('width', video[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[0].pause(); }); //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[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[0].currenttime = maxduration * percentage / 100; }; //volume bar //volume bar event var volumedrag = false; $('.volume').on('mousedown', function(e) { volumedrag = true; video[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[0].volume = percentage / 100; //change sound icon based on volume if(video[0].volume == 0){ $('.sound').removeclass('sound2').addclass('muted'); } else if(video[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 ? 0+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; }; });
运行效果:

 

 

小强的HTML5移动开发之路(5)——制作一个漂亮的视频播放器