mirror of
https://codeup.aliyun.com/67762337eccfc218f6110e0e/vue/learning-system-mobile.git
synced 2025-12-10 19:36:47 +08:00
视频组件
This commit is contained in:
BIN
components/video-player/images/back.png
Normal file
BIN
components/video-player/images/back.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 537 B |
BIN
components/video-player/images/full.png
Normal file
BIN
components/video-player/images/full.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 518 B |
BIN
components/video-player/images/pause.png
Normal file
BIN
components/video-player/images/pause.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 385 B |
BIN
components/video-player/images/play.png
Normal file
BIN
components/video-player/images/play.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 532 B |
@@ -1,29 +1,58 @@
|
|||||||
<template>
|
<template>
|
||||||
<video id="myVideo" style="width: 100%;"
|
<view class="video-box" @click="clickVideo" @dblclick="dbclickVideo">
|
||||||
:src="url"
|
<video id="myVideo" style="width: 100%;"
|
||||||
@error="videoErrorCallback"
|
:src="url"
|
||||||
:initial-time="videoPlayingTime"
|
:controls="false"
|
||||||
@play="onPlayerPlay"
|
@error="videoErrorCallback"
|
||||||
@pause="onPlayerPause"
|
:initial-time="videoPlayingTime"
|
||||||
@ended="onPlayerEnded"
|
@play="onPlayerPlay"
|
||||||
@timeupdate="onPlayerPlaying"
|
@pause="onPlayerPause"
|
||||||
@fullscreenchange="onFullScreen"
|
@ended="onPlayerEnded"
|
||||||
controls>
|
@timeupdate="onPlayerPlaying"
|
||||||
<view class='process-container'>
|
@fullscreenchange="onFullScreen"
|
||||||
<view class="video-controls-play">
|
@loadeddata="onPalyerLoad"
|
||||||
<image :src="palyFlag ? '../../static/img/start.png' : '../../static/img/pause.png'" class='video-controls-icon' @click='videoOpreation'/>
|
@loadedmetadata="onPlayerMetaLoad"
|
||||||
|
@controlstoggle="onPlayerControlsToggle"
|
||||||
|
@dblclick="dbclickVideo"
|
||||||
|
>
|
||||||
|
</video>
|
||||||
|
<view v-if="contrlShow">
|
||||||
|
<view class="process-container">
|
||||||
|
<view class="controller-play">
|
||||||
|
<image :src="require(playing? './images/pause.png':'./images/play.png')" @click='videoOpreation'/>
|
||||||
|
</view>
|
||||||
|
<view class="currtime">{{currtime}}</view>
|
||||||
|
<view class='slider-container'>
|
||||||
|
<slider @change="sliderChange" @changing="sliderChanging" step="1" :value="sliderValue" backgroundColor="#9f9587" activeColor="#d6d2cc" block-color="#FFFFFF" block-size="12"/>
|
||||||
|
</view>
|
||||||
|
<view class="druationTime">{{druationTime}}</view>
|
||||||
|
<view class="druationTime">
|
||||||
|
<view id="myVideoSpeed" class="player-speed btn-speed">
|
||||||
|
<view @click="showSpeedCtrl">{{videoSpeed === 1 ? '倍速' : `${videoSpeed}x`}}</view>
|
||||||
|
<view class="speed-control" v-if="speedListShow">
|
||||||
|
<view class="speed-control-list">
|
||||||
|
<view class="li"
|
||||||
|
v-for="item in speedList"
|
||||||
|
:key="item"
|
||||||
|
@click="changeSpeed(item)"
|
||||||
|
:data-value="item"
|
||||||
|
:class="{'current': videoSpeed === Number(item)}">
|
||||||
|
{{ item }}x
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="controller-screen">
|
||||||
|
<image :src="require(fullScreenFlag? './images/back.png':'./images/full.png')" @click='fullScreen'/>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="currtime">{{currtime}}</view>
|
|
||||||
<view class='slider-container'>
|
|
||||||
<slider @change="sliderChange" @changing="sliderChanging" step="1" :value="sliderValue" backgroundColor="#9f9587" activeColor="#d6d2cc" block-color="#FFFFFF" block-size="16rpx"/>
|
|
||||||
</view>
|
|
||||||
<view class="druationTime">{{druationTime}}</view>
|
|
||||||
<image :src="fullScreenFlag ? '../../static/img/videoBack.png' : '../../static/img/fullScreen.png'" class='video-controls-icon' @click='videoAllscreen'></image>
|
|
||||||
</view>
|
</view>
|
||||||
</video>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import {mapGetters} from 'vuex'
|
||||||
|
import studyUtil from '@/utils/study.js';
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
url:{
|
url:{
|
||||||
@@ -37,28 +66,48 @@
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fullScreenFlag: false,
|
contrlShow:true,//是否显示进度条
|
||||||
currtime:'00:00:00',//当前播放时间 字符串 计算后
|
contrlShowTimeout:null,//显示控制条句柄
|
||||||
druationTime:'00:00:00',//总时间 字符串 计算后
|
videoContext:null,//播放器
|
||||||
videoPlayingTime:0,
|
fullScreenFlag: false,//是否全屏
|
||||||
bool:false,
|
currtime:'00:00',//当前播放时间 字符串 计算后
|
||||||
|
druationTime:'00:00',//总时间 字符串 计算后
|
||||||
|
videoPlayingTime:0,//指定播放的时间位置
|
||||||
sliderValue: 0, //控制进度条slider的值,
|
sliderValue: 0, //控制进度条slider的值,
|
||||||
updateState: false, //防止视频播放过程中导致的拖拽失效
|
updateState: false, //防止视频播放过程中导致的拖拽失效
|
||||||
palyFlag:false,
|
playing:false,//是否在播放中
|
||||||
|
curVideo:{
|
||||||
|
duration:0
|
||||||
|
},
|
||||||
|
speedListShow:false,
|
||||||
|
speedList:["2.0", "1.5", "1.25", "1.0", "0.75", "0.5"],
|
||||||
|
videoSpeed: 1.0, // 当前倍速:
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters(['userInfo']),
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.videoContext=uni.createVideoContext("myVideo", this);
|
||||||
|
|
||||||
|
},
|
||||||
methods: {
|
methods: {
|
||||||
// video_back: function (e) {
|
|
||||||
// this.fullScreenFlag ? this.videoContext.requestFullScreen() : this.videoContext.exitFullScreen();
|
|
||||||
// // this.fullScreenFlag ? this.bool=false : this.bool=true;
|
|
||||||
// this.fullScreenFlag= !this.fullScreenFlag;
|
|
||||||
// },
|
|
||||||
// 全屏+退出全屏
|
// 全屏+退出全屏
|
||||||
videoAllscreen(e) {
|
fullScreen(){
|
||||||
|
this.fullScreenFlag ? this.videoContext.exitFullScreen() : this.videoContext.requestFullScreen();
|
||||||
|
// this.fullScreenFlag ? this.bool=true : this.bool=false;
|
||||||
|
this.fullScreenFlag=!this.fullScreenFlag;
|
||||||
|
},
|
||||||
|
onFullScreen(e) {
|
||||||
this.fullScreenFlag ? this.videoContext.exitFullScreen() : this.videoContext.requestFullScreen();
|
this.fullScreenFlag ? this.videoContext.exitFullScreen() : this.videoContext.requestFullScreen();
|
||||||
// this.fullScreenFlag ? this.bool=true : this.bool=false;
|
// this.fullScreenFlag ? this.bool=true : this.bool=false;
|
||||||
this.fullScreenFlag=!this.fullScreenFlag;
|
this.fullScreenFlag=!this.fullScreenFlag;
|
||||||
},
|
},
|
||||||
|
|
||||||
videoErrorCallback(e){
|
videoErrorCallback(e){
|
||||||
console.log(e,'播放错误');
|
console.log(e,'播放错误');
|
||||||
},
|
},
|
||||||
@@ -77,14 +126,29 @@
|
|||||||
return "00:00";
|
return "00:00";
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
changeSpeed(e) {
|
||||||
|
// 获取选择的倍速
|
||||||
|
let value = e;
|
||||||
|
this.videoSpeed = Number(value);
|
||||||
|
this.videoContext.playbackRate(this.videoSpeed);
|
||||||
|
studyUtil.setVideoSpeed(this.videoSpeed);
|
||||||
|
this.speedListShow=false;
|
||||||
|
},
|
||||||
|
showSpeedCtrl(){
|
||||||
|
if(this.speedListShow){
|
||||||
|
this.speedListShow=false;
|
||||||
|
}else{
|
||||||
|
this.speedListShow=true;
|
||||||
|
}
|
||||||
|
},
|
||||||
//开始+暂停
|
//开始+暂停
|
||||||
videoOpreation() {
|
videoOpreation() {
|
||||||
this.palyFlag ? this.videoContext.play() : this.videoContext.pause();
|
this.playing ? this.videoContext.pause() : this.videoContext.play();
|
||||||
this.palyFlag= !this.palyFlag;
|
this.playing= !this.playing;
|
||||||
},
|
},
|
||||||
// 播放进度变化时触发,event.detail = {currentTime, duration} 。触发频率 250ms 一次
|
// 播放进度变化时触发,event.detail = {currentTime, duration} 。触发频率 250ms 一次
|
||||||
videoUpdate(e) {
|
videoUpdate(e) {
|
||||||
let duration=this.live.liveRoomRecordList[0].duration;
|
let duration=this.curVideo.duration;
|
||||||
let sliderValue = e.detail.currentTime / duration * 100;
|
let sliderValue = e.detail.currentTime / duration * 100;
|
||||||
let second=sliderValue / 100 * duration;
|
let second=sliderValue / 100 * duration;
|
||||||
if (this.updateState) { //判断拖拽完成后才触发更新,避免拖拽失效
|
if (this.updateState) { //判断拖拽完成后才触发更新,避免拖拽失效
|
||||||
@@ -92,8 +156,9 @@
|
|||||||
}else{
|
}else{
|
||||||
|
|
||||||
}
|
}
|
||||||
this.druationTime = this.formatSeconds(duration);
|
this.druationTime = this.formatSeconds(duration);
|
||||||
this.currtime = this.formatSeconds(second);
|
//console.log(this.druationTime,'this.druationTime');
|
||||||
|
this.currtime = this.formatSeconds(second);
|
||||||
},
|
},
|
||||||
//拖动过程中触发的事件
|
//拖动过程中触发的事件
|
||||||
sliderChanging(e) {
|
sliderChanging(e) {
|
||||||
@@ -102,7 +167,7 @@
|
|||||||
},
|
},
|
||||||
// 拖动slider完成后触发
|
// 拖动slider完成后触发
|
||||||
sliderChange(e) {
|
sliderChange(e) {
|
||||||
var duration=this.live.liveRoomRecordList[0].duration;
|
var duration=this.curVideo.duration;
|
||||||
var second=e.detail.value / 100 * duration;
|
var second=e.detail.value / 100 * duration;
|
||||||
if (duration) { //完成拖动后,计算对应时间并跳转到指定位置
|
if (duration) { //完成拖动后,计算对应时间并跳转到指定位置
|
||||||
this.videoContext.seek(second);
|
this.videoContext.seek(second);
|
||||||
@@ -113,54 +178,93 @@
|
|||||||
}
|
}
|
||||||
else { }
|
else { }
|
||||||
},
|
},
|
||||||
|
clickVideo(){
|
||||||
|
// if(this.contrlShowTimeout!=null){
|
||||||
|
// window.clearTimeout(this.contrlShowTimeout);
|
||||||
|
// }
|
||||||
|
// this.contrlShow=!this.contrlShow;
|
||||||
|
},
|
||||||
|
dblclickVideo(){
|
||||||
|
console.log("双击了");
|
||||||
|
},
|
||||||
|
onPlayerLoad(e){
|
||||||
|
this.contrlShow=false;
|
||||||
|
},
|
||||||
|
onPlayerMetaLoad(e){
|
||||||
|
this.curVideo.duration=Number(e.detail.duration);
|
||||||
|
this.druationTime = this.formatSeconds(this.curVideo.duration);
|
||||||
|
},
|
||||||
|
onPlayerControlsToggle(e){
|
||||||
|
console.log(e,"ControlsToggle");
|
||||||
|
},
|
||||||
// 开始
|
// 开始
|
||||||
contrPlay(){
|
onPlayerPlay(){
|
||||||
this.videoContext.play();
|
this.videoContext.play();
|
||||||
this.palyFlag=false;
|
this.playing=true;
|
||||||
|
this.contrlShow=true;
|
||||||
|
},
|
||||||
|
onPlayerPlaying(e){
|
||||||
|
this.playing=true;
|
||||||
|
this.updateState=true;
|
||||||
|
this.videoUpdate(e);
|
||||||
|
// let $this=this;
|
||||||
|
// if(this.contrlShow){
|
||||||
|
// this.contrlShowTimeout=window.setTimeout(function(){
|
||||||
|
// $this.contrlShow=false;
|
||||||
|
// },5000);
|
||||||
|
// }
|
||||||
},
|
},
|
||||||
// 暂停
|
// 暂停
|
||||||
pause() {
|
onPlayerPause() {
|
||||||
this.videoContext.pause(); //站厅播放
|
this.videoContext.pause(); //站厅播放
|
||||||
this.palyFlag=true;
|
this.playing=false;
|
||||||
},
|
},
|
||||||
stop(){
|
onPlayerEnded(){
|
||||||
this.videoContext.stop(); //
|
this.playing=false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.process-container{
|
.video-box{
|
||||||
width:100%;
|
width: 100%;
|
||||||
padding:1% 2% 1% 2%;
|
height: 100%;
|
||||||
height:60rpx;
|
position: relative;
|
||||||
max-height:60rpx;
|
}
|
||||||
position:absolute;
|
.process-container{
|
||||||
bottom:40rpx;
|
width:100%;
|
||||||
left:0;
|
padding:1% 2% 1% 2%;
|
||||||
right:0;
|
height:60rpx;
|
||||||
z-index:13;
|
max-height:60rpx;
|
||||||
display:flex;
|
position:absolute;
|
||||||
align-items: center;
|
bottom:0rpx;
|
||||||
background:rgba(59, 57, 57, 0.2);
|
color:#ffffff;
|
||||||
|
left:0;
|
||||||
|
right:0;
|
||||||
|
z-index:99;
|
||||||
|
display:flex;
|
||||||
|
align-items: center;
|
||||||
|
background:rgba(59, 57, 57, 0.2);
|
||||||
}
|
}
|
||||||
.process-container image{
|
.process-container image{
|
||||||
display:inline-block;
|
display:inline-block;
|
||||||
flex:1;
|
max-width:30rpx;
|
||||||
max-width:50rpx;
|
max-height:30rpx;
|
||||||
max-height:50rpx;
|
text-align:center;
|
||||||
text-align:center;
|
|
||||||
}
|
}
|
||||||
.slider-container{
|
.slider-container{
|
||||||
z-index:13;
|
z-index:13;
|
||||||
height:60rpx;
|
height:60rpx;
|
||||||
margin-bottom:10rpx;
|
margin-bottom:10rpx;
|
||||||
flex:6;
|
flex:6;
|
||||||
max-width:58%;
|
max-width:40%;
|
||||||
}
|
}
|
||||||
.video-controls-play{
|
.controller-play{
|
||||||
width: 8%;
|
width: 12%;
|
||||||
|
}
|
||||||
|
.controller-screen{
|
||||||
|
|
||||||
}
|
}
|
||||||
.currtime{
|
.currtime{
|
||||||
color: #ffffff;
|
color: #ffffff;
|
||||||
@@ -192,4 +296,46 @@
|
|||||||
width:44rpx;
|
width:44rpx;
|
||||||
height:44rpx;
|
height:44rpx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.player-speed{
|
||||||
|
position: relative;
|
||||||
|
color: #e5e5e5;
|
||||||
|
padding: 0 0.4rem;
|
||||||
|
transition: color 0.3s;
|
||||||
|
height: 22px;
|
||||||
|
}
|
||||||
|
.btn-speed:hover .speed-control {
|
||||||
|
// visibility: visible;
|
||||||
|
}
|
||||||
|
.speed-control {
|
||||||
|
position: absolute;
|
||||||
|
//top: 180px;
|
||||||
|
transition: visibility 0.3s;
|
||||||
|
transform: translate(-50%, -100%);
|
||||||
|
}
|
||||||
|
.speed-control .speed-control-list {
|
||||||
|
list-style: none;
|
||||||
|
color: #e5e5e5;
|
||||||
|
width: 50px;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: left;
|
||||||
|
padding: 0px 0px 0px 5px;
|
||||||
|
margin: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 4px;
|
||||||
|
background: rgba(21, 21, 21, 0.8);
|
||||||
|
}
|
||||||
|
.speed-control .speed-control-list .li {
|
||||||
|
position: relative;
|
||||||
|
display: block;
|
||||||
|
height: 25px;
|
||||||
|
line-height: 25px;
|
||||||
|
}
|
||||||
|
.speed-control .speed-control-list .li:hover {
|
||||||
|
color: #fff;
|
||||||
|
background: rgba(99, 99, 99, 0.8);
|
||||||
|
}
|
||||||
|
.speed-control .speed-control-list .li.current {
|
||||||
|
color: var(--primaryColor);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
export default{
|
export default{
|
||||||
data(){
|
data(){
|
||||||
return {
|
return {
|
||||||
fileUrl:'http:/127.0.0.1:9090/cdn/upload/course/2022/8/1013883711839379456.mp4',
|
fileUrl:'/static/temp/test.mp4',
|
||||||
title:'测试播放',
|
title:'测试播放',
|
||||||
author:'',
|
author:'',
|
||||||
}
|
}
|
||||||
@@ -41,16 +41,16 @@
|
|||||||
this.author='作者信息';
|
this.author='作者信息';
|
||||||
},
|
},
|
||||||
videoPlay(){
|
videoPlay(){
|
||||||
console.log('audioPlay');
|
console.log('videoPlay');
|
||||||
},
|
},
|
||||||
videoEnd(){
|
videoEnd(){
|
||||||
console.log('audioEnd');
|
console.log('videoEnd');
|
||||||
},
|
},
|
||||||
videoPause(){
|
videoPause(){
|
||||||
console.log('audioPause');
|
console.log('videoPause');
|
||||||
},
|
},
|
||||||
videoPlaying(){
|
videoPlaying(){
|
||||||
console.log('audioPlaying');
|
console.log('videoPlaying');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user