新增短视频播放插件

master
于肖磊 2025-09-11 17:57:45 +08:00
parent 2cffe9b1f1
commit 95c6d139a6
3 changed files with 496 additions and 0 deletions

View File

@ -2000,6 +2000,32 @@
}
}
]
},
{
"root": "pages/plugins/video",
"pages": [
{
"path": "index/index",
"style": {
"enablePullDownRefresh": true,
"navigationBarTitleText": ""
}
},
{
"path": "detail/detail",
"style": {
"enablePullDownRefresh": true,
"navigationBarTitleText": ""
}
},
{
"path": "search/search",
"style": {
"enablePullDownRefresh": true,
"navigationBarTitleText": ""
}
}
]
}
],
"preloadRule": {

View File

@ -0,0 +1,102 @@
<template>
<view :class="theme_view">
<block v-if="(data || null) != null && (data.config || null) != null">
<!-- diy模块 -->
<component-form-input :propValue="data" :propDataFormId="data.id" :propKey="random_value" @onLocationBack="user_back_choice_location">
<!-- 底部内容 -->
<template slot="diy-bottom-content">
<!-- 结尾 -->
<component-bottom-line :propStatus="data_bottom_line_status"></component-bottom-line>
</template>
<!-- 底部公共 -->
<template slot="diy-bottom-common">
<component-common ref="common"></component-common>
</template>
</component-form-input>
</block>
<block v-else>
<component-no-data :propStatus="data_list_loding_status" :propMsg="data_list_loding_msg"></component-no-data>
</block>
</view>
</template>
<script>
const app = getApp();
import componentCommon from '@/components/common/common';
import componentFormInput from '@/pages/form-input/components/form-input/form-input';
import componentNoData from '@/components/no-data/no-data';
import componentBottomLine from '@/components/bottom-line/bottom-line';
export default {
components: {
componentCommon,
componentFormInput,
componentNoData,
componentBottomLine,
},
data() {
return {
theme_view: app.globalData.get_theme_value_view(),
data_bottom_line_status: false,
data_list_loding_status: 1,
data_list_loding_msg: '',
load_status: 0,
params: null,
data: null,
//
share_info: {},
//
random_value: 0,
};
},
onLoad(params) {
//
app.globalData.page_event_onload_handle(params);
//
this.setData({
params: app.globalData.launch_params_handle(params),
});
},
onShow() {
//
app.globalData.page_event_onshow_handle();
// onshow
this.init_common();
//
this.set_navigation_bar_color();
},
created() {
window.addEventListener('message', function(event) {
console.log(event.data); //
var upd_data = {
data: event.data || null,
data_list_loding_msg: '',
data_list_loding_status: 0,
data_bottom_line_status: true,
random_value: Math.random(),
};
this.setData(upd_data);
});
},
methods: {
//
init_common() {
// onshow
if ((this.$refs.common || null) != null) {
this.$refs.common.on_show();
}
},
//
set_navigation_bar_color() {
app.globalData.set_navigation_bar_color(parseInt(app.globalData.get_key_data(this.data, 'config.header.com_data.style.function_buttons_type', 0)) == 1);
},
},
};
</script>
<style scoped lang="scss">
</style>

View File

@ -0,0 +1,368 @@
<template>
<div class="page" :style="{ height: height }">
<swiper
class="swiper"
:vertical="true"
@change="changeCurrent"
@animationfinish="animationFinish"
:current="index">
<swiper-item v-for="(item, idx) in videoList" :key="idx" class="swiper-item">
<!-- 视频渲染数预加载数影响性能 -->
<div v-if="Math.abs(index-idx)<=1" class="video-box">
<block v-if="item.src">
<chunlei-video class="video" :src="item.src" :height="height" :width="width"
:play="item.flag" v-if="Math.abs(index-idx)<=1" :gDuration="item.duration"
:initialTime="item.initialTime" @pause="pauseVideo" :objectFit="item.objectFit"
@playEnd="playEnd" :danmuList="danmuList"
>
</chunlei-video>
<cover-view class="cover-view-left">
<cover-view class="left-view">
<!-- #ifdef APP-PLUS-NVUE -->
<text class="left-text">@{{item.at}}</text>
<!-- #endif -->
<!-- #ifndef APP-PLUS-NVUE -->
<cover-view class="left-text">@{{item.at}}</cover-view>
<!-- #endif -->
</cover-view>
<cover-view class="left-view">
<!-- #ifdef APP-PLUS-NVUE -->
<text class="left-text">{{item.content}}</text>
<!-- #endif -->
<!-- #ifndef APP-PLUS-NVUE -->
<cover-view class="left-text">{{item.content}}</cover-view>
<!-- #endif -->
</cover-view>
</cover-view>
<cover-view class="cover-view-right">
<cover-image :src="item.avater" class="avater img" @click.stop="tapAvater"></cover-image>
<!-- #ifdef APP-PLUS-NVUE -->
<text class="right-text-avater">+</text>
<text class="right-text"></text>
<!-- #endif -->
<!-- #ifndef APP-PLUS-NVUE -->
<cover-view class="right-text-avater">+</cover-view>
<cover-view class="right-text"></cover-view>
<!-- #endif -->
<cover-image :src="item.check?'../../static/aixinRed.png':'../../static/aixin.png'" class="img" @click.stop="tapLove"></cover-image>
<!-- #ifdef APP-PLUS-NVUE -->
<text class="right-text">{{item.like}}</text>
<!-- #endif -->
<!-- #ifndef APP-PLUS-NVUE -->
<cover-view class="right-text">{{item.like}}</cover-view>
<!-- #endif -->
<cover-image src="../../static/xiaoxi.png" class="img" @click.stop="tapMsg(item)"></cover-image>
<!-- #ifdef APP-PLUS-NVUE -->
<text class="right-text">{{item.comment}}</text>
<!-- #endif -->
<!-- #ifndef APP-PLUS-NVUE -->
<cover-view class="right-text">{{item.comment}}</cover-view>
<!-- #endif -->
<cover-image src="../../static/share-fill.png" class="img" @click.stop="tapShare"></cover-image>
<!-- #ifdef APP-PLUS-NVUE -->
<text class="right-text">分享</text>
<!-- #endif -->
<!-- #ifndef APP-PLUS-NVUE -->
<cover-view class="right-text">分享</cover-view>
<!-- #endif -->
</cover-view>
</block>
<image src="../../static/logo.png" :style="{ height: height }" v-else class="video-box"></image>
</div>
</swiper-item>
</swiper>
</div>
</template>
<script>
import chunleiVideo from '../../components/chunlei-video/chunlei-video'
export default {
components:{
chunleiVideo
},
data() {
return {
sysheight:0,
playCount:2,//
videoList:[
],
height:'667px',
index:0,
width:'',
oldIndex:0,
danmuList:[
{text: '发条弹幕0',color: '#fff',time: 2,avatar:'../../static/avatar.png'},
{text: '发条弹幕1',color: '#fff',time: 3,avatar:'../../static/avatar.png'},
{text: '发条弹幕2',color: '#fff',time: 4,avatar:'../../static/avatar.png'},
{text: '发条弹幕3',color: '#fff',time: 5,avatar:'../../static/avatar.png'},
],
}
},
created(){
//#ifdef APP-PLUS
plus.screen.lockOrientation("portrait-primary")
//subnvue
uni.getSubNVueById('comment').hide()
uni.getSubNVueById('input-box').hide()
//#endif
this.sysheight = uni.getSystemInfoSync().windowHeight
this.height = `${this.sysheight}px`
let width = uni.getSystemInfoSync().windowWidth
this.width = `${width}px`
this.videoList.length = 300
this.videoList.fill({src:''})
},
async mounted() {
//id id
let id = "http://img.kaiyanapp.com/255365dbfc2622930eb0cdb33e43abf0.jpeg?imageMogr2/quality/60/format/jpg"
await this.pushVideoList()
this.index = this.videoList.reduce((total,item)=>{
if(id==''||id==item.id){
id = ''
}else{
total++
}
return total
},0)
if(!this.index){
this.$nextTick(()=>{
this.videoPlay(this.index)
})
}
},
onHide(){
for (let item of this.videoList) {
item.flag = false
}
},
methods: {
animationFinish(e){
//#ifdef APP-PLUS
this.changeCurrent(e)
//#endif
},
changeCurrent(e){
this.index = e.detail.current;
this.$nextTick(()=>{
for (let item of this.videoList) {
item.flag = false
}
this.videoList[this.index].flag = true
})
},
pushVideoList(){
let promise = new Promise((resolve,reject)=>{
uni.request({
url: 'https://api.apiopen.top/videoRecommend?id=127397',
success: (res) => {
let videoGroup = []
for (let item of res.data.result) {
if(item.type == 'videoSmallCard'){
videoGroup.push({
src:item.data.playUrl,
content:item.data.title,
flag:false,
check:false,
like:'7w',
comment:'1045',
at:item.data.author.name,
id:item.data.author.icon,
avater:item.data.author.icon,
initialTime:0,
duration:item.data.duration
})
}
}
let len = this.videoList.filter(item=>item.src).length
for(let i = len;i<len+videoGroup.length;i++){
this.$set(this.videoList,i,videoGroup[i-len])
}
resolve()
}
})
})
return promise
},
tapLove(){
this.videoList[this.index].check = !this.videoList[this.index].check
this.videoList = [...this.videoList]
},
tapAvater(){
uni.showToast({
icon:'none',
title:`点击索引为${this.index}的头像`
})
},
tapMsg(item){
//#ifndef APP-NVUE
uni.showToast({
icon:'none',
title:`查看索引为${this.index}的评论`
})
//#endif
//#ifdef APP-NVUE
uni.getSubNVueById('comment').show('none',0,()=>{
uni.$emit('showComment',item.content)
});
//#endif
},
tapShare(){
uni.showToast({
icon:'none',
title:`分享索引为${this.index}的视频`
})
},
videoPlay(index){
let promise = new Promise((resolve,reject)=>{
resolve()
})
promise.then(res=>{
this.$set(this.videoList[index],'flag',!this.videoList[index].flag)
})
},
pauseVideo(val){
if(typeof this.videoList[this.oldIndex].initialTime !='undefined') this.videoList[this.oldIndex].initialTime = val
},
clickVideo(){
this.videoList[this.index].flag = !this.videoList[this.index].flag
}
},
watch:{
index(newVal,oldVal){
let len = this.videoList.filter(item=>item.src).length
//
if(len - this.index - 1 <= this.playCount){
this.pushVideoList()
}
this.oldIndex = oldVal
}
}
}
</script>
<style scoped>
.swiper{
flex: 1;
background-color: #000;
}
.swiper-item {
flex: 1;
}
.video {
flex: 1;
}
.video-box{
flex: 1;
width: 750rpx;
}
.cover-view-center{
position: absolute;
justify-content: center;
align-items: center;
opacity: 0.1;
z-index: 999;
}
.cover-view-left{
position: absolute;
margin-left: 10upx;
width: 500upx;
bottom: 120upx;
z-index: 9999;
font-size: 16px;
color: #FFFFFF;
/* #ifndef APP-PLUS */
white-space: pre-wrap;
text-overflow:ellipsis;
overflow:hidden;
/* #endif */
}
.left-view{
margin-bottom: 20upx;
}
.left-text{
font-size: 16px;
color: #FFFFFF;
}
.avater{
border-radius: 50upx;
border-color: #fff;
border-style: solid;
border-width: 2px;
}
.cover-view-right{
position: absolute;
bottom: 160upx;
right: 20upx;
/* #ifndef APP-PLUS-NVUE */
display: flex;
flex-direction: column;
/* #endif */
z-index: 9999;
}
.right-text-avater{
position: absolute;
font-size: 14px;
top: 80upx;
left: 30upx;
height: 40upx;
width: 40upx;
background-color: #DD524D;
color: #FFFFFF;
border-radius: 50%;
text-align: center;
line-height: 40upx;
z-index: 999;
}
.avater-icon{
height: 40upx;
width: 40upx;
color: #fff;
background-color: #DD524D;
border-radius: 50%;
position: absolute;
left: 30upx;
top:-20upx;
}
.right-text{
text-align: center;
font-size: 14px;
color: #FFFFFF;
margin-bottom: 50upx;
height: 20px;
}
.img{
height: 100upx;
width: 100upx;
opacity: 0.9;
}
.page{
/* #ifndef APP-PLUS-NVUE */
display: flex;
flex-direction: column;
/* #endif */
flex: 1;
}
</style>