123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567 |
- <template>
- <view>
- <view :style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;'">
- <list @scroll="scrolls" :show-scrollbar="false" ref="listBox" :pagingEnabled="true" :scrollable="true">
- <cell v-for="(item,i) in dataList" :key="i">
- <!-- 用div把视频模组套起来 -->
- <view :style="'width: '+ windowWidth +'px; height: '+ boxStyle.height +'px;'" :ref="'item'+i"
- style="position: relative;">
- <view v-if="(k-i)<=1" style="position: relative;">
- <view class="root">
- <video :id="item._id" :loop="true" :src="item.src"
- @play="playIngs(i)" :enable-progress-gesture="false" :page-gesture="false"
- :controls="false" :http-cache="true" :show-loading="false"
- :show-fullscreen-btn="false" :show-center-play-btn="false" :style="boxStyle"
- :object-fit="object_fit" @timeupdate="timeupdate($event,i)"
- :poster="item.src+'?x-oss-process=video/snapshot,t_480,f_jpg'"></video>
- <!-- 这里是封面 -->
- <!-- <image v-if="!item.playIng" :src="item.src+'?x-oss-process=video/snapshot,t_480,f_jpg'"
- :mode="mode"
- :style="'width: '+ windowWidth +'px; height: '+ (wHeight - deleteHeight) +'px; position: absolute;'">
- </image> -->
- </view>
-
- <!-- 这个是暂停时出现的图标 -->
- <view class="videoHover" @click="tapVideoHover(item.state,$event)"
- @touchstart="touchstartHover" :style="boxStyle">
- <image v-if="item.state=='pause' && item.isShowPlayIcon" class="playState" src="/static/image/course/play.png"></image>
- </view>
-
- <!-- 这里是直播时的界面其他内容 -->
- <view class="es es-ac es-h-88 " style="right:0;position: absolute;left:20rpx;" :style="'top:'+top+'px'">
- <image class="es-w-18 es-h-31 es-mr-20 es-ml-30" @tap="navBack()" src="/static/images/other/ret-white.png"></image>
- <view class="es-brc es-h-60 es es-ac es-br" style="background-color: rgba(255,255,255,0.2);">
- <view class="es-icon-57 es-br es-oh es-bc-red es es-ac es-pc">
- <image class="es-icon-57" style="border-radius: 29rpx;" src="/static/image/mine/doctor.png"></image>
- </view>
- <view class="es-c-white es-fw-500 es-fs-28 es-ml-11 es-mr-30" style="max-width: 6em;"><text class="es-c-white es-fs-28 es-fw-500">名字</text></view>
- <image class="es-icon-27 es-mr-21" src="/static/images/other/video/add.png"></image>
- </view>
- <view class="es-w-180"></view>
- <view class="es">
- <image class="es-br es-icon-57 es-ml-10" src="/static/image/mine/doctor.png"></image>
- <image class="es-br es-icon-57 es-ml-10" src="/static/image/mine/doctor.png"></image>
- <image class="es-br es-icon-57 es-ml-10" src="/static/image/mine/doctor.png"></image>
- </view>
- </view>
- <view class="person es es-ac " style="position: absolute;right:0;" :style="'top:'+top+'px'">
- <view class="num es es-ac es-pc "><text class="es-fs-28 es-fw-500 es-c-white">188人</text></view>
- </view>
-
-
- <view class="right es-c-white">
- <view class="item1 es es-ver es-ac es-pc es-mt-33" @tap="click()">
- <view class="es-icon-94 es-br-47 x-c" style="background-color:#ec5646;">
- <image class="es-icon-42" src="/static/images/other/video/like2.png"></image>
- </view>
- <view><text class="es-c-white es-fs-22 es-fw-500 es-mt-6">16.8万</text></view>
- </view>
- <view class="item1 es es-ver es-ac es-pc es-mt-33">
- <view class="es-icon-94 es-br-47 x-c" style="background-color:#5b6cde">
- <image class="es-icon-42" src="/static/images/other/video/collect2.png"></image>
- </view>
- <view><text class="es-c-white es-fs-22 es-fw-500 es-mt-6">3.2万</text></view>
- </view>
- <view class="item1 es es-ver es-ac es-pc es-mt-33">
- <view class="es-icon-94 es-br-47 x-c" style="background-color:#faa41d">
- <image class="es-icon-42" src="/static/images/other/video/star2.png"></image>
- </view>
- <view><text class="es-c-white es-fs-22 es-fw-500 es-mt-6">1.1万</text></view>
- </view>
- <view class="item1 es es-ver es-ac es-pc es-mt-33">
- <view class="es-icon-94 es-br-47 x-c" style="background-color:rgba(66,66,66,0.5)" >
- <image class="es-icon-42 es-h-14" src="/static/images/other/video/more.png"></image>
- </view>
- <view><text class="es-c-white es-fs-22 es-fw-500 es-mt-6">1.8万</text></view>
- </view>
- </view>
-
-
- <view class="bottom" style="width: 100%;">
- <view class="es-h-74 es es-ac">
- <view class="es-br-37 es-pl-20" :style="{width:(windowWidth-90)+'px'}" style="z-index: 1;width: 300rpx;background-color:rgba(66,66,66,0.5)">
- <input class="es-c-white es-fw-500 es-fs-26 es-h-74" type="text" placeholder="说点什么..."/>
- </view>
-
- <view class="es-icon-74 es-br-37 x-c es-ml-20" style="z-index: 1;background-color:#ff5000">
- <image class="es-icon-38" src="/static/images/other/video/car2.png"></image>
- </view>
-
- <view class="es-w-30"></view>
- </view>
- </view>
-
-
- <!-- <es-living-pop></es-living-pop> -->
-
- <!-- 这里是播放视频的其他内容 -->
- <!-- <es-video-pop></es-video-pop> -->
-
-
- </view>
-
- </view>
- </cell>
- </list>
- </view>
- </view>
- </template>
- <script>
- import userList from './data.js' //这个是假数据
- export default {
- data() {
- return {
- //下面打🌟号的是必须要的基础字段
- //下面打💗号的是拥有滑动条的必须字段
- dataList: [], //用于数据循环的列表🌟💗
- wHeight: 0, //获取的屏幕高度🌟💗
- boxStyle: { //视频,图片封面样式🌟💗
- 'height': 0,
- 'width': 0,
- },
- Heights: 0,
- k: 0, //默认为0🌟💗
- playIngIds: [], //正在播放的视频id列队,列队用于处理滑动过快导致的跳频问题🌟💗
- ready: false, //可忽略
- isDragging: false, //false代表停止滑动🌟💗
- refreshing: true, //用于下拉刷新🌟💗
- windowWidth: 0, //获取屏幕宽度🌟💗
- windowHeight: 0,
- dex: [0, 0], //用于判断是上滑还是下滑,第一个存旧值,第二个存新值【目前在1.0.7已经废弃】
- currents: 0, //用于左右滑动,0代表视频界面,1代表右滑界面🌟💗
- platform: '', //用于获取操作系统:ios、android🌟💗
- playIng: false, //用于视频初始化时是否播放,默认不播放🌟💗
- videoTime: '', //视频总时长,这个主要用来截取时间数值💗
- videoTimes: '', //视频时长,用这个来获取时间值,例如:00:30这个时间值💗
- changeTime: '', //显示滑动进度条时变化的时间💗
- isShowimage: false, //是否显示封面【1.0.4已废弃,但是意思需要记住】
- currenttimes: 0, //当前时间💗
- isShowProgressBarTime: false, //是否拖动进度条,如果拖动(true)则显示进度条时间,否则不显示(false)【1.0.4已废弃,但是意思需要记住】
- ProgressBarOpacity: 0.7, //进度条不拖动时的默认值,就是透明的💗
- dotWidth: 0, //播放的小圆点,默认没有💗
- deleteHeight: 0, //测试高度🌟💗
- percent: 0, //百分小数💗
- currentPosition: 0, //滑块当前位置💗//2.0已弃用,现已用于后端参数
- currentPositions: 0, //滑块当前位置的副本💗//2.0已弃用,现已用于后端参数
- newTime: 0, //跟手滑动后的最新时间💗
- timeNumber: 0, //🌟💗
- ProgressBarBottom: 20, //进度条离底部的距离💗
- object_fit: 'contain', //视频样式默认包含🌟💗
- mode: 'aspectFit', //图片封面样式🌟💗
- timeout: "", //🌟用来阻止 setTimeout()方法
- voice: "", //🌟用来阻止 setTimeout()方法
- oldVideo: "",
- isAutoplay: false, //是否开启自动播放(默认不开启)
- autoplayText: "开启自动播放",
- timers: "",
- // 引入评论 - 参数
- heightNum: 1.18,
- // 双击点赞参数
- touchNum: 0,
- aixinLeft: 0,
- aixinTop: 0,
- isShowAixin: false,
- Rotate: 0,
- isShow1: false, //控制渲染变量1
- isShow2: false, //控制渲染变量2 : 专门控制 uni-popup
- showPlay: false, //转轮显示控制
- rotates: 0, //转轮旋转角度
- rotateTime: "", //转轮递归事件控制
- xrotats: "",
- player: "",
- top:0,
- w:0,
- }
- },
- created: function() {
- setTimeout(e => {
- uni.createSelectorQuery().select('#w').boundingClientRect(r2 => {
- //this.w = r2.width;
-
- }).exec();
- }, 50)
- },
- onLoad(options) {
- this.windowWidth = uni.getSystemInfoSync().screenWidth //获取屏幕宽度
- this.boxStyle.width = this.windowWidth + 'px' //给宽度加px
- this.wHeight = uni.getSystemInfoSync().screenHeight; //获取屏幕高度
- this.boxStyle.height = this.wHeight - this.deleteHeight; //改变视频高度
- setTimeout(e=>{
- this.getData();
- },10)
-
- setTimeout(e=>{
- this.tapVideoHover("");
- },100)
-
- uni.getSystemInfo({
- success: (res) => {
- this.top = res.safeArea.top;
- }
- });
- },
- onShow(){
- console.log('回到前台');
- if(this.dataList.length !== 0){
- this.dataList[this.k].state = 'play';
- console.log('1');
- uni.createVideoContext(this.dataList[this.k]._id,this).play()
- console.log('2');
- }
- },
- onHide(){
- this.dataList[this.k].state = 'pause';//界面隐藏也要停止播放视频
- uni.createVideoContext(this.dataList[this.k]._id,this).pause();//暂停以后继续播放
- console.log('到后台');
- },
- watch:{
- k(k,old_k){//监听 k 值的变化,可以控制视频的播放与暂停
- console.log(k)
- // 清理定时器
- // this.dataList[old_k].state = 'stop'//如果是被滑走的视频,就停止播放
- this.dataList[old_k].playIng = false//如果视频暂停,就加载封面
- this.dataList[old_k].isplay = true
- uni.createVideoContext(this.dataList[old_k]._id,this).play()
- clearTimeout(this.oldVideo)
- this.oldVideo = setTimeout(()=>{
- uni.createVideoContext(this.dataList[old_k]._id,this).seek(0)
- uni.createVideoContext(this.dataList[old_k]._id,this).pause()
- console.log('预留第' + (old_k + 1) + '个视频:' + this.dataList[old_k]._id)
- },500)
- // 2.0版本已经去掉了下面这一句,视频不用暂停,只需要把声音禁止就行
- // uni.createVideoContext(this.dataList[old_k]._id + '' + old_k,this).stop()//如果视频暂停,那么旧视频停止,这里的this.dataList[old_k]._id + '' + old_k,后面加 old_k 是为了每一个视频的 id 值不同,这样就可以大程度的避免串音问题
- this.dataList[k].state = 'play'
- console.log('已经暂停 --> 第' + (old_k + 1) + '个视频~')//提示
- clearTimeout(this.player);
- this.player = setTimeout(()=>{
- uni.createVideoContext(this.dataList[k]._id,this).play();
- },50);
-
- if(k == (this.dataList.length-1)) {
- (async ()=>{
- await this.getData();
- // 【2.0版本更新内容】- start
- var p = k;
- ++p;
- this.dataList[p].isplay = true
- setTimeout(()=>{
- uni.createVideoContext(this.dataList[p]._id,this).play()
- clearTimeout(this.timeout)
- this.timeout = setTimeout(()=>{
- uni.createVideoContext(this.dataList[p]._id,this).seek(0)
- uni.createVideoContext(this.dataList[p]._id,this).pause()
- console.log('预加载第' + (p + 1) + '个视频:' + this.dataList[p]._id)
- },1500)
- },20)
- //【2.0版本更新内容】- end
- })();
- }
- //【此处处理进度条卡住的问题】
- if(uni.getSystemInfoSync().platform !== 'ios'){
- setTimeout(()=>{
- uni.createVideoContext(this.dataList[k]._id,this).pause()
- uni.createVideoContext(this.dataList[k]._id,this).play()
- },100)
- }
- this.xrotats = setTimeout(()=>{
- this.showPlay = true;
- },200)
- }
- },
- methods: {
- getData:function(){
- userList.forEach(e=>{
- e.id = 'A'+e.id+''+parseInt(Math.random()*1000);
- this.dataList.push(e);
- });
-
- },
- touchstart(event) {
- this.dataList[this.k].isShowimage = true //刚触摸的时候就要显示预览视频图片了
- this.dataList[this.k].isShowProgressBarTime = true //显示时间线
- this.ProgressBarOpacity = 1 //让滑块显示起来更明显一点
- this.dotWidth = 10 //让点显示起来更明显一点
- },
- touchend() { //当手松开后,跳到最新时间
- console.log('touchEnd');
- uni.createVideoContext(this.dataList[this.k]._id, this).seek(this.newTime)
- if (this.dataList[this.k].state == 'pause') {
- this.dataList[this.k].state = 'play'
- uni.createVideoContext(this.dataList[this.k]._id, this).play();
- console.log('touchEnd 播放数据',this.k,this.dataList[this.k]._id);
- }
- this.dataList[this.k].isShowProgressBarTime = false //触摸结束后,隐藏时间线
- this.dataList[this.k].isShowimage = false //触摸结束后,隐藏时间预览
- this.ProgressBarOpacity = 0.5 //隐藏起来进度条,不那么明显了
- this.dotWidth = 0 //隐藏起来进度条,不那么明显了
- },
- touchmove(event) { //当手移动滑块时,计算位置、百分小数、新的时间
- var msg = []
- if (this.videoTime !== '') {
- msg = this.videoTime.split(':')
- }
- var timeNumber = Number(msg[0]) * 60 + Number(msg[1])
- this.currentPositions = event.changedTouches[0].screenX
- this.percent = this.currentPositions / this.windowWidth
- this.newTime = this.percent * timeNumber
- this.currenttimes = parseInt(this.newTime)
- let theTime = this.newTime
- let middle = 0; // 分
- if (theTime > 60) {
- middle = parseInt(theTime / 60);
- theTime = parseInt(theTime % 60);
- }
- this.changeTime = `${Math.round(middle)>9?Math.round(middle):'0'+Math.round(middle)}:${Math.round(theTime)>9?Math.round(theTime):'0'+Math.round(theTime)}`
- },
- tapVideoHover(state,event){
- console.log('kkkk=>',this.k);
-
- this.dataList[this.k].isShowimage = false
- this.dataList[this.k].isShowProgressBarTime = false
- this.ProgressBarOpacity = 0.5
- this.dotWidth = 0
- console.log('state--',state);
- // 1.启用双击点赞 --- start
-
-
- if(state=='play'||state=='continue'){
- this.dataList[this.k].state = 'pause';
- }else{
- this.dataList[this.k].state = 'continue';
- }
-
- this.dataList[this.k].isShowPlayIcon = true;
-
- console.log('xxx',this.dataList[this.k].state);
- if(this.dataList[this.k].state == 'continue'){
- console.log('播放数据',this.dataList[this.k]._id);
- uni.createVideoContext(this.dataList[this.k]._id,this).play();//暂停以后继续播放
- }
- if(this.dataList[this.k].state == 'pause'){
- uni.createVideoContext(this.dataList[this.k]._id,this).pause();//暂停以后继续播放
- }
-
- },
- scrolls (event) {
- console.log('scrolls');
-
- this.isDragging = event.isDragging;
- if (!event.isDragging) {//isDragging:判断用户是不是在滑动,滑动:true,停止滑动:false。我们要用户停止滑动时才给 k 赋值,这样就可以避免很多麻烦
- var i = Math.round(Math.abs(event.contentOffset.y) / (this.wHeight - this.deleteHeight + 1))//先用绝对值取出滑动的距离,然后除以屏幕高度,取一个整,就知道你现在滑动到哪一个视频了
- if(i !== this.k){//这里加判断是因为这个方法会执行很多次,会造成重复请求,所以这里写一个限制
- let num = 300;
- clearTimeout(this.timers);
- this.timers = setTimeout(()=>{
- this.k = i;//判断了用户没有滑动,确认了用户的确是在看这个视频,然后就赋值啦
- this.dataList[this.k].state = 'play';
- console.log('正在播放 --> 第' + (this.k + 1) + '个视频~');
- },num);
- }
- }
- },
- timeupdate:function(){
-
- },
- playIngs:function(){
-
- },
- click:function(){
- console.log('click');
- },
- navBack:function(){
- uni.navigateBack({
- animationType: 'pop-out',
- animationDuration: 200
- });
- },
- }
- }
- </script>
- <style>
- .container {
- background-color: #000000;
- }
- .item {
- /* width : 750rpx; */
- background-color: #000000;
- position: relative;
- }
- .videoHover {
- position: absolute;
- top: 0;
- left: 0;
- flex: 1;
- background-color: rgba(0, 0, 0, 0.1);
- justify-content: center;
- align-items: center;
- /* border-style: dashed;
- border-color: #DD524D;
- border-width: 1px; */
- }
- .playState {
- width: 80rpx;
- height: 80rpx;
- opacity: 0.9;
- }
- .userInfo {
- position: absolute;
- bottom: 80px;
- right: 10px;
- flex-direction: column;
- }
- .userAvatar {
- border-radius: 500%;
- margin-bottom: 15px;
- border-style: solid;
- border-width: 2px;
- border-color: #ffffff;
- }
- .userAvatar {
- width: 100rpx;
- height: 100rpx;
- }
- .likeIco,
- .commentIco
- .shareIco{
- width: 60rpx;
- height: 60rpx;
- margin-top: 15px;
- }
- .likeNum,
- .commentNum,
- .shareTex {
- color: #ffffff;
- font-size: 30rpx;
- text-align: center;
- margin: 5px;
- }
- .likeNumActive {
- color: red;
- }
- .content {
- width: 610rpx;
- z-index: 99;
- position: absolute;
- bottom: 30px;
- /* background-color: #007AFF; */
- /* justify-content: center; */
- padding: 15rpx;
- flex-direction: column;
- justify-content: flex-start;
- color: #ffffff;
- }
- .userName {
- font-size: 30rpx;
- color: #ffffff;
- margin-top: 80upx;
- }
- .words {
- margin-top: 10rpx;
- font-size: 30rpx;
- color: #ffffff;
- }
- .root {
- /* background-color: #000000; */
- background-color: #00ffff;
- }
-
- .person {
- position: absolute;
- right: 0;
- height: 88rpx;
- }
-
- .person .num {
- background-color: rgba(255, 100, 3, 1);
- height: 58rpx;
- border-radius: 100rpx 0 0 100rpx;
- padding: 0 20rpx;
- }
-
-
- .right,
- .bottom {
- position: absolute;
- bottom: 80rpx;
- padding-bottom: env(safe-area-inset-bottom);
- }
-
- .right {
- right: 30rpx;
- bottom: 250rpx;
- }
-
- .right .item1 {
- width: 100rpx;
- text-align: center;
- }
-
- .right .iconbox{
- width: 94rpx;
- }
-
- .right image {
- width: 100%;
- height: 100%;
- }
-
-
- .bottom {
- left: 30rpx;
- }
-
- .goods .icon,
- .goods .icon image {
- width: 290rpx;
- height: 290rpx;
- }
-
- .bg {
- /* background-image: url(/static/images/other/video/bg.png); */
- position: absolute;
- left: 0;
- top: 0;
- width: 100%;
- height: 74rpx;
- }
-
- .goods {
- width: 330rpx;
- background-color: rgba(255, 255, 255, 0.4);
- padding: 20rpx;
- border-radius: 20rpx;
- margin-top: 20rpx;
- }
-
-
-
-
- </style>
|