HTML 标签
您的浏览器不支持 video 标签。
提示和注释
提示:可以在开始标签和结束标签之间放置文本内容,这样老的浏览器就可以显示出不支持该标签的信息。
![](https://img2020.cnblogs.com/blog/731220/202008/731220-20200807104032379-1474386364.png)
当 video 标签添加上 controls 属性时,页面上会显示出所有的控制组件。若有些组件不需要只需要在css中设置相关属性把它隐藏掉即可。
//全屏按钮
video::-webkit-media-controls-fullscreen-button {
display: none;
}
//播放按钮
video::-webkit-media-controls-play-button {
display: none;
}
//进度条
video::-webkit-media-controls-timeline {
display: none;
}
//观看的当前时间
video::-webkit-media-controls-current-time-display{
display: none;
}
//剩余时间
video::-webkit-media-controls-time-remaining-display {
display: none;
}
//音量按钮
video::-webkit-media-controls-mute-button {
display: none;
}
video::-webkit-media-controls-toggle-closed-captions-button {
display: none;
}
//音量的控制条
video::-webkit-media-controls-volume-slider {
display: none;
}
//所有控件
video::-webkit-media-controls-enclosure{
display: none;
}
常用的一些 video API
"视频播放":video.play();
"视频暂停播放":video.pause();
"视频地址":video.currentSrc;
"视频总时长":video.duration;
"视频播放速率":video.playbackRate;
"是否暂停":video.paused;
"是否结束":video.ended;
"是否静音":video.muted;
"当前播放时间": video.currentTime;
"当前缓冲量":video.buffered.end(0);
"当前音量":video.volume
obj.clientWidth //获取元素的宽度
obj.clientHeight //元素的高度
obj.offsetLeft //元素相对于父元素的left
obj.offsetTop //元素相对于父元素的top
如果有 position: relative 那么父元素指向的当前
obj.offsetWidth //元素的宽度
obj.offsetHeight //元素的高度
示例效果(PC端)
![](https://img2020.cnblogs.com/blog/731220/202008/731220-20200814181918244-329987220.png)
已完成:暂停/播放、可拖拽播放 、上一个、下一个、全屏事件、断点续播;
未完成: 音量
↓↓↓↓↓↓ 完善断点续播↓↓↓↓↓↓
![](https://img2020.cnblogs.com/blog/731220/202008/731220-20200817094744593-2096134974.png)
>播放资源列表
// 资源列表
var resourceList = [{
resId: 1, //资源id
url: 'http://nettuts.s3.amazonaws.com/763_sammyJSIntro/trailer_test.mp4'
},
{
resId: 2,
url: '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 = 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;
}
}
}
// ###播放指定资源及断点续播###
全部代码示例
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
Document
* {
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;
}
播放
上一个
下一个
全屏
00:00/
00:00
// ***以下如需要自行封装***
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 - 1) {
alert('最后一个资源')
return;
}
curPlayIdx++;
playListFun(curPlayIdx);
}
// 播放上一个资源
function playUpFun() {
if (curPlayIdx = 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 '';
}
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;
示例展示:
###竖屏###
![](https://img2020.cnblogs.com/blog/731220/202008/731220-20200819091108766-447964113.png)
###横屏###
![](https://img2020.cnblogs.com/blog/731220/202008/731220-20200819091155006-1255257078.png)
>暂停状态时,切换横竖屏进度条异常;
如图:竖屏正常
![](https://img2020.cnblogs.com/blog/731220/202008/731220-20200820132427447-1612175219.png)
横屏情况下:
![](https://img2020.cnblogs.com/blog/731220/202008/731220-20200820132514081-123254568.png)
时间区域进度条位置不正确;
原因:暂停状态没有重新计算宽及进度
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);
}
示例代码
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
DOCTYPE html>
移动端Video
* {
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;
}
播放
全屏
00:00:00/
00:00:00
这里是简单的文字描述
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 = 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;
}
View Code
>问题汇总:
1、 video 标签 post无法适应video大小问题
### object-fit:fill \ cover;
2、苹果默认播放
### muted属性 静音情况是可以播放(利弊需要衡量)
|