视频组件

This commit is contained in:
daihh
2022-11-17 19:51:36 +08:00
parent 1d1d4d1832
commit 7297d37a25
6 changed files with 217 additions and 71 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 537 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 518 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 532 B

View File

@@ -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>

View File

@@ -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');
} }
} }
} }