视频页面
2021-04-13 本文已影响0人
Shiki_思清
一、自定义视频操作按钮
由于原video组件不方便操作,所以果断放弃
使用自定义页面组件配合js操作video,同时使用 requestFullscreen和exitFullscreen配合放大缩小。
1. 重写最大化 最大化父节点
<div class="video-player" id="myvideo">
<video></video>
<div>
// 播放/暂停
// 进度条
// 最大化最小化
</div>
</div>
const myvideo = document.getElementById("myvideo");
// 判断是否最大化
if (isFullScreen) {
if (document.exitFullscreen) {
document.exitFullscreen();
} else if (document.msExitFullscreen) {
document.msExitFullscreen();
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen();
} else if (document.webkitCancelFullScreen) {
document.webkitCancelFullScreen();
}
} else {
if (myvideo.requestFullscreen) {
myvideo.requestFullscreen();
} else if (myvideo.mozRequestFullScreen) {
myvideo.mozRequestFullScreen();
} else if (myvideo.webkitRequestFullscreen) {
myvideo.webkitRequestFullscreen();
} else if (myvideo.msRequestFullscreen) {
myvideo.msRequestFullscreen();
}
}
}
2. 重写播放和滚动条
<div class="video-player-container">
<video
ref="videoPlayer"
class="video-player"
width="100%"
:src="videoObj.video_info && videoObj.video_info.play_url_fd"
@pause="() => handPlay('pause')"
@play="() => handPlay('play')"
@loadedmetadata="getAudioLength"
@timeupdate="videoTimeUpdate"
@click="playVideo"
/>
<div class="video_control">
<div class="controler">
<img
@click="playVideo"
class="play-btn"
:src="
`https://sc2.hexiaoxiang.com/write-artifact/hx_dxb_website/video-player/${
initVideo.play ? 'pause1.png' : 'play1.png'
}`
"
alt=""
/>
<div class="time">
<!-- //videoLength 总时间,currentTime 当前时间,videoTime 自定义过滤器 -->
<span>{{ getFormatVideoTime(initVideo.currentTime) }}</span>
/
<span>{{ getFormatVideoTime(initVideo.videoLength) }}</span>
</div>
<img
@click="setWidth"
class="screen-btn"
:src="
`https://sc2.hexiaoxiang.com/write-artifact/hx_dxb_website/video-player/${
isFullScreen ? 'exitFullScreen.png' : 'fullScreen.png'
}`
"
alt=""
/>
</div>
<!-- //进度条 -->
<a-slider
class="commonSlider"
:tooltip-visible="false"
v-model="initVideo.currentTime"
:max="initVideo.videoLength"
@change="changeVideoTime"
>
</a-slider>
</div>
<div class="auto-play">
<a-switch @change="handleAutoplay" v-model="isAutoPlay" />
<a-tooltip
placement="bottomRight"
:arrowPointAtCenter="true"
overlayClassName="overrideClass"
>
<template slot="title">
<span>开启后自动播放下一个视频,播放完本课自动播放下一课</span>
</template>
<div>{{ isAutoPlay ? "关闭自动播放" : "打开自动播放" }}</div>
</a-tooltip>
</div>
</div>
data() {
return {
player: {},
isAutoPlay: false,
initVideo: {
play: false, //播放还是暂停 true播放中
videoLength: 0, //时长
url: "", //视频课件Url
currentTime: 0, //当前播放时间
lastTime: null, //标记时间戳
name: ""
},
isFullScreen: false
};
},
watch: {
videoObj() {
this.handPlay("pause");
this.initVideo = {
play: false, //播放还是暂停 true播放中
videoLength: 0, //时长
url: "", //视频课件Url
currentTime: 0, //当前播放时间
lastTime: null, //标记时间戳
name: ""
};
},
isAutoPlay(newV, oldV) {
if (newV != oldV) {
this.$emit("is-auto-play", newV);
}
}
},
mounted() {
this.$nextTick(function() {
this.player = this.$refs.videoPlayer;
this.player.onended = this.onended;
this.player.onerror = this.onerror;
});
},
methods: {
setWidth() {
this.$emit("set-width", this.isFullScreen);
setTimeout(() => {
this.isFullScreen = !this.isFullScreen;
}, 100);
},
playVideo() {
//播放视频
if (this.initVideo.play) {
this.player.pause();
} else {
Math.abs(this.initVideo.currentTime - this.player.currentTime) > 2
? (this.player.currentTime = this.initVideo.currentTime)
: "";
this.player.play();
this.player.muted = false;
}
},
videoTimeUpdate() {
//更新视频时间。节流,每秒触发一次
let nowTime = Date.now();
let gapTime = 1000;
if (
!this.initVideo.lastTime ||
nowTime - this.initVideo.lastTime > gapTime
) {
if (this.player) {
let time = this.player.currentTime;
this.initVideo.currentTime = time;
}
this.initVideo.lastTime = nowTime;
}
},
changeVideoTime(val) {
//改变视频时间
if (this.player) {
this.player.currentTime = val;
}
},
getAudioLength() {
//获取音视频时长
this.initVideo.videoLength = this.player.duration;
},
handPlay(type) {
this.initVideo.play = type == "play";
},
//格式化时间
getFormatVideoTime(time) {
let curtime = time;
let h = parseInt(curtime / 3600);
let m = parseInt((curtime % 3600) / 60);
let s = parseInt(curtime % 60);
h = h < 10 ? "0" + h : h;
m = m < 10 ? "0" + m : m;
s = s < 10 ? "0" + s : s;
if (h == "00") {
return m + ":" + s;
}
return h + ":" + m + ":" + s;
},
// 播放错误
onerror() {
console.log("error");
this.$message.error("视频资源无法播放~");
},
onended() {
this.$emit("file-ended");
// this.handPlay("pause");
// this.player.load();
// this.playVideo();
},
handleAutoplay() {
this.player.autoplay = !this.player.autoplay;
// this.player.load();
}
}
3. 动态调整视频大小
<template>
<div class="carousel"><video></video></div>
</template>
<style lang="scss" scoped>
.carousel {
@media screen and (max-width: 1239px) {
max-width: 824px;
}
@media screen and (min-width: 1240px) and (max-width: 1329px) {
max-width: 854px;
}
@media screen and (min-width: 1330px) and (max-width: 1592px) {
max-width: 924px;
}
@media screen and (min-width: 1593px) and (max-width: 1789px) {
max-width: 1046px;
}
@media screen and (min-width: 1790px) {
max-width: 1128px;
}
}
</style>
image.png
二、拖拽滚动
image.png1.通过点击滚动
2.鼠标滚球滚动
3.鼠标点击拖动
<div class="carousel">
<div class="carousel-left">
<div @click="carouselLeftEnd ? null : offset('left')">
<img
:src="
`https://sc2.hexiaoxiang.com/write-artifact/hx_dxb_website/video-player/${
carouselLeftEnd ? 'arrow-left.png' : 'arrow-left-active.png'
}`
"
alt=""
/>
</div>
</div>
<div class="carousel-content" ref="ref" draggable="true">
<div
v-for="(item, index) in fontList"
:key="index"
@click="() => $emit('change', { ...item, index })"
>
<RectFont
:fontText="item.module_title"
:active="currentIndex == index"
/>
</div>
</div>
<div class="carousel-right">
<div @click="carouselRightEnd ? null : offset('right')">
<img
:src="
`https://sc2.hexiaoxiang.com/write-artifact/hx_dxb_website/video-player/${
carouselRightEnd ? 'arrow-right.png' : 'arrow-right-active.png'
}`
"
alt=""
/>
</div>
</div>
</div>
props: {
fontList: {
type: Array,
default: () => []
},
currentIndex: {
type: Number,
default: 0
}
},
data() {
return {
currentPosition: 0,
carouselLeftEnd: true,
carouselRightEnd: false
};
},
watch: {
fontList: {
handler: function(newValue, oldValue) {
if (!newValue) {
return;
}
if (JSON.stringify(newValue) != JSON.stringify(oldValue)) {
this.$refs.ref && this.$refs.ref.scrollTo(0, 0);
}
},
immediate: true
}
},
mounted() {
if (this.$refs.ref) {
const el = this.$refs.ref;
const that = this;
// 2.鼠标滚球滚动
el.onscroll = function() {
that.currentPosition = el.scrollLeft;
that.changeBtnStatus(el.scrollWidth - el.offsetWidth);
};
// 3.鼠标点击拖动
el.onmousedown = function(ev) {
const disX = ev.clientX;
const originalScrollLeft = el.scrollLeft;
const originalScrollBehavior = el.style.scrollBehavior;
const originalPointerEvents = el.style.pointerEvents;
el.style.scrollBehavior = "auto";
document.onmousemove = function(ev) {
ev.preventDefault();
const distanceX = ev.clientX - disX;
el.scrollTo(originalScrollLeft - distanceX, 0);
el.style.pointerEvents = "none";
that.currentPosition = el.scrollLeft;
that.changeBtnStatus(el.scrollWidth - el.offsetWidth);
};
document.onmouseup = function() {
document.onmousemove = null;
document.onmouseup = null;
el.style.scrollBehavior = originalScrollBehavior;
el.style.pointerEvents = originalPointerEvents;
};
};
}
},
methods: {
getScrollPosition(el = window) {
const x = el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft;
const y = el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop;
return { x, y };
},
// 1.通过点击滚动
offset(direction) {
const typemap = {
left: -360,
right: 360
};
const currentScrollWidth =
this.$refs.ref.scrollWidth - this.$refs.ref.offsetWidth;
this.currentPosition =
this.currentPosition + typemap[direction] >= 0
? this.currentPosition + typemap[direction] >= currentScrollWidth
? currentScrollWidth
: this.currentPosition + typemap[direction]
: 0;
this.$refs.ref.scrollTo(this.currentPosition, 0);
this.changeBtnStatus(currentScrollWidth);
},
changeBtnStatus(currentScrollWidth) {
const cuurenScrollPos = this.getScrollPosition(this.$refs.ref);
this.carouselLeftEnd = cuurenScrollPos.x == 0;
this.carouselRightEnd = cuurenScrollPos.x == currentScrollWidth;
}
}