自己写的video播放器
最近放了个MV在博客上,总觉得浏览器的自带控件不够美观,于是...我就自己动手写一个video播放器
觉得bilibili的播放器还可以,于是在外观上模仿了一下
截图:
亮出我的代码:
html
<html>
<head>
<meta charset="UTF-8">
<title>video</title>
<script src='jquery.min.js'></script>
<script src='video.js'></script>
<link rel="stylesheet" href="video.css" type="text/css" />
</head>
<body height="100%">
<div id="video" style="width:600px;height:400px;">
<script>
video('video','http://file.littlehands.site/MV/Shelter.mp4','https://i1.hdslb.com/bfs/archive/d7bec4f0ccd05ab2e85da8e1389add959e68ffa8.jpg');
</script>
</div>
</body>
</html>
javascript
var touch_dblclick_time;
//触摸双击事件
/* $.fn.touch_dblclick = function(fc){
$(this).on('touchstart',function(){
touch_dblclick_time++;
setTimeout(function(){
touch_dblclick_time = 0;
}, 1000);
if (touch_dblclick_time > 1) {
fc();
touch_dblclick_time = 0;
}
});
} */
function video(id,url,img){
/* @id 生成元素id
* @url 视频链接
* @img 预览图片链接,可空
*
* 该函数将会加载一个自定义视频和视频控件
* video元素宽高由生成元素宽高决定
*/
//处理空参数
if (!img){
img = '';
}
//打印html代码
$('#' + id).html('' +
'<div id="' + id + '_box" class="video_box">' +
'<video id="' + id + '_video" style="display: none;" class="video_video"><br>你用这种浏览器,还好意思装逼!</video>' +
'<div id="' + id + '_load" class="video_load">' +
'<img src="' + img + '"/>' +
'<div class="video_icon"></div>' +
'</div>' +
'<div id="' + id + '_control" class="video_control" style="display: none;">' +
'<div id="' + id + '_time" class="video_time">' +
'<span id="' + id + '_time_current" class="video_time_current">00:00</span>' +
'<span>/</span>' +
'<span id="' + id + '_time_total" class="video_time_total">00:00</span>' +
'</div>' +
'<div id="' + id + '_progress" class="video_progress">' +
'<div id="' + id + '_progress_bar" style="width:0;" class="video_progress_bar"></div>' +
'</div>' +
'<div class="video_right">' +
'<div class="video_icon video_voice_btn" id="' + id + '_voice_btn"></div>' +
'<div id="' + id + '_voice_div" class="video_voice_div" style="display: none;">' +
'<div id="' + id + '_voice" class="video_voice">' +
'<div id="' + id + '_voice_bar" class="video_voice_bar" style="height: 50%;"></div>' +
'</div>' +
'</div>' +
'<div style="width: 0.5rem;height: 2rem;"></div>' +
'<div class="video_icon video_screen" id="' + id + '_screen"></div>' +
'</div>' +
'<div class="video_icon video_state" id="' + id + '_state"></div>' +
'</div>' +
'<div id="' + id + '_display" class="video_display" style="display: none;"></div>' +
'</div>' +
''
);
//打印全局变量
$('#' + id).after('' +
'<script>' +
'var ' +
id + '_display_mouse_xy,' +
id + '_mobile,' +
id + '_mobile_time = 0,' +
id + '_control_mouse,' +
id + '_control_touch,' +
id + '_load_del' +
';' +
'</script>'
);
/* icon 信息
* @vocal -3.47222rem -1.725rem 有声的
* @voicaless -4.86111rem -1.725rem 无声的
* @screen_full -3.47222rem 0.38rem 全屏
* @screen_restore -4.86111rem 0.38rem 还原屏幕
* @play -0rem -0rem 播放
* @pause -0rem -3.15rem 暂停
*/
//局部变量声明
var
_ = $('#' + id),
_box = $('#' + id + '_box'),
_video = $('#' + id + '_video'),
_state = $('#' + id + '_state'),
_control = $('#' + id + '_control'),
_screen = $('#' + id + '_screen'),
_time_current = $('#' + id + '_time_current'),
_time_total = $('#' + id + '_time_total'),
_progress = $('#' + id + '_progress'),
_progress_bar = $('#' + id + '_progress_bar'),
_voice = $('#' + id + '_voice'),
_voice_bar = $('#' + id + '_voice_bar'),
_voice_btn = $('#' + id + '_voice_btn'),
_voice_div = $('#' + id + '_voice_div'),
_display = $('#' + id + '_display'),
_load = $('#' + id + '_load')
;
//load加载层被点击
_load.click(function(){
_load.remove();
_video.css('display','inline');
_control.css('display','inline');
_video.html('<source src="' + url + '"><br>你用这种浏览器,还好意思装逼!');
window[id + '_load_del'] = true;
_display.css('display','inline');
video_play_mobile_process(id);
_video.get(0).play();
_state.css('background-position','-0rem -3.15rem');
_voice_bar.height(_voice.height() * _video.get(0).volume);
});
//播放控制
_display.click(function(){
video_play(id);
});
_display.on('touchend',function(){
window[id + '_mobile'] = true;
video_play(id,true);
});
_state.click(function(){
if (window[id + '_mobile']){
window[id + '_mobile'] = false;
}else{
if (_video.get(0).paused){
_video.get(0).play();
_state.css('background-position','-0rem -3.15rem');
}else{
_video.get(0).pause();
_state.css('background-position','-0rem -0rem');
}
}
});
/*_video.touch_dblclick(function(){
//window[id + '_mobile'] = true;
video_play(id,true);
});*/
//屏幕按钮被点击
_screen.click(function(){
if (window[id + '_mobile']){
window[id + '_mobile'] = false;
}else{
if (_box.css('position') !== 'fixed'){
//全屏
_box.addClass('video_box_screen_full');
_video.addClass('video_video_screen_full');
_screen.css('background-position','-4.86111rem 0.38rem');
}else{
//还原
_box.removeClass('video_box_screen_full');
_video.removeClass('video_video_screen_full');
_screen.css('background-position','-3.47222rem 0.38rem');
}
}
});
_display.dblclick(function(){
_screen.click();
});
//时间
_video.on('loadedmetadata',function(){
_time_total.html(video_time_conversion(this.duration));
});
_video.on('timeupdate',function(){
if (!window[id + '_progress_click']){
_time_current.html(video_time_conversion(this.currentTime));
_progress_bar.width(this.currentTime / this.duration * 100 + '%');
}
_video.css('z-index','0');
});
//拖动进度条
_progress.mousedown(function(e){
//按下
if (window[id + '_mobile']){
window[id + '_mobile'] = false;
}else{
window[id + '_progress_click'] = true;
video_progress_position(e.pageX,id);
}
});
$(window).mouseup(function(){
//放开
if (window[id + '_progress_click']){
_video.get(0).currentTime = _progress_bar.width() / _progress.width() * _video.get(0).duration;
window[id + '_progress_click'] = false;
}
});
$('body').mousemove(function(e){
//移动
video_progress_position(e.pageX,id);
});
//播放结束
_video.on('ended',function(){
_state.css('background-position','-0rem -0rem');
});
//控制组件
_display.mousemove(function(e){
//鼠标移动
var xy = e.pageX + e.pageY;
if (window[id + '_load_del'] && !window[id + '_mobile'] && !(xy == window[id + '_display_mouse_xy'])){
_display.removeClass('video_control_hide');
_control.css('display','inline');
window[id + '_display_mouse_xy'] = xy;
video_control_mouse_process(id);
}
});
_control.mousemove(function(){
video_control_mouse_process(id);
});
_control.mouseenter(function(){
window[id + '_control_mouse_on'] = true;
video_control_mouse_process(id);
});
_control.mouseleave(function(){
window[id + '_control_mouse_on'] = false;
video_control_mouse_process(id);
});
_control.on('touchstart',function(){
clearTimeout(window[id + '_control_touch']);
});
_control.on('touchend',function(){
video_play_mobile_process(id);
});
//拖动音量条
_voice.mousedown(function(e){
//按下
if (window[id + '_mobile']){
window[id + '_mobile'] = false;
}else{
window[id + '_voice_click'] = true;
video_voice_position(e.pageY,id);
}
});
$(window).mouseup(function(){
//放开
if (window[id + '_voice_click']){
window[id + '_voice_click'] = false;
}
});
$('body').mousemove(function(e){
//移动
video_voice_position(e.pageY,id);
if(!window[id + '_voice_click'] && !window[id + '_voice_btn_mouse'] && !window[id + '_voice_div_mouse']){
_voice_div.css('display','none');
}
});
//静音
_video.on('volumechange',function(){
if(this.volume == 0){
_voice_btn.css('background-position','-4.86111rem -1.725rem');
}else{
_voice_btn.css('background-position','-3.47222rem -1.725rem');
window[id + '_volume'] = this.volume;
}
});
_voice_btn.click(function(){
if(!window[id + '_mobile']){
voice_process(id);
}else{
window[id + '_mobile'] = false;
}
});
//音量按钮
_voice_btn.mouseenter(function(){
window[id + '_voice_btn_mouse'] = true;
_voice_div.css('display','inline');
});
_voice_btn.mouseleave(function(){
window[id + '_voice_btn_mouse'] = false;
});
_voice_div.mouseenter(function(){
window[id + '_voice_div_mouse'] = true;
});
_voice_div.mouseleave(function(){
window[id + '_voice_div_mouse'] = false;
});
_voice_btn.on('touchend',function(){
window[id + '_mobile'] = true;
if(_voice_div.css('display') == 'none'){
_voice_div.css('display','inline');
}else{
voice_process(id);
}
});
}
//播放控制
function video_play(id,mobile){
var
video = $('#' + id + '_video')[0],
_state = $('#' + id + '_state'),
_control = $('#' + id + '_control'),
_display = $('#' + id + '_display')
;
if (window[id + '_mobile']){
if (mobile){
clearTimeout(window[id + '_control_touch']);
if (_control.css('display') == 'none'){
_control.css('display','inline');
video_play_mobile_process(id);
}else{
_control.css('display','none');
}
}else{
window[id + '_mobile'] = false;
}
}else{
if(!window[id + '_control_mouse_on']){
if (video.paused){
video.play();
_state.css('background-position','-0rem -3.15rem');
}else{
video.pause();
_state.css('background-position','-0rem -0rem');
}
video_control_mouse_process(id);
}
}
}
function video_play_mobile_process(id){
var
_control = $('#' + id + '_control')
;
window[id + '_control_touch'] = setTimeout(function(){
_control.css('display','none');
},5000);
}
//时间转化 seconds => minutes
function video_time_conversion(time){
var minutes,seconds;
minutes = parseInt(time / 60);
seconds = parseInt(time - 60 * minutes);
if (seconds < 10){
seconds = '0' + seconds;
}
if (minutes < 10){
minutes = '0' + minutes;
}
return minutes + ':' + seconds;
};
//拖动进度条
function video_progress_position(x,id){
if (window[id + '_progress_click']){
var x1 = x - $('#' +id + '_progress').offset().left,
x2 = $('#' +id + '_progress').width();
if (x1 <= x2){
x = x1;
}else{
x = x2;
}
$('#' +id + '_progress_bar').width(x);
$('#' + id + '_time_current').html(video_time_conversion(x / x2 * $('#' + id + '_video').get(0).duration));
}
}
//拖动音量条
function video_voice_position(y,id){
var
_video = $('#' +id + '_video'),
_voice = $('#' +id + '_voice'),
_voice_bar = $('#' +id + '_voice_bar');
if (window[id + '_voice_click']){
var y1 = _voice.offset().top + _voice.height() -y,
y2 = _voice.height();
if (y1 <= y2){
y = y1;
}else{
y = y2;
}
_voice_bar.height(y);
_video.get(0).volume = _voice_bar.height() / _voice.height();
}
}
//控制组件
function video_control_mouse_process(id){
var
_control = $('#' + id + '_control'),
_display = $('#' + id + '_display')
;
clearTimeout(window[id + '_control_mouse']);
window[id + '_control_mouse'] = setTimeout(function(){
if (!window[id + '_control_mouse_on'] && !window[id + '_voice_click'] && !window[id + '_progress_click']){
_display.addClass('video_control_hide');
_control.css('display','none');
}
},5000);
}
//静音
function voice_process(id){
var
_video = $('#' + id + '_video'),
_voice = $('#' + id + '_voice'),
_voice_bar = $('#' + id + '_voice_bar')
;
if(_video.get(0).volume == 0){
_video.get(0).volume = window[id + '_volume'] || 1;
}else{
_video.get(0).volume = 0;
}
_voice_bar.height(_video.get(0).volume * _voice.height());
}
css
.video_load img{
width: 100%;
height: 100%;
filter: blur(0.34133rem);
-webkit-filter: blur(0.34133rem);
cursor: pointer;
}
.video_icon{
background-image: url(icon.png);
background-repeat: no-repeat;
background-size: 6.25rem;
cursor: pointer;
}
.video_load .video_icon{
width: 3.438rem;
height: 3rem;
position: absolute;
bottom: 0.5rem;
right: 0.5rem;
}
.video_load{
z-index: 3;
}
.video_box{
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
overflow: hidden;
position: relative;
width: 100%;
height: 100%;
z-index: 2;
}
.video_control{
position: absolute;
bottom: 0px;
left: 0px;
width: 100%;
height: 2rem;
color: white;
display: inline;
background-color: rgba(0, 0, 0, 0.498039);
z-index: 2;
}
.video_time{
position: absolute;
height: 2rem;
}
.video_time span{
font-family: arial,sans-serif;
float: left;
height: 100%;
line-height: 2rem;
}
.video_time_current{
width: 3rem;
text-align: right;
}
.video_time_total{
width: 3rem;
text-align: left;
}
.video_progress{
background: #4c4c4c;
position: absolute;
bottom: 0.75em;
left: 6.25rem;
right: 4.5rem;
height: 0.5rem;
cursor: pointer;
}
.video_progress_bar{
background-color: #de698c;
height: 100%;
position: absolute;
}
.video_progress_bar:after{
content: "";
background-color: #FFF;
height: 1rem;
width: 1rem;
position: absolute;
top: -0.25rem;
right: -0.95rem;
border-radius: 50%;
}
.video_right{
height: 100%;
float: right;
margin-right: 0.5rem;
}
.video_right div{
float: left;
}
.video_voice_btn {
width: 1rem;
height: 2rem;
background-position: -3.47222rem -1.725rem;
z-index: 3;
}
.video_screen {
width: 1.3rem;
height: 2rem;
background-position: -3.47222rem 0.38rem;
}
.video_right .video_icon:hover{
opacity: 0.75;
}
.video_state{
position: absolute;
top: -3rem;
right: 0.5rem;
width: 3.438rem;
height: 3rem;
}
.video_video{
//height: 130%;
height: 100%;
width: 100%;
//top: -15%;
//position: relative;
//position: absolute;
background: #000;
color: #FFF;
}
.video_box_screen_full{
position: fixed !important;
width: auto !important;
height: auto !important;
top: 0 !important;
bottom: 0 !important;
left: 0 !important;
right: 0 !important;
z-index: 999 !important;
}
.video_video_screen_full{
height: 100% !important;
top: auto !important;
}
.video_control_hide{
cursor: none;
}
.video_control_hide .video_icon{
cursor: none;
}
.video_display{
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
z-index: 1;
}
.video_voice_div{
background: rgba(0, 0, 0, 0.498039);
position: absolute;
width: 1rem;
height: 5rem;
top: -5rem;
right: 2.3rem;
z-index: 3;
}
.video_voice{
position: absolute;
top: 0.5rem;
left: 0.35rem;
background: #4c4c4c;
width: 0.3rem;
height: 4rem;
cursor: pointer;
}
.video_voice_bar{
position: absolute;
bottom: 0;
width: 100%;
background: #de698c;
}
.video_voice_bar:before{
content: "";
position: absolute;
width: 0.5rem;
height: 0.5rem;
border-radius: 50%;
background-color: #FFF;
top: -0.3rem;
left: -0.1rem;
}
/* icon 信息
* @vocal -3.47222rem -1.725rem 有声的
* @voicaless -4.86111rem -1.725rem 无声的
* @screen_full -3.47222rem 0.38rem 全屏
* @screen_restore -4.86111rem 0.38rem 还原屏幕
* @play -0rem -0rem 播放
* @pause -0rem -3.15rem 暂停
*/
同一个页面播放多个视频怎么办啊
回复 @jrotty:
id不要重复就可以
/diy/video/video1.html
回复 @小さな手は:
示例的视频是什么啊,感觉很好看
回复 @Sakura_Love:
Shelter