<template>
<view class="shortVideo" @click="showManage = false">
<!--
注意:这是 H5、微信小程序界面,请勿和 new_index.nvue、index.nvue 混用
1. new_index.nvue、index.nvue这两个是App页面
2. 另外:data.js 是上一版本留下的假数据,这一版改成了 URL 请求了(如不需要可以删除,也可作为后端请求参考)
3. 请各位大神多多留手,我已经把请求内存开到最大了
4. 视频 id 切记是字符串类型
-->
<!-- 头部导航 -->
<view class="header" :style="{ top: mTop }">
<view class="tool-bar">
<view class="iconfont icon-ic_leftarrow" @tap="goBack"></view>
</view>
<view class="items" @click.stop="navTap(2)" v-if="!isUser">
<text class="tName" :class="currentNav == 2 ? 'on' : ''">关注</text>
</view>
<view class="items" @click.stop="navTap(1)" v-if="!isUser">
<text class="tName" :class="currentNav == 1 ? 'on' : ''">推荐</text>
</view>
</view>
<swiper :style="'width: ' + windowWidth + 'px; height: ' + windowHeight + 'px;'" :vertical="true"
@animationfinish="animationfinish" @change="change" @touchstart="forcePlayVideo" :current="k"
:indicator-dots="false">
<swiper-item v-for="(list, index) in dataList" :key="index">
<view v-if="max > index">
<view>
<!--
1.v-if:用于控制视频在节点的渲染数
2.muted的默认值是 false,代表默认是禁音视频的
3.http-cache默认开启视频缓存
4.poster(封面(方案一)):这里的封面默认处理存储在阿里云的视频
5.show-loading:这里默认去掉播放转圈的标志
v-if="Math.abs(k-index)<=1"
-->
<video class="video" :id="list.community_id + '' + index" :loop="true"
:muted="(platform === 'ios' && index !== k) || (isIOS13 && !audioUnlocked)"
:autoplay="index === k" :controls="false" :http-cache="true" :custom-cache="false"
:page-gesture="false" :show-fullscreen-btn="false" :show-loading="false"
:show-center-play-btn="false" :enable-progress-gesture="false" :src="list.video_link"
@ended="ended(index)" @play="play(index)" @click="tapVideoHover(list.state, $event)"
@waiting="waiting(index)" @progress="onprogress($event)"
@timeupdate="ontimeupdate(index, $event)"
:style="'width: ' + windowWidth + 'px; height: ' + windowHeight + 'px;z-index: -1;'"></video>
</view>
<!-- 播放状态:pause 的时候就会暂停 -->
<view class="videoHover" @click="tapVideoHover(list.state, $event)"
:style="'width: ' + windowWidth + 'px; height: ' + windowHeight + 'px;'">
<image v-if="list.state == 'pause'" class="playState" src="../static/img/index/play.png">
</image>
</view>
<view class="videoHover" v-if="list.loading"
:style="'width: ' + windowWidth + 'px; height: ' + windowHeight + 'px;'">
<image class="playState" src="../static/img/index/play.png"></image>
</view>
<!--审核状态-->
<view v-if="list.status == -1 || list.status == 0 || list.status == -2" class="video-status">
<view v-if="list.status == -1 || list.status == -2" class="status-title">
<image class="image" src="../static/img/index/video-failed.png"></image>
<text class="title">{{ list.status == -1 ? '审核未通过' : '已下架' }},内容仅自己可见</text>
</view>
<view v-else class="status-title">
<image class="image" src="../static/img/index/video-review.png"></image>
<text class="title">正在审核,内容仅自己可见</text>
</view>
<view class="status_info">
<text
class="refusal">{{ list.status == -1 || list.status == -2 ? list.refusal : '发布的内容审核通过后,将在首页展示!' }}</text>
</view>
</view>
<view>
<!-- 最底下的文字部分 -->
<view class="content">
<view class="cart">
<text class="cartName">@{{ list.author && list.author.nickname }}</text>
</view>
<view class="words" :style="'width: ' + (windowWidth - 120) + 'px;'">
<view v-if="list.isMore || list.content.length <= 15">
<text class="info">{{ list.content }}</text>
<view class="close">
<text v-if="list.isMore" class="more" @click="moreTap(list)">收起</text>
</view>
</view>
<view class="wordsCon" v-else>
<text class="info">{{ list.content.slice(0, 15) }}...</text>
<text class="more" @click.stop="moreTap(list)">展开</text>
</view>
</view>
<view v-if="list.relevance.length == 1 && k === index" class="product">
<scroll-view scroll-x="true" style="white-space: nowrap; display: flex"
scroll-with-animation show-scrollbar="true">
<view class="product-item" v-for="(goods, idx) in list.relevance" :key="idx"
v-if="goods.spu">
<view v-if="goods.spu" class="item-count acea-row" @click="goDetail(goods.spu)">
<view class="picture">
<image :src="goods.spu.image"></image>
</view>
<view class="product-text">
<view class="name line1">{{ goods.spu.store_name }}</view>
<view class="product-price">
<view class="price">
¥
<text>{{ goods.spu.price }}</text>
</view>
<view class="buy-btn">购买</view>
</view>
</view>
</view>
</view>
</scroll-view>
</view>
<view v-else-if="list.relevance.length > 1 && k === index" class="product">
<swiper :autoplay="false" :circular="circular" :interval="interval" :duration="duration"
:loop="true" next-margin="20rpx">
<block v-for="(goods, idx) in list.relevance" :key="idx" v-if="goods.spu">
<swiper-item class="swiper-item">
<view class="swiper-count">
<view v-if="goods.spu" class="item-count acea-row"
@click="goDetail(goods.spu)">
<view class="picture">
<image :src="goods.spu.image"></image>
</view>
<view class="product-text">
<view class="name line1">{{ goods.spu.store_name }}</view>
<view class="product-price">
<view class="price">
<priceFormat :price="goods.spu.price" weight
intSize="32" floatSize="22" labelSize="22">
</priceFormat>
</view>
<view class="buy-btn">购买</view>
</view>
</view>
</view>
</view>
</swiper-item>
</block>
</swiper>
</view>
<navigator v-if="list.topic" hover-class="none" class="product_cate"
:url="'/pages/plantGrass/plant_search_list/index?id=' + list.topic.topic_id">
<view>
<text class="icon">#</text>
<text class="text">{{ list.topic.topic_name }}</text>
</view>
</navigator>
</view>
<view class="userInfo">
<!-- 1.头像 -->
<navigator v-if="list.author" hover-class="none"
:url="'/pages/plantGrass/plant_user/index?id=' + list.uid" class="pictrue">
<image class="userAvatar"
:src="(list.author && list.author.avatar) || '/static/images/f.png'"
mode="aspectFill"></image>
<view v-if="(!list.is_fans || !userInfo.uid) && userInfo.uid != list.author.uid"
class="guanzhu" @click.stop="followAuthor(list)"><text
class="iconfont icon-ic_increase"></text>
</view>
<view v-else class="yiguanzhu"><text class="iconfont"></text></view>
</navigator>
<!-- 2.点赞 -->
<view @click="cLike(list)" style="margin-top: 5px"
:class="{ likeNumActive: list.relevance_id }">
<text class="iconfont icon-ic_love_2"
:class="{ likeNumActive: list.relevance_id }"></text>
<text class="info-text">{{ list.count_start > 0 ? list.count_start : '点赞' }}</text>
</view>
<!-- 3.评论 -->
<view v-if="community_reply_status == 1 && list.status == 1" class="comment"
@click="toComment(list, index)" style="margin-top: 18px">
<text class="iconfont icon-icon_comment"></text>
<text class="info-text">{{ list.count_reply > 0 ? list.count_reply : '评论' }}</text>
</view>
<!-- 4.分享 -->
<view v-if="list.status == 1" @click="listenerActionSheet" style="margin-top: 17px">
<text class="iconfont icon-icon_transmit"></text>
<text class="info-text">分享</text>
</view>
<!-- 5.自己的视频 -->
<view v-if="list.author && userInfo.uid == list.author.uid && isUser"
style="margin-top: 17px">
<view class="video-my">
<view class="video-dian" @click.stop="showManage = !showManage">
<text class="dian"></text>
<text class="dian"></text>
<text class="dian"></text>
</view>
<view class="manage" v-show="showManage">
<navigator hover-class="none"
:url="'/pages/plantGrass/plant_release/index?id=' + list.community_id + '&type=2'"
class="items">
<image class="image" src="../static/img/index/video-edit.png"></image>
<text>编辑</text>
</navigator>
<view class="items" @click.stop="deleteTopic(list)">
<image class="image" src="../static/img/index/video-delete.png"></image>
<text>删除</text>
</view>
</view>
</view>
</view>
<!-- 提到的商品 -->
<view v-if="list.relevance.length > 0 && k === index" @click="openMore(list)"
class="mention" style="opacity: 0.9; margin-top: 18px">
<image src="../static/img/index/collection.png"></image>
<text class="count">{{ list.relevance.length }}</text>
</view>
</view>
</view>
</view>
</swiper-item>
</swiper>
<view class="noVideo acea-row row-center-wrapper" v-if="!dataList.length && !loadVideo">
<view>
<image :src="imgHost + '/static/no-video.png'" class="pictrue"></image>
<text class="tips">暂无短视频内容哦~</text>
</view>
</view>
<comment ref="comments" :bottom="0" :isShow="showComment" :userInfo="userInfo" @successFul="pinlunFun"
@close="closeScrollview"></comment>
<!-- 他提到的宝贝弹窗 -->
<mentioned ref="mentioned" @close="closePopup" :list="moreList" :uid="authorUid"></mentioned>
<image v-if="H5ShareBox" class="shareImg" :src="imgHost + '/static/images/share-info.png'"
@click="H5ShareBox = false"></image>
<!-- 分享按钮 -->
<view class="generate-posters acea-row row-middle" :class="posters ? 'on' : ''">
<!-- #ifndef MP -->
<button class="item" :class="weixinStatus ? 'item3' : ''" hover-class="none" v-if="weixinStatus === true"
@click="H5ShareBox = true">
<view class="iconfont icon-ic_wechat"></view>
<view class="">发送给朋友</view>
</button>
<!-- #endif -->
<!-- #ifdef MP -->
<button class="item" :class="weixinStatus ? 'item3' : ''" open-type="share" hover-class="none"
@click="goFriend">
<view class="iconfont icon-ic_wechat"></view>
<view class="">发送给朋友</view>
</button>
<!-- #endif -->
<button class="item" :class="weixinStatus ? 'item3' : ''" hover-class="none" @click="goPoster">
<view class="iconfont icon-a-ic_picture1"></view>
<view class="">生成海报</view>
</button>
</view>
<view class="mask" v-if="posters" @click="listenerActionClose"></view>
<!-- 海报展示 -->
<view class="mask" v-if="posterImageStatus"></view>
<view class="poster-pop" v-if="posterImageStatus">
<image src="/static/images/poster-close.png" class="close" @click="posterImageClose"></image>
<image :src="posterImage" class="image"></image>
<!-- #ifndef H5 -->
<view class="keep" @click="savePosterPath">保存到相册</view>
<!-- #endif -->
</view>
<canvas class="canvas" canvas-id="myCanvas" v-if="canvasStatus"></canvas>
</view>
</template>
<script>
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
const app = getApp();
let sysHeight = uni.getSystemInfoSync().statusBarHeight + 'px';
import {
toLogin
} from '@/libs/login.js';
import {
mapGetters
} from 'vuex';
import {
configMap
} from '@/utils';
import comment from '@/components/comment.vue';
import mentioned from '@/components/mentioned.vue';
import {
HTTP_REQUEST_URL
} from '@/config/app';
import {
videoList,
myVideoList,
graphicStartApi,
followAuthorApi,
getVideoCode,
deletePlantApi,
focusArticleLst
} from '@/api/community.js';
import {
getUserInfo,
imgToBase
} from '@/api/user.js';
import ClipboardJS from '@/plugin/clipboard/clipboard.js';
export default {
components: {
comment,
mentioned
},
computed: configMap({
community_reply_status: 0
}, mapGetters(['isLogin', 'uid'])),
data() {
return {
sysHeight: sysHeight,
//#ifdef MP
mTop: uni.getSystemInfoSync().statusBarHeight + 'px',
//#endif
//#ifndef MP
mTop: 20 + 'px',
//#endif
imgHost: HTTP_REQUEST_URL,
videoID: 0,
pinlunNum: 0,
windowWidth: 0,
windowHeight: 0,
platform: '',
deleteHeight: 0,
dataList: [],
shareItem: null,
k: 0,
max: 2,
oldVideo: '',
voice: '',
timeout: '',
authorUid: 0,
current: 0,
// 引入评论 - 参数
heightNum: 1.3,
// 双击点赞参数
touchNum: 0,
aixinLeft: 0,
aixinTop: 0,
Rotate: 0,
currentNav: 1,
limit: 6,
page: 1,
oldCurrent: 1,
H5ShareBox: false,
showComment: false,
loadVideo: true,
loadend: false,
userInfo: {},
moreList: [],
posters: false,
weixinStatus: false,
showManage: false,
isUser: false,
isSatrt: 0,
userUid: 0,
posterImageStatus: false,
storeImage: '', //海报产品图
PromotionCode: '', //二维码图片
canvasStatus: false, //海报绘图标签
posterImage: '', //海报路径
posterbackgd: '../static/img/index/posterbackgd.png',
avatar: '/static/images/f.png',
codeImg: '',
autoplay: false,
circular: true,
interval: 3000,
duration: 500,
actionSheetHidden: false,
isLoadingIndex: 0,
buffered: 0, // 加载进度
// #ifdef MP
isRoutine: true,
// #endif
// #ifndef MP
isRoutine: false,
// #endif
platform: '', // 检测 iOS
// ...其他数据
isIOS13: false, // 是否是iOS13
audioUnlocked: false, // 音频是否已解锁
};
},
watch: {
k(new_k, old_k) {
const max = new_k + 2;
if (this.max < max) {
this.max = max;
}
if (this.oldCurrent != this.currentNav) {
this.oldCurrent = this.currentNav;
return false;
}
this.dataList[old_k].playIng = false; //如果视频暂停,就加载封面
this.dataList[old_k].isplay = true;
this.dataList[old_k].state = 'pause';
// 2.0版本已经去掉了下面这一句,视频不用暂停,只需要把声音禁止就行
uni.createVideoContext(this.dataList[old_k].community_id + '' + old_k, this)
.pause(); //如果视频暂停,那么旧视频停止,这里的this.dataList[old_k].id + '' + old_k,后面加 old_k 是为了每一个视频的 id 值不同,这样就可以大程度的避免串音问题
// #ifdef MP
this.dataList[new_k].state = 'play';
this.dataList[new_k].isplay = false;
this.dataList[new_k].playIng = true;
this.$nextTick(() => {
var videoContext = uni.createVideoContext(this.dataList[new_k].community_id + '' + new_k,
this);
videoContext.play();
});
// setTimeout(() => {
// uni.createVideoContext(this.dataList[new_k].community_id + '' + new_k, this).play()
// }, 250)
this.videoShare(this.dataList[new_k]);
// #endif
}
},
onLoad(options) {
this.platform = uni.getSystemInfoSync().platform.toLowerCase();
// 获取系统信息
const systemInfo = uni.getSystemInfoSync();
// 判断是否为 iPhone 13 系列
if (systemInfo.platform === 'ios') {
const model = systemInfo.model;
this.isIOS13 = model.includes('iPhone 13')
}
console.log(systemInfo, this.isIOS13, '系统信息');
this.getOptions(options);
this.videoID = options.id;
this.isUser = options.user == 1 ? true : false;
this.userUid = options.uid ? options.uid : 0;
this.isSatrt = options.tab == 1 ? 1 : 0;
this.get(); //刚进入页面加载数据
this.downloadFilePromotionCode(this.videoID);
if (this.isLogin) {
this.getUserInfo();
}
// #ifdef H5
this.setOpenShare();
// #endif
},
onShow() {},
onHide() {
this.dataList[this.k].state = 'pause'; //界面隐藏也要停止播放视频
uni.createVideoContext(this.dataList[this.k].community_id + '' + this.k, this).pause(); //暂停以后继续播放
clearInterval(timer)
},
onReady: function() {
this.windowWidth = uni.getSystemInfoSync().windowWidth;
this.windowHeight = uni.getSystemInfoSync().windowHeight;
},
//发送给朋友
onShareAppMessage(res) {
let uid = this.uid ? this.uid : 0;
return {
title: this.shareItem.title || '',
path: '/pages/short_video/nvueSwiper/index?id=' + this.shareItem.community_id + '&pid=' + uid,
imageUrl: this.shareItem.image[0] || '' //分享图标,路径可以是本地文件路径、代码包文件路径或者网络图片路径.支持PNG及JPG。显示图片长宽比是 5:4
};
},
//分享到朋友圈
onShareTimeline(res) {
return {
title: this.shareItem.title || '',
query: {
id: this.shareItem.community_id,
pid: this.uid
}, //页面参数
imageUrl: this.shareItem.image[0] || '' //分享图标,路径可以是本地文件路径、代码包文件路径或者网络图片路径.支持PNG及JPG。显示图片长宽比是 5:4
};
},
methods: {
//#ifdef MP
videoShare(item) {
this.shareItem = item;
if (item && item.status == 1) {
uni.showShareMenu({
withShareTicket: true,
menus: ['shareAppMessage', 'shareTimeline']
});
} else {
uni.hideShareMenu();
}
},
// #endif
goBack: function() {
uni.navigateBack();
},
navTap(n) {
this.currentNav = n;
this.dataList.forEach((item) => {
item.state = 'pause';
});
this.k = 0;
this.page = 1;
this.loadVideo = true;
this.loadend = false;
this.dataList = [];
n == 1 ? this.get() : this.getFocusList();
},
/**
* 获取个人用户信息
*/
getUserInfo: function() {
let that = this;
getUserInfo().then((res) => {
that.userInfo = res.data;
});
},
// 关注作者
followAuthor: function(item) {
if (this.isLogin === false) {
toLogin();
} else {
let status = 1;
followAuthorApi(item.uid, {
status: status
})
.then((res) => {
if (res.status === 200) {
item.is_fans = true;
}
this.$util.Tips({
title: res.message
});
})
.catch((err) => {
return uni.showToast({
title: err,
icon: 'none',
duration: 2000
});
});
}
},
// 删除话题
deleteTopic(item) {
let that = this;
uni.showModal({
content: '确定要删除该话题么?',
success: function(res) {
if (res.confirm) {
deletePlantApi(item.community_id).then((res) => {
if (res.status === 200) {
that.$util.Tips({
title: res.message
});
setTimeout(function() {
uni.redirectTo({
url: '/pages/plantGrass/plant_user/index?id=' +
item.uid
});
}, 1000);
}
});
} else if (res.cancel) {
console.log('用户点击取消');
}
}
});
},
play(k) {
console.log(' 播放了', k);
this.dataList[k].isplay = false;
this.dataList[k].playIng = true;
this.dataList[k].state = 'play';
this.dataList[k].loading = false;
},
// 进入加载状态
waiting(k) {
if (this.buffered < 100) {
uni.showLoading({
title: '努力加载中',
mask: false
});
this.isLoadingIndex = 0;
}
},
// 加载百分比
onprogress(e) {
this.buffered = e.detail.buffered;
},
// 播放进度变化时触发
ontimeupdate(k, e) {
this.isLoadingIndex += 1;
if (this.isLoadingIndex > 1) uni.hideLoading();
},
pinlunFun(e) {
this.pinlunNum = e;
this.dataList.forEach((item) => {
if (item.community_id == this.videoID) {
item.count_reply = item.count_reply + 1;
}
});
},
getOptions(options) {
let that = this;
// #ifdef MP
if (options.scene) {
let value = that.$util.getUrlParams(decodeURIComponent(options.scene));
//记录推广人uid
if (value.pid) app.globalData.spid = value.pid;
}
// #endif
if (options.pid) app.globalData.spid = options.pid;
},
// #ifdef H5
// 微信分享;
setOpenShare: function() {
let that = this;
let uid = this.uid ? this.uid : 0;
if (that.$wechat.isWeixin()) {
let data = this.dataList[0];
let configAppMessage = {
desc: data.content,
title: data.title,
link: location.href + '?pid=' + uid + '&id=' + this.videoID,
imgUrl: data.image
};
that.$wechat.wechatEvevt(['updateAppMessageShareData', 'updateTimelineShareData',
'onMenuShareAppMessage', 'onMenuShareTimeline'
], configAppMessage);
}
},
// #endif
moreTap(item) {
item.isMore = !item.isMore;
},
moveHandle() {},
closeScrollview() {
// 点击评论里面的叉叉,就会关闭评论
this.showComment = false;
},
toComment(item, index) {
// 注意点击评论之后会执行这里
/*
(1)先加载缓冲
(2)获取当前视频 ID 信息
(3)????重要????
- 一定要记得看 index.vue 里面
uni.setStorageSync("user",this.peopleList[i]);
这个东西,用于存储当前用户信息。在 插件里面会使用到这个东西,
记得写一下。
(4)打开评论
*/
this.showComment = true;
this.$refs.comments.getData(item, index);
},
ended(k) {
if (this.dataList[k]) {
const videoCtx = uni.createVideoContext(this.dataList[k].community_id + '' + k, this);
if (this.isIOS13) {
videoCtx.muted = true;
videoCtx.seek(0);
videoCtx.play();
setTimeout(() => {
if (this.k === k) {
videoCtx.muted = false;
}
}, 300);
} else {
videoCtx.seek(0);
// iOS 需要重置状态
if (this.platform === 'ios') {
videoCtx.muted = false;
setTimeout(() => {
videoCtx.play();
}, 300);
} else {
videoCtx.play();
}
}
}
},
//点击播放&&暂停
tapVideoHover(state, event) {
// 1.启用双击点赞 --- start
this.touchNum++;
setTimeout(() => {
if (this.touchNum == 1) {
if (state == 'play' || state == 'continue') {
// this.dataList[this.k].state = 'pause';
this.$set(this.dataList[this.k], 'state', 'pause');
} else {
// this.dataList[this.k].state = 'continue';
this.$set(this.dataList[this.k], 'state', 'continue');
}
if (this.dataList[this.k].state == 'continue') {
uni.createVideoContext(this.dataList[this.k].community_id + '' + this.k, this)
.play(); //暂停以后继续播放
}
if (this.dataList[this.k].state == 'pause') {
uni.createVideoContext(this.dataList[this.k].community_id + '' + this.k, this)
.pause(); //暂停以后继续播放
}
}
this.touchNum = 0;
}, 200);
},
forcePlayVideo() {
if (this.platform === 'ios') {
const currentVideoCtx = uni.createVideoContext(this.dataList[this.k].community_id + '' + this.k, this);
currentVideoCtx.muted = false;
currentVideoCtx.play();
// 确保状态同步
this.$nextTick(() => {
this.dataList[this.k].isplay = false;
this.dataList[this.k].playIng = true;
this.dataList[this.k].state = 'play';
});
}
},
// 专门处理iOS13播放
handleIOS13Play(videoCtx, index) {
console.log('进入ios13');
// 1. 先确保静音
videoCtx.muted = true;
// 2. 播放静音视频
videoCtx.play();
// 3. 延迟后尝试取消静音
setTimeout(() => {
console.log('进入ios13定时器');
// 双重确认当前是活跃视频
if (this.k === index) {
videoCtx.muted = false;
// 4. iOS13需要额外的seek操作来激活音频
videoCtx.seek(videoCtx.currentTime || 0);
// 5. 标记音频已解锁
this.audioUnlocked = true;
this.$set(this.dataList[index], 'state', 'play');
}
}, 500);
},
// iOS专用播放处理方法
handleIOSPlay(videoCtx, index) {
// 1. 先静音播放
videoCtx.muted = true;
videoCtx.play();
// 2. 延迟后取消静音
setTimeout(() => {
videoCtx.muted = false;
this.$set(this.dataList[index], 'state', 'play');
}, 300);
},
change(event) {
const newIndex = event.detail.current;
const oldIndex = this.k;
// 暂停旧视频
if (this.dataList[oldIndex]) {
const oldVideoCtx = uni.createVideoContext(this.dataList[oldIndex].community_id + '' + oldIndex, this);
oldVideoCtx.pause();
oldVideoCtx.muted = true;
this.$set(this.dataList[oldIndex], 'state', 'pause');
}
this.k = newIndex;
// 播放新视频
if (this.dataList[newIndex]) {
const newVideoCtx = uni.createVideoContext(this.dataList[newIndex].community_id + '' + newIndex, this);
if (this.isIOS13) {
this.handleIOS13Play(newVideoCtx, newIndex);
} else if (this.platform === 'ios') {
this.handleIOSPlay(newVideoCtx, newIndex);
} else {
newVideoCtx.play();
this.$set(this.dataList[newIndex], 'state', 'play');
}
}
},
animationfinish(event) {
// 1.这里进行判断,如果是最后一个视频就进入 get() 方法加载视频进入列表
if (this.k == this.dataList.length - 1) {
this.loadVideo = true;
this.currentNav == 1 ? this.GET() : this.getFocusList();
}
// iOS 可能需要再次触发播放
if (this.platform === 'ios' && this.dataList[this.k]) {
const currentVideoCtx = uni.createVideoContext(this.dataList[this.k].community_id + '' + this.k, this);
currentVideoCtx.muted = true;
currentVideoCtx.play();
setTimeout(() => {
currentVideoCtx.muted = false;
}, 500);
}
},
//每一组结束时新的请求
GET() {
let that = this;
if (!that.loadVideo) return;
if (that.loadend) return;
that.loadVideo = true;
that.isUser ?
myVideoList(that.userUid, {
page: that.page,
limit: that.limit,
is_star: that.isSatrt,
community_id: that.videoID
})
.then((res) => {
that.videoData(res.data.list);
that.loadVideo = false;
that.loadend = res.data.list.length < that.limit;
})
.catch((err) => {
return uni.showToast({
title: err,
icon: 'none',
duration: 2000
});
}) :
videoList({
page: that.page,
limit: that.limit,
id: that.videoID
})
.then((res) => {
that.loadVideo = false;
that.videoData(res.data.list);
that.loadend = res.data.list.length < that.limit;
})
.catch((err) => {
return uni.showToast({
title: err,
icon: 'none',
duration: 2000
});
});
},
get() {
let that = this;
// 1.这里引入后端请求数据
that.isUser ?
myVideoList(that.userUid, {
page: that.page,
limit: that.limit,
is_star: that.isSatrt,
community_id: that.videoID
})
.then((res) => {
that.page = that.page + 1;
that.videoData(res.data.list);
})
.catch((err) => {
return uni.showToast({
title: err,
icon: 'none',
duration: 2000
});
}) :
videoList({
page: that.page,
limit: that.limit,
id: that.videoID
})
.then((res) => {
that.page = that.page + 1;
that.videoData(res.data.list);
})
.catch((err) => {
return uni.showToast({
title: err,
icon: 'none',
duration: 2000
});
});
},
getFocusList() {
let that = this;
if (!that.loadVideo) return;
if (that.loadend) return;
that.loadVideo = true;
focusArticleLst({
page: that.page,
limit: that.limit
})
.then((res) => {
that.loadVideo = false;
that.loadend = res.data.list.length < that.limit;
that.page = that.page + 1;
that.videoData(res.data.list);
})
.catch((err) => {
return uni.showToast({
title: err,
icon: 'none',
duration: 2000
});
});
},
videoData(list) {
if (list.length == 0) return;
let that = this;
var msg = list;
// 2.这里把视频添加到视频列表
for (let i = 0; i < msg.length; i++) {
msg[i]['isMore'] = false;
msg[i]['playIng'] = false;
msg[i]['state'] = 'pause';
msg[i]['isplay'] = true;
msg[i]['loading'] = false;
that.dataList.push(msg[i]);
//#ifndef H5
if (i == 0 && that.k == 0) {
this.dataList[0].isplay = false;
this.dataList[0].playIng = true;
this.dataList[0].state = 'play';
this.dataList[0].loading = false;
this.$nextTick(() => {
var videoContext = uni.createVideoContext(this.dataList[0].community_id + '' + 0,
this);
// videoContext.requestFullScreen({
// direction: 0
// })
videoContext.play();
});
// uni.createVideoContext(that.dataList[0].community_id+''+0,that).play()
}
//#endif
}
//#ifdef MP
if (this.k == 0) {
this.videoShare(this.dataList[0]);
}
// #endif
// #ifdef H5
if (that.isLogin) {
that.setOpenShare(that.videoID);
}
// #endif
},
share() {
this.H5ShareBox = true;
},
/**
* 分享打开
*
*/
listenerActionSheet: function() {
// #ifdef H5
if (this.$wechat.isWeixin() === true) {
this.weixinStatus = true;
}
// #endif
this.posters = true;
},
// 分享关闭
listenerActionClose: function() {
this.posters = false;
},
//隐藏海报
posterImageClose: function() {
this.posterImageStatus = false;
},
// 小程序关闭分享弹窗;
goFriend: function() {
this.posters = false;
},
/* 获取产品分销二维码
* @param function successFn 下载完成回调
*
*/
downloadFilePromotionCode: function(id) {
let that = this;
let type;
// #ifndef MP
type = 'wechat';
// #endif
// #ifdef MP
type = 'routine';
// #endif
getVideoCode(id, {
type: type
})
.then(async (res) => {
that.codeImg = res.data.url;
})
.catch((err) => {
that.$set(that, 'PromotionCode', '');
});
},
/*
* 保存到手机相册
*/
// #ifdef MP
savePosterPath: function() {
let that = this;
uni.getSetting({
success(res) {
if (!res.authSetting['scope.writePhotosAlbum']) {
uni.authorize({
scope: 'scope.writePhotosAlbum',
success() {
uni.saveImageToPhotosAlbum({
filePath: that.posterImage,
success: function(res) {
that.posterImageClose();
that.$util.Tips({
title: '保存成功',
icon: 'success'
});
},
fail: function(res) {
that.$util.Tips({
title: '保存失败'
});
}
});
}
});
} else {
uni.saveImageToPhotosAlbum({
filePath: that.posterImage,
success: function(res) {
that.posterImageClose();
that.$util.Tips({
title: '保存成功',
icon: 'success'
});
},
fail: function(res) {
that.$util.Tips({
title: '保存失败'
});
}
});
}
}
});
},
// #endif
/**
* 生成海报
*/
async goPoster() {
if (this.posterImage) {
this.posterImageStatus = true;
this.posters = false;
return;
}
let that = this;
let arr2;
that.posters = false;
that.$set(that, 'canvasStatus', true);
uni.showLoading({
title: '海报生成中',
mask: true
});
// #ifdef MP || APP-PLUS
if (that.dataList[that.k].author.avatar) {
arr2 = [
that.posterbackgd,
await that.fileStoreImage(that.dataList[that.k].image[0]),
await that.fileStoreImage(that.codeImg),
await that.fileStoreImage(that.dataList[that.k].author.avatar)
];
} else {
arr2 = [that.posterbackgd, await that.fileStoreImage(that.dataList[that.k].image[0]), await that
.fileStoreImage(that.codeImg), that.avatar
];
}
// #endif
// #ifdef H5
if (that.dataList[that.k].author.avatar) {
arr2 = [
that.posterbackgd,
await that.imgToBase(that.dataList[that.k].image[0]),
await that.imgToBase(that.codeImg),
await that.imgToBase(that.dataList[that.k].author.avatar)
];
} else {
arr2 = [that.posterbackgd, await that.imgToBase(that.dataList[that.k].image[0]), await that
.imgToBase(that.codeImg), that.avatar
];
}
// #endif
//生成推广海报
that.$util.videoPosterCanvas(
arr2,
that.dataList[that.k].content,
that.dataList[that.k].author.nickname,
function(tempFilePath) {
that.$set(that, 'posterImage', tempFilePath);
that.$set(that, 'posterImageStatus', true);
that.$set(that, 'actionSheetHidden', !that.actionSheetHidden);
that.$set(that, 'canvasStatus', false);
},
(err) => {
that.$set(that, 'canvasStatus', false);
}
);
},
//图片转符合安全域名路径
fileStoreImage(url) {
let that = this;
// #ifdef MP || APP-PLUS
let ishttps = url.split('//')[0] == 'https:';
if (!ishttps) {
url = 'https://' + url.split('//')[1];
}
// #endif
return new Promise((resolve, reject) => {
uni.downloadFile({
url: url,
success: function(res) {
resolve(res.tempFilePath);
},
fail: function() {
return that.$util.Tips({
title: ''
});
}
});
});
},
/*
* 保存到手机相册
*/
// #ifdef MP
savePosterPath: function() {
let that = this;
uni.getSetting({
success(res) {
if (!res.authSetting['scope.writePhotosAlbum']) {
uni.authorize({
scope: 'scope.writePhotosAlbum',
success() {
uni.saveImageToPhotosAlbum({
filePath: that.posterImage,
success: function(res) {
that.posterImageClose();
that.$util.Tips({
title: '保存成功',
icon: 'success'
});
},
fail: function(res) {
that.$util.Tips({
title: '保存失败'
});
}
});
}
});
} else {
uni.saveImageToPhotosAlbum({
filePath: that.posterImage,
success: function(res) {
that.posterImageClose();
that.$util.Tips({
title: '保存成功',
icon: 'success'
});
},
fail: function(res) {
that.$util.Tips({
title: '保存失败'
});
}
});
}
}
});
},
// #endif
async imgToBase(url) {
let res = await imgToBase({
image: url
});
return res.data.image;
},
cLike(item) {
if (this.isLogin) {
let status = item.relevance_id ? 0 : 1;
graphicStartApi(item.community_id, {
status: status
})
.then((res) => {
if (item.relevance_id) {
item.count_start--;
item.count_start = item.count_start == 0 ? 0 : item.count_start;
item.relevance_id = false;
} else {
item.count_start++;
item.relevance_id = true;
}
})
.catch((err) => {
return uni.showToast({
title: err,
icon: 'none',
duration: 2000
});
});
} else {
toLogin();
}
},
/*查看提到的宝贝*/
openMore(item) {
this.$refs.mentioned.showPopup();
this.moreList = item.relevance;
this.authorUid = item.uid;
},
closePopup() {
this.$refs.mentioned.closePopup();
},
goDetail(item) {
if (item.product_type === 1) {
uni.navigateTo({
url: `/pages/activity/goods_seckill_details/index?id=${item.product_id}&time=${item.stop_time}&spid=${this.uid}`
});
} else if (item.product_type === 2) {
uni.navigateTo({
url: `/pages/activity/presell_details/index?id=${item.activity_id}&spid=${this.uid}`
});
} else if (item.product_type === 0) {
uni.navigateTo({
url: `/pages/goods_details/index?id=${item.product_id}&spid=${this.uid}`
});
} else if (item.product_type === 4) {
uni.navigateTo({
url: `/pages/activity/combination_details/index?id=${item.activity_id}&spid=${this.uid}`
});
} else if (item.product_type === 40) {
uni.navigateTo({
url: `/pages/activity/combination_status/index?id=${item.activity_id}&spid=${this.uid}`
});
}
}
}
};
</script>
<style lang="scss" scoped>
.header {
position: fixed;
z-index: 9;
width: 750rpx;
height: 86rpx;
flex-direction: row;
justify-content: center;
align-items: center;
top: 20rpx;
.tool-bar {
position: absolute;
left: 0;
top: 0;
width: 60rpx;
height: 86rpx;
display: flex;
justify-content: center;
.icon-ic_leftarrow {
margin-right: 40rpx;
margin-left: 20rpx;
font-size: 38rpx;
color: #fff;
}
}
.items {
margin: 0 30rpx;
.tName {
color: #ffffff;
font-size: 32rpx;
&.on {
font-size: 38rpx;
}
}
}
}
.shareImg {
z-index: 1000;
position: fixed;
left: 0;
top: 0;
width: 100%;
height: 100%;
}
.shortVideo,
.container {
background: linear-gradient(180deg, rgba(0, 0, 0, 0.8) 0%, #000000 100%);
}
.item {
position: relative;
}
.video-status {
width: 690rpx;
position: absolute;
left: 30rpx;
background: rgba(0, 0, 0, 0.55);
border-radius: 16rpx;
top: 60rpx;
padding: 30rpx;
.status-title {
flex-direction: row;
align-items: center;
.title {
margin-left: 20rpx;
color: #ffffff;
font-size: 28rpx;
}
}
.refusal {
color: #ffffff;
font-size: 22rpx;
margin: 15rpx 0 0 48rpx;
}
.image {
width: 28rpx;
height: 28rpx;
}
}
.videoHover {
position: absolute;
top: 0;
left: 0;
flex: 1;
justify-content: center;
align-items: center;
}
.playState {
width: 160rpx;
height: 160rpx;
opacity: 0.2;
}
.userInfo {
position: absolute;
bottom: 60rpx;
right: 20rpx;
flex-direction: column;
text-align: center;
.pictrue {
flex-direction: column;
justify-content: center;
align-items: center;
position: relative;
image {
width: 92rpx;
height: 92rpx;
}
.guanzhu {
width: 42rpx;
height: 42rpx;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
background: #e93323;
border-radius: 100%;
position: relative;
top: -20rpx;
left: 26rpx;
.iconfont {
font-size: 20rpx;
}
}
.yiguanzhu {
width: 42rpx;
height: 42rpx;
}
}
.mention {
width: 92rpx;
height: 92rpx;
position: relative;
image {
width: 58rpx;
height: 58rpx;
position: absolute;
right: 16rpx;
}
.count {
width: 30rpx;
height: 30rpx;
line-height: 30rpx;
background: #fff;
border-radius: 100%;
display: flex;
align-items: center;
justify-content: center;
color: #e93323;
position: absolute;
right: 8rpx;
top: -12rpx;
font-size: 20rpx;
}
}
.iconfont {
color: #ffffff;
&.likeNumActive {
color: #e93323;
}
}
}
.icon-ic_love_2 {
font-size: 64rpx;
}
.icon-icon_comment {
font-size: 59rpx;
}
.icon-icon_transmit {
font-size: 58rpx;
}
.info-text {
margin-top: 10rpx;
color: #ffffff;
}
.userAvatar {
border-radius: 500%;
border-style: solid;
border-width: 2px;
border-color: #ffffff;
width: 80rpx;
height: 80rpx;
display: block;
}
.video-dian {
position: relative;
width: 66rpx;
height: 66rpx;
align-items: center;
justify-content: center;
flex-direction: row;
left: 12rpx;
.dian {
width: 13rpx;
height: 13rpx;
background-color: #fff;
border-radius: 100%;
margin-right: 10rpx;
&:last-child {
margin-right: 0;
}
}
}
.manage {
width: 210rpx;
background: #ffffff;
box-shadow: 0 2rpx 15rpx rgba(0, 0, 0, 0.1);
padding: 0 15rpx;
position: absolute;
bottom: -50rpx;
right: 110rpx;
z-index: 90;
border-radius: 16rpx;
&::before {
content: '';
display: inline-block;
width: 26rpx;
height: 26rpx;
background: #ffffff;
transform: rotate(140deg);
position: absolute;
top: 60rpx;
right: -12rpx;
box-shadow: -1rpx -1rpx 1rpx rgba(0, 0, 0, 0.05);
}
.items {
border-bottom: 1px solid #eeeeee;
color: #282828;
font-size: 26rpx;
padding: 20rpx 0;
display: flex;
align-items: center;
flex-direction: row;
&:last-child {
border-bottom: none;
}
.image {
width: 32rpx;
height: 32rpx;
margin: 0 16rpx 0;
}
}
}
.likeNumActive {
color: #e93323;
}
.content {
width: 590rpx;
position: absolute;
bottom: 30rpx;
bottom: calc(30rpx+ constant(safe-area-inset-bottom)); ///兼容 IOS<11.2/
bottom: calc(30rpx + env(safe-area-inset-bottom)); ///兼容 IOS>11.2/
padding: 15rpx 0;
flex-direction: column;
justify-content: flex-start;
color: #ffffff;
left: 50%;
margin-left: -345rpx;
.time {
font-size: 24rpx;
color: rgba(255, 255, 255, 0.5);
margin-left: 12rpx;
}
.cart {
height: 48rpx;
flex-direction: row;
.cartName {
font-size: 24rpx;
color: #fff;
}
}
}
.canvas {
z-index: 300;
width: 750px;
height: 1036px;
}
.poster-pop {
width: 600rpx;
/*#ifdef H5*/
height: 820rpx;
/*#endif*/
/*#ifndef H5*/
height: 910rpx;
/*#endif*/
position: fixed;
left: 50%;
transform: translateX(-50%);
z-index: 399;
top: 50%;
margin-top: -410rpx;
border-radius: 30rpx;
}
.poster-pop .image {
width: 100%;
height: 100%;
display: block;
border-radius: 16rpx;
}
.poster-pop .close {
width: 46rpx;
height: 75rpx;
position: fixed;
right: 0;
top: -73rpx;
display: block;
}
.poster-pop .keep {
text-align: center;
width: 600rpx;
height: 70rpx;
line-height: 70rpx;
border-radius: 43rpx;
background: #e93323;
color: #ffffff;
font-size: 25rpx;
margin-top: 40rpx;
}
.mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.6);
z-index: 9;
}
.words {
margin-top: 12rpx;
.close {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
margin-right: 20rpx;
.imgClose {
width: 18rpx;
height: 10rpx;
margin-left: 10rpx;
}
}
.wordsCon {
position: relative;
.more {
position: absolute;
bottom: 0;
right: 40rpx;
font-size: 26rpx;
}
.img {
width: 18rpx;
height: 10rpx;
margin-left: 4rpx;
position: absolute;
bottom: 7rpx;
right: 15rpx;
}
}
.info {
color: #fff;
font-size: 28rpx;
}
.more {
font-size: 26rpx;
color: #ffffff;
font-weight: 400;
}
}
.product {
display: block;
margin-top: 27rpx;
.product-item {
display: inline-block;
width: 444rpx;
height: 136rpx;
background: rgba(0, 0, 0, 0.55);
border-radius: 12rpx;
padding: 16rpx 15rpx;
margin-right: 30rpx;
}
/deep/uni-swiper,
/deep/swiper {
display: block;
height: 136rpx !important;
.swiper-count {
display: block;
width: 444rpx !important;
height: 136rpx !important;
background: rgba(0, 0, 0, 0.55);
border-radius: 12rpx;
padding: 16rpx 15rpx 16rpx 15rpx;
}
.swiper-item {
display: block;
width: 480rpx !important;
}
}
.item-count {
width: 414rpx;
flex-direction: row;
justify-content: space-between;
border-radius: 12rpx;
.picture {
width: 104rpx;
height: 104rpx;
border-radius: 10rpx;
image {
width: 104rpx;
height: 104rpx;
border-radius: 10rpx;
}
}
.product-text {
width: 266rpx;
justify-content: space-between;
.name {
display: inline-block;
width: 266rpx;
}
.product-price {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
.price {
display: flex;
flex-direction: row;
align-items: end;
text {
font-size: 34rpx;
}
}
.buy-btn {
width: 92rpx;
height: 40rpx;
display: flex;
align-items: center;
justify-content: center;
color: #fff;
border-radius: 26rpx;
background: #e93323;
font-size: 20rpx;
}
}
}
}
}
.product_cate {
margin: 20rpx 0;
flex-direction: row;
>view {
display: inline-block;
flex-direction: row;
align-items: center;
border-radius: 30rpx;
padding: 0 24rpx;
line-height: 40rpx;
border-radius: 29rpx;
border: 1px solid #ffffff;
.text {
font-size: 24rpx;
}
.icon {
display: inline-block;
font-size: 26rpx;
font-weight: bold;
position: relative;
top: 2rpx;
margin-right: 8rpx;
}
}
}
.generate-posters {
width: 100%;
height: 170rpx;
background-color: #fff;
position: fixed;
left: 0;
bottom: 0;
z-index: 388;
transform: translate3d(0, 100%, 0);
transition: all 0.3s cubic-bezier(0.25, 0.5, 0.5, 0.9);
border-radius: 40rpx 40rpx 0 0;
align-content: center;
align-items: center;
flex-direction: row;
}
.generate-posters.on {
transform: translate3d(0, 0, 0);
}
.generate-posters .item {
/* #ifdef H5 */
flex: 100%;
/* #endif */
/* #ifndef H5 */
flex: 33.33%;
/* #endif */
text-align: center;
font-size: 30rpx;
&.item3 {
flex: 33.33%;
}
}
.generate-posters .item .iconfont {
font-size: 36rpx;
background-color: #5eae72;
width: 70rpx;
height: 70rpx;
border-radius: 100%;
color: #ffffff;
display: inline-block;
line-height: 70rpx;
margin-bottom: 8rpx;
}
.generate-posters .item .iconfont.icon-a-ic_picture1 {
background-color: #5391f1;
}
.mask {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: rgba(0, 0, 0, 0.6);
z-index: 9;
}
.noVideo {
position: fixed;
top: 400rpx;
z-index: 9;
width: 750rpx;
flex-direction: row;
justify-content: center;
.pictrue {
width: 414rpx;
height: 256rpx;
}
.tips {
text-align: center;
margin-top: 14rpx;
font-size: 26rpx;
color: #999;
}
}
</style>
该代码实现了仿抖音短视频功能,其他设备都没问题,在ios13 系统18.5 设备上打开第一个视频没问题,滑动到第二个视频没有声音了,尝试了很多方法没有解决各位大神有遇到过吗?
0 个回复