'https://video.miaocloud.net/002ef208cc2949bba4e9439f2c3ba769/be792fd5b0c245429da6ede4a704ec08-81cec51c4b0c8d5b6cb9df02d7f94b0d-sd.mp4'
>上报播放进度
function timeupdateFun(e) {
var currentTime = e.target.currentTime;
var duration = e.target.duration;
// 如需上报播放进度---在此
// e.target.currentTime
showTimeBox.onmousedown = function (event) {
var event = event || window.event;
// 距离左边距离(起始位置)
var leftVal = event.clientX - this.offsetLeft;
document.onmousemove = function (event) {
var event = event || window.event;
if (!drag) { // 是否可以拖拽
return;
barleft = event.clientX - leftVal;
if (barleft <= 0) {
barleft = 0;
} else if (barleft >= scroll.offsetWidth - showTimeBox.offsetWidth) {
barleft = scroll.offsetWidth - showTimeBox.offsetWidth;
// 进度条
var _x = barleft * 100 / (scroll.offsetWidth - showTimeBox.offsetWidth);
timeBar.style.width = _x + "%";
// 时间展示区域
showTimeBox.style.left = barleft + 'px';
// 拖拽计算播放-- 根据拖拽计算播放进度
//时间拖拽计算
var updateTime = (times * _x) / 100;
videoObj.currentTime = updateTime;
// 时间进度条
curTime.innerHTML = getTimeStr(updateTime);
//防止选择内容--当拖动鼠标过快时候,弹起鼠标,bar也会移动,修复bug
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
document.onmouseup = function () {
document.onmousemove = null; //弹起鼠标不做任何操作
>播放上下资源
根据播放资源列表、索引ID、资源列表长度
索引idx = 资源列表.length - 1
根据URL地址传递资源id及播放时长 ,
在onloadedmetadata 在续播处理 currentTime =续播时间
playRes();
function playRes() {
if (!getResId) {
return;
for (var i = 0; i < resourceList.length; i++) {
if (getResId == resourceList[i].resId) {
document.getElementById('video').src = resourceList[i].url;
document.getElementById('video').load();
// 当指定的音频/视频的元数据已加载时,会发生 loadedmetadata 事件。
document.getElementById('video').onloadedmetadata = function () {
document.getElementById('video').play();
document.getElementById("playStatus").innerText = '暂停';
// 断点继播
document.getElementById('video').currentTime = getResPlayTime;
curPlayIdx = i;
return;
// ###播放指定资源及断点续播###
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
margin: 0;
padding: 0;
/* 去掉全屏时显示的自带控制条 */
video::-webkit-media-controls {
display: none !important;
.player {
width: 720px;
height: 400px;
margin: 0 auto;
position: relative;
#video {
object-fit: fill;
width: 720px;
height: 400px;
.control {
position: relative;
bottom: 0;
width: 100%;
display: flex;
overflow: hidden;
align-items: center;
.play-status {
color: red;
.upPlay,
.downPlay,
.fullscreen {
background: #000;
color: #fff;
margin: 0 5px;
cursor: pointer
;
font-size: 16px;
.progress-outer {
height: 10px;
background-color: #ccc;
margin: 0 5px;
flex: 1;
position: relative;
border-radius: 7px;
.progress-inner {
height: 10px;
background-color: blue;
width: 0;
border-radius: 7px 0 0 7px;
.play-status {
width: 40px;
font-size: 18px;
background-color: #333;
color: #fff;
.video-timer {
position: absolute;
background: blue;
color: #fff;
left: 0%;
width: 120px;
text-align: center;
font-size: 12px;
height: 15px;
line-height: 15px;
/* display: flex;
align-items: center;
justify-content: center; */
border-radius: 7px;
vertical-align: middle;
cursor: pointer;
top: -2px;
</style>
</head>
<!-- http://nettuts.s3.amazonaws.com/763_sammyJSIntro/trailer_test.mp4 -->
<!-- https://video.miaocloud.net/002ef208cc2949bba4e9439f2c3ba769/be792fd5b0c245429da6ede4a704ec08-81cec51c4b0c8d5b6cb9df02d7f94b0d-sd.mp4 -->
<div class="player">
<video id="video" controls poster=""
src="http://nettuts.s3.amazonaws.com/763_sammyJSIntro/trailer_test.mp4"></video>
<div class="control">
<div class="play-status" id="playStatus">播放</div>
<div class="upPlay" id="playUp">上一个</div>
<div class="downPlay" id="playDown">下一个</div>
<div class="fullscreen" id="fullscreen">全屏</div>
<div class="progress-outer" id="scroll">
<div class="progress-inner" id="timeBar"></div>
<div class="video-timer" id="showTimeBox">
<span id="currentTime">00:00</span><em>/</em>
<span id="duration">00:00</span>
</div>
</div>
</div>
</div>
<script>
// ***以下如需要自行封装***
var videoObj = document.querySelector('video');
videoObj.addEventListener('canplay', canplayFun);
videoObj.addEventListener('timeupdate', timeupdateFun);
videoObj.addEventListener('loadedmetadata', onloadedmetadata);
videoObj.addEventListener('play', playFun);
videoObj.addEventListener('pause', pauseFun);
videoObj.addEventListener('ended', endedFun);
// 资源列表
var resourceList = [{
resId: 1,
url: 'http://nettuts.s3.amazonaws.com/763_sammyJSIntro/trailer_test.mp4'
resId: 2,
url: 'https://video.miaocloud.net/002ef208cc2949bba4e9439f2c3ba769/be792fd5b0c245429da6ede4a704ec08-81cec51c4b0c8d5b6cb9df02d7f94b0d-sd.mp4'
// 总时长
var times = 0;
// 是否拖拽快进
var drag = false;
// 当前播放状态
var playStatus = document.getElementById("playStatus");
// 播放当前时间
var curTime = document.getElementById("currentTime");
// 播放总时长
var duration = document.getElementById("duration");
// 进度条移动距离 --inner
var timeBar = document.getElementById("timeBar");
// 进度条总宽度 --outer
var scroll = document.getElementById('scroll');
// 播放时间展示区域
var showTimeBox = document.getElementById('showTimeBox');
//数组播放资源位置
var curPlayIdx = 0;
// 当前资源播放URL
var curVideoURL = '';
// 播放上一个资源
var playUp = document.getElementById('playUp');
// 播放下一个资源
var playDown = document.getElementById('playDown');
// 全屏播放
var fullscreen = document.getElementById('fullscreen');
playDown.onclick = playNextFun;
playUp.onclick = playUpFun;
fullscreen.onclick = fullscreenFun;
// ###播放指定资源及断点续播###
var getResId = getQueryString('resid');
var getResPlayTime = getQueryString('playtime');
playRes();
function playRes() {
if
(!getResId) {
return;
for (var i = 0; i < resourceList.length; i++) {
if (getResId == resourceList[i].resId) {
document.getElementById('video').src = resourceList[i].url;
document.getElementById('video').load();
// 当指定的音频/视频的元数据已加载时,会发生 loadedmetadata 事件。
document.getElementById('video').onloadedmetadata = function () {
document.getElementById('video').play();
document.getElementById("playStatus").innerText = '暂停';
// 断点继播
document.getElementById('video').currentTime = getResPlayTime;
curPlayIdx = i;
return;
// ###播放指定资源及断点续播###
//距离左边距离
var barleft = 0;
showTimeBox.onmousedown = function (event) {
var event = event || window.event;
// 距离左边距离(起始位置)
var leftVal = event.clientX - this.offsetLeft;
document.onmousemove = function (event) {
var event = event || window.event;
if (!drag) { // 是否可以拖拽
return;
barleft = event.clientX - leftVal;
if (barleft <= 0) {
barleft = 0;
} else if (barleft >= scroll.offsetWidth - showTimeBox.offsetWidth) {
barleft = scroll.offsetWidth - showTimeBox.offsetWidth;
// 进度条
var _x = barleft * 100 / (scroll.offsetWidth - showTimeBox.offsetWidth);
timeBar.style.width = _x + "%";
// 时间展示区域
showTimeBox.style.left = barleft + 'px';
// 拖拽计算播放-- 根据拖拽计算播放进度
//时间拖拽计算
var updateTime = (times * _x) / 100;
videoObj.currentTime = updateTime;
// 时间进度条
curTime.innerHTML = getTimeStr(updateTime);
//防止选择内容--当拖动鼠标过快时候,弹起鼠标,bar也会移动,修复bug
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
document.onmouseup = function () {
document.onmousemove = null; //弹起鼠标不做任何操作
// 播放下一个资源
function playNextFun() {
if (curPlayIdx >= resourceList.length - 1) {
alert('最后一个资源')
return;
curPlayIdx++;
playListFun(curPlayIdx);
// 播放上一个资源
function playUpFun() {
if (curPlayIdx <= 0) {
alert('已是第一个资源');
return;
curPlayIdx--;
playListFun(curPlayIdx);
// 播放资源List
function playListFun(idx) {
var playURL = "";
var len = resourceList.length;
if (!resourceList.length) {
return;
playURL = resourceList[idx].url;
document.getElementById('video').src = playURL
document.getElementById('video').load();
document.getElementById('video').play();
// videoObj.load();
// videoObj.play();
// 全屏播放
function fullscreenFun() {
var ele = document.getElementById('video');
if (ele.requestFullscreen) {
ele.requestFullscreen();
} else if (ele.mozRequestFullScreen) {
ele.mozRequestFullScreen();
} else if (ele.webkitRequestFullScreen) {
ele.webkitRequestFullScreen();
//是否能播放
function canplayFun(e) {
times = e.target.duration;
// duration = times;
drag = true;
//总时长
duration.innerHTML = getTimeStr(times);
function onloadedmetadata() {
playStatus.onclick = function () {
if (videoObj.paused || videoObj.ended) {
//播放
videoObj.play();
playStatus.innerText = '暂停';
} else {
//暂停
videoObj.pause();
playStatus.innerText = '播放';
//更新时间
function timeupdateFun(e) {
var currentTime = e.target.currentTime;
var duration = e.target.duration;
// 如需上报播放进度---在此
// e.target.currentTime
var percent = currentTime / duration * 100;
// console.log(percent)
timeBar.style.width = percent + "%";
// 时间滚动区域
var _timeBoxWidth = scroll.offsetWidth - showTimeBox.offsetWidth;
var x = currentTime * _timeBoxWidth / duration;
// 时间进度条
showTimeBox.style.left = x + 'px';
curTime.innerHTML = getTimeStr(currentTime);
//播放
function playFun() {
//监听播放
//暂停
function pauseFun() {
// 监听暂停
//监听结束
function endedFun() {
playNextFun()
//将以秒为单位的时间变成“00:00:00”格式的字符串
function getTimeStr(time) {
var h = Math.floor(time / 3600);
var m = Math.floor(time % 3600 / 60);
var s = Math.floor(time % 60);
h = h >= 10 ? h : "0" + h;
m = m >= 10 ? m : "0" + m;
s = s >= 10 ? s : "0" + s;
return h + ":" + m + ":" + s;
function getQueryString(name) {
var reg = new RegExp('(^|&)' + name + '=([^&]*)(&|$)', 'i');
var r = window.location.search.substr(1).match(reg);
if (r != null) {
return unescape(r[2]);
return '';
</script>
</body>
</html>
View Code
移动端 video/audio播放实现(功能实现,后边总结适配)
已完成: 播放/暂停 、横竖切换、拖拽播放
未完成:断点续播(同理)、资源上下切换(同理) 、
>横竖屏切换
ps:可以旋转某个Dom元素
// horizontalScreen('body');
function horizontalScreen(className) {
// transform 强制横屏
var conW = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
var conH = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
$(className).css({
"transform": "rotate(90deg) translate(" + ((conH - conW) / 2) + "px," + ((conH - conW) / 2) + "px)",
"width": conH + "px",
"height": conW + "px",
"transform-origin": "center center",
"-webkit-transform-origin": "center center"
>横竖屏 、拽进度条 由于(坐标方向不通做相应处理clientX \ clientY)
if(isFullScreen){
eventXY = event.clientY;
}else{
eventXY = event.clientX;
barleft = eventXY - leftVal;
示例展示:
###竖屏###
###横屏###
>暂停状态时,切换横竖屏进度条异常;
如图:竖屏正常
横屏情况下:
时间区域进度条位置不正确;
原因:暂停状态没有重新计算宽及进度
timeupdateFun 函数,导致切换时长度没有计算
function timeupdateFun(e) {
origCurrentTime = e.target.currentTime;
origDuration = e.target.duration;
var percent = origCurrentTime / origDuration * 100;
// console.log(percent)
timeBar.style.width = percent + "%";
// 时间滚动区域
var _timeBoxWidth = scroll.offsetWidth - showTimeBox.offsetWidth;
var x = origCurrentTime * _timeBoxWidth / origDuration;
// 时间进度条
showTimeBox.style.left = x + 'px';
curTime.innerHTML = getTimeStr(origCurrentTime);
<!DOCTYPE html>
<html lang="en">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<script src="jquery-2.1.4.min.js"></script>
<title>移动端Video</title>
<style>
margin: 0;
padding: 0;
#video {
object-fit: fill;
.video-box {
position: relative;
/* border: 1px solid red; */
/* 去掉全屏时显示的自带控制条 */
/* video::-webkit-media-controls {
display: none !important;
.control {
position: absolute;
bottom: 50px;
left: 0;
z-index: 100;
width: 100%;
/* padding-left: 20px; */
/* border: 1px solid yellow; */
.progress-box{
position: absolute;
bottom: 30px;
left: 0;
width: 100%;
.play-status {
color: red;
.upPlay,
.downPlay,
.fullscreen {
background: #000;
color: #fff;
margin: 0 5px;
cursor: pointer;
font-size: 16px;
.progress-outer {
height: 10px;
background-color: #ccc;
margin: 0 5px;
position: relative;
border-radius: 7px;
margin-top: 50px;
.progress-inner {
height: 10px;
background-color: blue;
width: 0;
border-radius: 7px 0 0 7px;
.play-status {
width: 40px;
font-size: 18px;
background-color: #333;
color: #fff;
.video-timer {
position: absolute;
background: blue;
color: #fff;
left: 0%;
width: 120px;
text-align: center;
font-size: 12px;
height: 15px;
line-height:
15px;
/* display: flex;
align-items: center;
justify-content: center; */
border-radius: 7px;
vertical-align: middle;
cursor: pointer;
top: -2px;
</style>
</head>
<div class="video-box">
<video id="video" muted src="https://video.miaocloud.net/002ef208cc2949bba4e9439f2c3ba769/be792fd5b0c245429da6ede4a704ec08-81cec51c4b0c8d5b6cb9df02d7f94b0d-sd.mp4" poster="200x200.jpg"
preload="auto" autoplay x5-video-player-type="h5-page" webkit-playsinline="true" playsinline="true"
x-webkit-airplay="true" style="width:100%;object-fit: cover;">
</video>
<div class="control">
<span class="play-status" id="playStatus">播放</span>
<span class="fullscreen" id="fullscreen">全屏</span>
</div>
<div class="progress-box">
<div class="progress-outer" id="scroll">
<div class="progress-inner" id="timeBar"></div>
<div class="video-timer" id="showTimeBox">
<span id="currentTime">00:00:00</span><em>/</em>
<span id="duration">00:00:00</span>
</div>
</div>
</div>
</div>
这里是简单的文字描述
</div>
<script>
var isFullScreen = false;
// ***以下如需要自行封装***
var videoObj = document.querySelector('video');
videoObj.addEventListener('timeupdate', timeupdateFun);
videoObj.addEventListener('canplay', canplayFun);
var origCurrentTime = 0;
var origDuration = 0;
var playStatus = document.getElementById('playStatus');
// 播放当前时间
var curTime = document.getElementById("currentTime");
// 播放总时长
var duration = document.getElementById("duration");
// 进度条移动距离 --inner
var timeBar = document.getElementById("timeBar");
// 进度条总宽度 --outer
var scroll = document.getElementById('scroll');
// 播放时间展示区域
var showTimeBox = document.getElementById('showTimeBox');
var times = 0;
//距离左边距离
var barleft =
0;
document.addEventListener("touchmove", function (e) {
e.preventDefault();
passive: false
showTimeBox.ontouchstart = function (event) {
var event = event.touches[0];
var eventXY = 0;
// 距离左边距离(起始位置)
// 横竖屏拖拽 X与Y坐标方向相反
if(isFullScreen){
eventXY = event.clientY;
}else{
eventXY = event.clientX;
var leftVal = eventXY - this.offsetLeft;
showTimeBox.ontouchmove = function (event) {
var event = event.touches[0];
var eventXY = 0;
if(isFullScreen){
eventXY = event.clientY;
}else{
eventXY = event.clientX;
barleft = eventXY - leftVal;
if (barleft <= 0) {
barleft = 0;
} else if (barleft >= scroll.offsetWidth - showTimeBox.offsetWidth) {
barleft = scroll.offsetWidth - showTimeBox.offsetWidth;
console.log(barleft)
// 进度条
var _x = barleft * 100 / (scroll.offsetWidth - showTimeBox.offsetWidth);
timeBar.style.width = _x + "%";
// 时间展示区域
showTimeBox.style.left = barleft + 'px';
// 拖拽计算播放-- 根据拖拽计算播放进度
//时间拖拽计算
var updateTime = (times * _x) / 100;
videoObj.currentTime = updateTime;
videoObj.play();
// 时间进度条
curTime.innerHTML = getTimeStr(updateTime);
//防止选择内容--当拖动鼠标过快时候,弹起鼠标,bar也会移动,修复bug
window.getSelection ? window.getSelection().removeAllRanges() : document.selection.empty();
document.onmouseup = function () {
document.onmousemove = null; //弹起鼠标不做任何操作
playStatus.onclick = function () {
if (videoObj.paused || videoObj.ended) {
//播放
videoObj.play();
playStatus.innerText = '暂停';
} else {
//暂停
videoObj.pause();
playStatus.innerText = '播放';
function timeupdateFun(e) {
origCurrentTime = e.target.currentTime;
origDuration = e.target.duration;
var percent = origCurrentTime / origDuration * 100;
// console.log(percent)
timeBar.style.width
= percent + "%";
// 时间滚动区域
var _timeBoxWidth = scroll.offsetWidth - showTimeBox.offsetWidth;
var x = origCurrentTime * _timeBoxWidth / origDuration;
// 时间进度条
showTimeBox.style.left = x + 'px';
curTime.innerHTML = getTimeStr(origCurrentTime);
// 切换横竖
function zoomChange(){
var percent = origCurrentTime / origDuration * 100;
// console.log(percent)
timeBar.style.width = percent + "%";
// 时间滚动区域
var _timeBoxWidth = scroll.offsetWidth - showTimeBox.offsetWidth;
var x = origCurrentTime * _timeBoxWidth / origDuration;
// 时间进度条
showTimeBox.style.left = x + 'px';
//是否能播放
function canplayFun(e) {
times = e.target.duration;
// duration = times;
drag = true;
//总时长
duration.innerHTML = getTimeStr(times);
fullscreen.onclick = function(){
if(isFullScreen){
$('.video-box').removeAttr('style');
}else{
horizontalScreen('.video-box');
isFullScreen = !isFullScreen;
// 重新计算进度,避免暂停切换横竖导致进度条位置不准确
zoomChange();
function horizontalScreen(className) {
// transform 强制横屏
var conW = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth;
var conH = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
$(className).css({
"transform": "rotate(90deg) translate(" + ((conH - conW) / 2) + "px," + ((conH - conW) / 2) + "px)",
"width": conH + "px",
"height": conW + "px",
"transform-origin": "center center",
"-webkit-transform-origin": "center center"
//将以秒为单位的时间变成“00:00:00”格式的字符串
function getTimeStr(time) {
var h = Math.floor(time / 3600);
var m = Math.floor(time % 3600 / 60);
var s = Math.floor(time % 60);
h = h >= 10 ? h : "0" + h;
m = m >= 10 ? m : "0" + m;
s = s >= 10 ? s : "0" + s;
return h + ":" + m + ":" + s;
</script>
</body>
</html>
View Code
>问题汇总:
1、 video 标签 post无法适应video大小问题
### object-fit:fill \ cover;
2、苹果默认播放
### muted属性 静音情况是可以播放(利弊需要衡量)