Skip to content

小小前端

明月本无心,行人自回首。

Menu
  • 前端开发
  • 编程技术
  • SQL语句
  • Linux
  • 生活/旅行
  • JSEditor
  • MiniBarCMS
  • About
  • 隐私政策
Menu

个性化html5中的video,打造属于自己的html5视频播放器

Posted on 2017年11月12日2017年11月12日 by king2088

本文使用的都是CSS3以及html5中的video实现的播放器,在PC与手机端都可以完美播放,目前还未实现播放进度条的拖移功能,后续会增加这个功能。
demo效果查看地址:https://king2088.github.io/html5-vPlayer/
先看效果图:

html5 video
html5 video

首先我们要了解一下html5中的media事件以及属性

1、html5 Media api

*loadstart
*progress
*suspend
*abort
*error
*emptied
*stalled
*loadedmetadata
*loadeddata
*canplay
*canplaythrough
*playing
*waiting
*seeking
*seeked
*ended
*durationchange
*timeupdate
*play
*pause
*ratechange
*resize
*volumechange

2、Media properties

[cc lang=”javascript”][ “error”, “src”, “srcObject”, “currentSrc”, “crossOrigin”, “networkState”, “preload”, “buffered”, “readyState”, “seeking”, “currentTime”, “duration”, “paused”, “defaultPlaybackRate”, “playbackRate”, “played”, “seekable”, “ended”, “autoplay”, “loop”, “controls”, “volume”, “muted”, “defaultMuted”, “audioTracks”, “videoTracks”, “textTracks”, “width”, “height”, “videoWidth”, “videoHeight”, “poster” ][/cc]

3、CSS部分代码

[cc lang=”css”]*,
html,
body,
video {
margin: 0;
padding: 0;
}
* #vPlayer,
html #vPlayer,
body #vPlayer,
video #vPlayer {
width: 100%;
background: #000;
position: relative;
overflow: hidden;
}
* #playerContent,
html #playerContent,
body #playerContent,
video #playerContent {
width: 100%;
background: #000;
display: block;
}
* #playerControler,
html #playerControler,
body #playerControler,
video #playerControler {
width: 100%;
z-index: 99999999;
position: absolute;
bottom: 2px;
left: 0;
padding: 4px 0;
opacity: 1;
}
* #playerControler:after,
html #playerControler:after,
body #playerControler:after,
video #playerControler:after {
content: ”;
display: block;
height: 0;
clear: both;
}
* #playerControler .playButtonWrap,
html #playerControler .playButtonWrap,
body #playerControler .playButtonWrap,
video #playerControler .playButtonWrap {
width: 24px;
height: 24px;
border-radius: 14px;
border: 2px #ccc solid;
margin-left: 8px;
float: left;
}
* #playerControler .playButtonWrap .playButton,
html #playerControler .playButtonWrap .playButton,
body #playerControler .playButtonWrap .playButton,
video #playerControler .playButtonWrap .playButton {
margin: 4px 0 0 8px;
width: 0;
height: 0;
border-bottom: 8px solid transparent;
border-top: 8px solid transparent;
border-left: 10px solid #ccc;
}
* #playerControler .playButtonWrap .pauseButton,
html #playerControler .playButtonWrap .pauseButton,
body #playerControler .playButtonWrap .pauseButton,
video #playerControler .playButtonWrap .pauseButton {
margin: 6px 0 0 8px;
width: 5px;
height: 12px;
border-left: 2px #ccc solid;
border-right: 2px #ccc solid;
display: none;
}
* #playerControler #vplayerTimeLine,
html #playerControler #vplayerTimeLine,
body #playerControler #vplayerTimeLine,
video #playerControler #vplayerTimeLine {
color: #ccc;
line-height: 30px;
font-size: 12px;
float: left;
margin-left: 2%;
}
* #playerControler .vPlayVolumeWrap,
html #playerControler .vPlayVolumeWrap,
body #playerControler .vPlayVolumeWrap,
video #playerControler .vPlayVolumeWrap {
float: right;
margin: 6px 10% 0 0;
width: 25%;
}
* #playerControler .vPlayVolumeWrap #volumeIcon,
html #playerControler .vPlayVolumeWrap #volumeIcon,
body #playerControler .vPlayVolumeWrap #volumeIcon,
video #playerControler .vPlayVolumeWrap #volumeIcon {
width: 0px;
height: 0px;
padding: 5px 3px;
border-width: 5px 10px 5px 0px;
border-color: transparent #ccc transparent transparent;
border-style: solid;
/*喇叭效果*/
-webkit-box-shadow: inset 15px 0 #666;
-moz-box-shadow: inset 15px 0 #666;
box-shadow: inset 15px 0 #666;
float: left;
display: inline-block;
}
* #playerControler .vPlayVolumeWrap #vPlayVolume,
html #playerControler .vPlayVolumeWrap #vPlayVolume,
body #playerControler .vPlayVolumeWrap #vPlayVolume,
video #playerControler .vPlayVolumeWrap #vPlayVolume {
width: 70%;
height: 2px;
background: #ccc;
position: relative;
float: left;
margin: 10px 0 0 10px;
display: inline-block;
}
* #playerControler .vPlayVolumeWrap #vPlayVolume #dragBar,
html #playerControler .vPlayVolumeWrap #vPlayVolume #dragBar,
body #playerControler .vPlayVolumeWrap #vPlayVolume #dragBar,
video #playerControler .vPlayVolumeWrap #vPlayVolume #dragBar {
width: 8px;
height: 8px;
border-radius: 4px;
background: #369;
position: absolute;
top: -3px;
left: 0;
cursor: pointer;
}
* #playerControler .vPlayVolumeWrap #vPlayVolume #dragMask,
html #playerControler .vPlayVolumeWrap #vPlayVolume #dragMask,
body #playerControler .vPlayVolumeWrap #vPlayVolume #dragMask,
video #playerControler .vPlayVolumeWrap #vPlayVolume #dragMask {
position: absolute;
left: 0;
top: 0;
background: #369;
width: 0;
height: 2px;
}
* #playerControler #fullScreen,
html #playerControler #fullScreen,
body #playerControler #fullScreen,
video #playerControler #fullScreen {
width: 24px;
height: 24px;
float: right;
margin: 5px 2% 0 0;
display: block;
background: url(“data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAA/UlEQVRIS91V2w3CMAy8qP0HNoAJoOrtQ9mgI8AEiAlgBAZxJEaADWCBGqUqUktbkSAVAfmMH+ezk7PBwMcMnB+fB7DW5kVRLI0xixq7K8lJna2IXAGMandnVT3GcbxJksTZytNg4JKr6rajbTeS4xcAD/OOZN4JICInAHNjzCpN00PIfGrFnUnO+gDUGUi+NRsRacU3EnU5hLD4CoBy+s8D9WVRvaxG/Fu99gVsPdOQQF/fP2NQDUmfZcG3HV3x//cPBpeKUuwA5CR3vr13ftbaTFX3AC4kp6Fy7bMPXst1VYnbCVnF5BHksw8uAI5RFK17F05IS3x9f/8n3wFQDZcZDw/gGQAAAABJRU5ErkJggg==”) no-repeat center;
}
* #progressBar,
html #progressBar,
body #progressBar,
video #progressBar {
width: 100%;
background: #333;
height: 2px;
position: absolute;
bottom: 0;
display: block;
}
* #progressBar .reloadProgress,
html #progressBar .reloadProgress,
body #progressBar .reloadProgress,
video #progressBar .reloadProgress {
width: 0;
height: 2px;
background: #ccc;
position: relative;
left: 0;
top: 0;
z-index: 999;
}
* #progressBar .reloadProgress .progress,
html #progressBar .reloadProgress .progress,
body #progressBar .reloadProgress .progress,
video #progressBar .reloadProgress .progress {
width: 0;
height: 2px;
background: #008b8b;
position: absolute;
left: 0;
top: 0;
z-index: 9999;
}
* .fadeIn,
html .fadeIn,
body .fadeIn,
video .fadeIn {
animation-name: fadeIn;
}
* .fadeOut,
html .fadeOut,
body .fadeOut,
video .fadeOut {
animation-name: fadeOut;
}
@-moz-keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@-webkit-keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@-o-keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}
@-moz-keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@-webkit-keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@-o-keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}
video::-webkit-media-controls,
video::-moz-media-controls,
video::-webkit-media-controls-enclosure {
display: none !important;
}
video::-webkit-media-controls-panel,
video::-webkit-media-controls-panel-container,
video::-webkit-media-controls-start-playback-button {
display: none !important;
-webkit-appearance: none;
}[/cc]

4、html部分代码

[cc lang=”html”]




vPlayer




[/cc]

5、javascript部分代码

[cc lang=”javascript”]”use strict”
window.onload = function () {
var vPlayer = document.getElementById(‘vPlayer’)
var playerContent = document.getElementById(‘playerContent’)
var playerControl = document.getElementById(‘playerControler’)
var play = document.getElementById(‘play’)
var pause = document.getElementById(‘pause’)
var reloadProgressDOM = document.getElementById(‘progressBar’)
var progressTimeShowDOM = document.getElementById(‘vplayerTimeLine’)
var volumeIconDOM = document.getElementById(‘volumeIcon’)
var vPlayVolumeDOM = document.getElementById(‘vPlayVolume’)
var dragBarDOM = document.getElementById(‘dragBar’)
var dragMaskDOM = document.getElementById(‘dragMask’)
var fullscreen = document.getElementById(‘fullScreen’)
var _playerControlHidden,_playTime

var isSupportTouch = ‘ontouchend’ in document ? true : false;
// console.log(‘isSupportTouc’,isSupportTouch)
playerContent.controls = false
playerContent.preload = ‘auto’

//3000ms hidden player
playerControlHidden()
//play
play.onclick = function () {
vPlayerPlay()
}
// play.ontouchstart = function () {
// vPlayerPlay()
// }

//pause
pause.onclick = function () {
vPlayerPause()
}
// pause.ontouchstart = function () {
// vPlayerPause()
// }
//show player control
if(!isSupportTouch){
playerContent.addEventListener(‘mouseover’,playerControlShow)
}else{
playerContent.addEventListener(‘touchstart’,playerControlShow)
}

//hidden player control
if(!isSupportTouch){
playerContent.addEventListener(‘mouseleave’,playerControlHidden)
}else{
playerContent.addEventListener(‘touchend’,playerControlHidden)
}

function vPlayerPlay() {
progressBar()
playerContent.play()
play.style.display = ‘none’;
pause.style.display = ‘block’;
}

function vPlayerPause() {
if(_playTime){
clearInterval(_playTime)
}
playerContent.pause()
pause.style.display = ‘none’;
play.style.display = ‘block’;
}

function playerControlShow() {
// console.log(‘start’)
if(_playerControlHidden){
clearTimeout(_playerControlHidden)
}
if(!playerControl.style.opacity) return
playerControl.style.display = ‘block’
playerControl.style.animation = ‘fadeIn 1s’
playerControl.style.opacity = 1
}

function playerControlHidden() {
// console.log(‘hidden’)
_playerControlHidden = setTimeout(function () {
playerControl.style.animation = ‘fadeOut 1s’
playerControl.style.opacity = 0
playerControl.style.display = ‘none’
},3000)
}

function progressBar() {
_playTime = setInterval(function () {
// console.log(playerContent.buffered.end(0))
//reload progress time (加载的时间/总时间)*100 = 加载的百分比
var reloadProgressTime = (playerContent.buffered.end(0) / playerContent.duration) * 100
reloadProgressDOM.children[0].style.width = reloadProgressTime + ‘%’

//progress time = (playerContent.currentTime/playerContent.duration)*100
var progressTime = playerContent.currentTime
reloadProgressDOM.children[0].children[0].style.width = (progressTime / playerContent.duration) * 100 + ‘%’

//progress time show
progressTimeShowDOM.innerText = secToTime(progressTime)+’ | ‘+secToTime(playerContent.duration)
// console.log(playerContent.duration,playerContent.currentTime,playerContent.buffered.end(0))
if(playerContent.currentTime === playerContent.duration){
clearInterval(_playTime)
vPlayerPause()
reloadProgressDOM.children[0].children[0].style.width = 0
}
},1)
}

//volume drag control
playerContent.volume = 0.5
dragMaskDOM.style.width = ‘50%’
dragBarDOM.style.left = ‘50%’

if(!isSupportTouch) {
dragBarDOM.onmousedown = function (event) {
drag(event, this)
}
}else {
dragBarDOM.ontouchstart = function (event) {
console.log(event)
drag(event, this)
}
}

/**
* drag element
* @param event event
* @param ele element
*/
function drag(event,ele) {
var event = event || window.event;
var lengthX
if(!isSupportTouch){
lengthX = event.clientX – ele.offsetLeft;
}else {
lengthX = event.touches[0].clientX – ele.offsetLeft;
}

if(!isSupportTouch) {
document.onmousemove = function (event) {
dragMove(event,ele,lengthX)
}
}else{
document.ontouchmove = function (event) {
dragMove(event,ele,lengthX)
}
}
}

/**
* drag move volume: volume+ volume-
* @param event event
* @param ele element
* @param x lengthX:clientX
*/
function dragMove(event,ele,x) {
var event = event || window.event;
var barleft
if(!isSupportTouch) {
barleft = event.clientX – x;
}else {
barleft = event.touches[0].clientX – x;
}
if(barleft < 0) barleft = 0; else if(barleft > vPlayVolumeDOM.offsetWidth – dragBarDOM.offsetWidth)
barleft = vPlayVolumeDOM.offsetWidth – dragBarDOM.offsetWidth;
dragMaskDOM.style.width = barleft +’px’ ;
ele.style.left = barleft + ‘px’;
var volumeValue = barleft/(vPlayVolumeDOM.offsetWidth-dragBarDOM.offsetWidth)
// console.log(volumeValue)
playerContent.volume = parseFloat(volumeValue)
//防止选择内容–当拖动鼠标过快时候,弹起鼠标,bar也会移动,修复bug
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
}

document.onmouseup = function(){
document.onmousemove = null; //移除事件
}
document.ontouchend = function () {
document.ontouchstart = null
document.ontouchmove = null
}

volumeIconDOM.onclick = function () {
if(playerContent.volume != 0){
playerContent.volume = 0
dragMaskDOM.style.width = ‘0’
dragBarDOM.style.left = ‘0’
}else{
playerContent.volume = 0.5
dragMaskDOM.style.width = ‘50%’
dragBarDOM.style.left = ‘50%’
}
}

//video fullscreen
fullscreen.onclick = function () {
if(playerContent.webkitRequestFullScreen){
playerContent.webkitRequestFullScreen()
}else if(playerContent.mozRequestFullScreen){
playerContent.mozRequestFullScreen()
}else {
playerContent.requestFullscreen()
}
}
console.log(‘networkState’,playerContent.networkState)

/**
* format second to hh:mm:ss
* @param second second
* @returns {*} format time to 00:00:00
*/
var secToTime = function (second) {
var t
if(second > -1){
var hour = Math.floor(second/3600)
var min = Math.floor(second/60) % 60
var sec = second % 60
if(hour < 10) { t = '0'+ hour + ":" } else { t = hour + ":" } if(min < 10){t += "0"} t += min + ":" if(sec < 10){t += "0"} t += sec.toFixed(0) } return t } }[/cc] 整个项目很简单,希望能够帮助到准备进入video事件以及视频处理的同学,此项目已经上传到github,如果你喜欢,请记得给我加星哦! github:https://github.com/king2088/html5-vPlayer

发表评论 取消回复

您的电子邮箱地址不会被公开。 必填项已用*标注

分类

近期文章

  • cordova-plugin-camera在某些android机型中拍照或选择文件时闪退出错的解决办法 2019年10月24日
  • JavaScript nodeJS base64加密解密url参数 2019年10月15日
  • 利用expressJS编写reset api 2019年4月13日
  • angular4 + http拦截器 2019年3月21日
  • ionic navCtrl.pop如何传递参数给上一个页面 2018年11月16日
  • ionic3搭建开发/测试环境 2018年10月25日
  • ionic2、3双击硬件back按键退出应用 2018年10月24日
  • VMware安装Mac OS High Sierra 10.12及高版本无法全屏 2018年8月24日

近期评论

  • 手表资讯发表在《ReactJS环境搭建》
  • king2088发表在《ionic中使用热更新插件cordova-hot-code-push》
  • 重阳节的诗句发表在《常用的sql语句》
  • 新郎致辞发表在《PHP代码实现WordPress相关文章的几种方法》
  • 霸道总裁发表在《vsftpd 提示 unrecognized service 解决办法》

归档

标签

Ajax Android Angular APP Cordova CSS css3 express html5 ionic Java javascript jQuery Linux loading mac Mac OS mongodb MySQL node nodejs PHP react SQL SSH VirtualBox vue vue-cli win10 WordPress WP REST API 主题 兼容性 前端 备份 插件 数据库 数组 服务器 正则表达式 浏览器 热更新 目录 组件 错误
2023年 4月
一 二 三 四 五 六 日
 12
3456789
10111213141516
17181920212223
24252627282930
« 10月    
© 2023 小小前端 | Powered by Superbs Personal Blog theme