Appearance
使用方法
安卓视频播放器UTS原生插件支持播放本地视频,网络视频,直播等多种视频,支持多种滤镜,支持切换音轨,支持弹幕,支持生成gif图片,视频截图等多种功能,插件支持uniapp和uniapp x,支持vue2和vue3的选项式和组合式
相关链接
插件使用注意事项
- 如果您在使用插件的过程中有任何问题,可以联系作者,作者将全力协助您使用插件
- 本文档同时提供了uniapp的用法示例和uniappx的用法示例,插件市场导入的示例项目仅为uniapp的用法示例,如果您需要uniappx的示例项目可以通过下方的链接下载示例
- 组件只能在nvue/uvue页面中使用,不支持vue页面
联系作者

关注微信公众号可联系作者
插件地址
https://ext.dcloud.net.cn/plugin?id=22159
权限
- android.permission.WRITE_EXTERNAL_STORAGE
- android.permission.READ_EXTERNAL_STORAGE
API用法
在使用插件的地方引入以下代码:
js
import * as module from "@/uni_modules/leven-uts-videoPlayer"js
import * as module from "@/uni_modules/leven-uts-videoPlayer"组件用法
在使用插件的地方引入以下代码:
vue
<leven-uts-videoPlayer ref="refVideoPlayer" style="flex:1; height: 300px;" :config="config" @onError="onError"
@onEvent="onEvent" @onEventMethod="onEventMethod">
</leven-uts-videoPlayer>vue
<leven-uts-videoPlayer ref="refLevenPlayer" style="flex:1; height: 300px;" :configX="config" @onError="onError"
@onEvent="onEvent" @onEventMethod="onEventMethod">
</leven-uts-videoPlayer>
//组件的引用
const refLevenPlayer = ref<LevenUtsVideoPlayerElement | null>(null)页面内容
API页面
vue
<template>
<view>
<uni-card title="API">
<button type="primary" @click="requestPermissions">申请插件所需权限</button>
<button type="primary" @click="checkAllFilesPermission">检查是否有所有文件访问权限</button>
<button type="primary" @click="toAllFilesPermissionPage">跳转到所有文件访问权限页面</button>
</uni-card>
<uni-card title="播放器组件">
<button type="primary" @click="toPlayer">播放器组件使用</button>
</uni-card>
</view>
</template>
<script>
import * as module from "@/uni_modules/leven-uts-videoPlayer"
export default {
data() {
return {
}
},
methods: {
toPlayer() {
uni.navigateTo({
url: "/pages/index/player"
})
},
//跳转到所有文件访问权限页面
toAllFilesPermissionPage() {
module.toAllFilesPermissionPage({
//成功执行的函数
success: (res) => {
console.log(res)
},
//失败执行的函数
fail: (res) => {
console.log(res)
},
//接口调用完成返回函数,不管成功还是失败都会返回
// complete: (res) => {
// console.log(res)
// }
})
},
//检查是否有所有文件访问权限
checkAllFilesPermission() {
module.checkAllFilesPermission({
//成功执行的函数
success: (res) => {
console.log(res)
},
//失败执行的函数
fail: (res) => {
console.log(res)
},
//接口调用完成返回函数,不管成功还是失败都会返回
// complete: (res) => {
// console.log(res)
// }
})
},
//申请插件所需权限
requestPermissions() {
module.requestPermissions({
//参数
params: {
permissions: [
'android.permission.WRITE_EXTERNAL_STORAGE',
'android.permission.READ_EXTERNAL_STORAGE'
]
},
success: (res) => {
console.log(res)
},
fail: (res) => {
console.log(res)
},
//接口调用完成返回函数,不管成功还是失败都会返回
// complete: (res) => {
// console.log(res)
// }
})
}
}
}
</script>
<style>
</style>vue
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<leven-ui-card title="API">
<button type="primary" @click="requestPermissions">申请插件所需权限</button>
<button type="primary" @click="checkAllFilesPermission">检查是否有所有文件访问权限</button>
<button type="primary" @click="toAllFilesPermissionPage">跳转到所有文件访问权限页面</button>
</leven-ui-card>
<leven-ui-card title="播放器组件">
<button type="primary" @click="toPlayer">播放器组件使用</button>
</leven-ui-card>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script setup>
import * as module from "@/uni_modules/leven-uts-videoPlayer"
import { LevenOptions } from "@/uni_modules/leven-uts-videoPlayer"
function toPlayer() {
uni.navigateTo({
url: "/pages/videoPlayer/player"
})
}
//跳转到所有文件访问权限页面
function toAllFilesPermissionPage() {
module.toAllFilesPermissionPage({
//成功执行的函数
success: (res) => {
console.log(res)
},
//失败执行的函数
fail: (res) => {
console.log(res)
},
//接口调用完成返回函数,不管成功还是失败都会返回
// complete: (res) => {
// console.log(res)
// }
} as LevenOptions)
}
//检查是否有所有文件访问权限
function checkAllFilesPermission() {
module.checkAllFilesPermission({
//成功执行的函数
success: (res) => {
console.log(res)
},
//失败执行的函数
fail: (res) => {
console.log(res)
},
//接口调用完成返回函数,不管成功还是失败都会返回
// complete: (res) => {
// console.log(res)
// }
} as LevenOptions)
}
//申请插件所需权限
function requestPermissions() {
module.requestPermissions({
//参数
params: {
permissions: [
'android.permission.WRITE_EXTERNAL_STORAGE',
'android.permission.READ_EXTERNAL_STORAGE'
]
},
success: (res) => {
console.log(res)
},
fail: (res) => {
console.log(res)
},
//接口调用完成返回函数,不管成功还是失败都会返回
// complete: (res) => {
// console.log(res)
// }
} as LevenOptions)
}
</script>
<style>
</style>组件页面
vue
<template>
<view>
<uni-card title="安卓视频播放器原生插件">
<view style="flex: 1; height: 300px; position: relative;">
<leven-uts-videoPlayer ref="refVideoPlayer" style="flex:1; height: 300px;" :config="config" @onError="onError"
@onEvent="onEvent" @onEventMethod="onEventMethod">
</leven-uts-videoPlayer>
</view>
<uni-section title="内核">
<uni-data-checkbox v-model="config.kernel" :localdata="kernelType"></uni-data-checkbox>
</uni-section>
<uni-section title="播放地址">
<uni-easyinput v-model="config.url" :maxlength="-1" placeholder="请输入播放地址"></uni-easyinput>
</uni-section>
<button type="primary" @click="addDanmaku">添加一条弹幕</button>
<button type="primary" @click="toogleDanmaku">开启/关闭弹幕</button>
<button type="primary" @click="changeMediaTrack">切换音轨</button>
<button type="primary" @click="getAllMediaTrack">获取所有音轨</button>
<button type="primary" @click="clearCache">清除缓存</button>
<button type="primary" @click="stopGif">结束生成gif</button>
<button type="primary" @click="startGif">开始生成gif</button>
<button type="primary" @click="customFilter">自定义滤镜</button>
<button type="primary" @click="setFilter">设置滤镜</button>
<button type="primary" @click="setTransform">镜像翻转</button>
<button type="primary" @click="setRotation">镜像旋转</button>
<button type="primary" @click="getSize">获取视频的尺寸</button>
<button type="primary" @click="getBufferedPercentage">获取当前缓冲百分比</button>
<button type="primary" @click="getCurrentPosition">获取当前播放的位置</button>
<button type="primary" @click="getDuration">获取视频时长</button>
<button type="primary" @click="setMute">设置是否静音播放</button>
<button type="primary" @click="smallVideo">小窗口播放</button>
<button type="primary" @click="fullScreen">全屏播放</button>
<button type="primary" @click="isPlaying">是否播放中</button>
<button type="primary" @click="taskShotPic">视频截图</button>
<button type="primary" @click="setSpeed">倍速播放</button>
<button type="primary" @click="seekTo">设置播放进度</button>
<button type="primary" @click="setVolume">播放音量</button>
<button type="primary" @click="getPlayerData">获取播放属性</button>
<button type="primary" @click="setScreenScaleType">播放比例</button>
<button type="primary" @click="play">开始播放</button>
<button type="primary" @click="pause">暂停播放</button>
<button type="primary" @click="resume">继续播放</button>
<button type="primary" @click="stop">停止播放</button>
<button type="primary" @click="logStr = ''">清空日志</button>
</uni-card>
<uni-card class="uni-card-box" title="日志">
<view><text style="font-size: 14px; flex-wrap: wrap;">{{logStr}}</text></view>
</uni-card>
<!-- 弹窗 -->
<uni-popup ref="refSelectSizePop">
<view style="width: 300px;">
<uni-card title="请选择播放比例">
<view class="view-button" v-for="(item, index) in sizeList" :key="index" @click="selectSizeItem(item)"><text
class="button-text">{{item.text}}</text></view>
</uni-card>
</view>
</uni-popup>
<!-- 弹窗 -->
<uni-popup ref="refSpeedPop">
<view style="width: 300px;">
<uni-card title="请选择播放倍速">
<view class="view-button" v-for="(item, index) in speedList" :key="index" @click="selectSpeedItem(item)">
<text class="button-text">{{item.text}}</text>
</view>
</uni-card>
</view>
</uni-popup>
</view>
</template>
<script>
import * as module from "@/uni_modules/leven-uts-videoPlayer"
export default {
data() {
return {
logStr: "",
//配置
config: {
//播放地址,rtmp://liteavapp.qcloud.com/live/liteavdemoplayerstreamid
//http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear1/prog_index.m3u8
//rtsp://rtspstream:effd2f46af6aef62a77b62104ceafbc0@zephyr.rtsp.stream/movie
//http://alvideo.ippzone.com/zyvd/98/90/b753-55fe-11e9-b0d8-00163e0c0248
// url: "http://vod.ulunix.cn/media_hls/X6-1-wAD-1yQ7R2q-bCJbio780yeu41irzHjQdxj0K42NQp24MULgIW8skzG9y2Cb_C7H3eq1BJFtf2exyVNUP6y69Y80TK7tNV0lCk3TcTiYq0Dmv4Sy2Yly6ZzRGECdsWtL6-fxe2ES3iUQKVtwZubE-ZG6tqe919YIlic2Soc1c1c1c1.m3u8",
//https://res.exexm.com/cw_145225549855002
//https://aliyuncdnsaascloud.xjhktv.com/video/A%20Lin%2B%E5%80%AA%E5%AD%90%E5%86%88-%E4%B8%8D%E5%B1%91%E5%AE%8C%E7%BE%8E%5B%E5%9B%BD%5D%5B1080P%5D.mp4
url: "https://aliyuncdnsaascloud.xjhktv.com/video/A%20Lin%2B%E5%80%AA%E5%AD%90%E5%86%88-%E4%B8%8D%E5%B1%91%E5%AE%8C%E7%BE%8E%5B%E5%9B%BD%5D%5B1080P%5D.mp4",
//播放器预览背景图片,支持网络地址
//http://www.yeyuboke.com/svga/image_default.jpg
backgroundImage: "",
//视频帧背景图片,以视频帧作为图片,单位:微秒
frame: 1000000,
//视频帧图片加载失败显示的图片,需放置到res/mipmap中
error: "error",
//图片预加载资源图片,需放置到res/mipmap中
placeholder: "placeholder",
//是否边播放边缓存
cacheWithPlay: true,
//标题是否显示
titleVisible: false,
//视频标题
title: "安卓高质量视频播放器原生插件",
//返回按钮是否显示
backButtonVisible: false,
//是否可以滑动界面改变进度,声音等
isTouchWidget: true,
//是否需要流量提示
needShowWifiTip: true,
//是否循环播放
loop: false,
//是否显示底部控制条
bottomContainer: true,
//是否显示开始播放按钮
startButtonVisible: false,
//开始播放位置,目前有时候前几秒有跳动问题,毫秒
startPosition: 0,
//请求头信息
header: {
ee: "333",
allowCrossProtocolRedirects: "true",
"User-Agent": "LEVEN"
},
//是否开启硬解码
enableMediaCodec: false,
//是否开启硬解码渲染优化
isMediaCodecTexture: false,
//视频播放比例,可选值:
//SCREEN_TYPE_DEFAULT,SCREEN_TYPE_16_9,SCREEN_TYPE_4_3
//SCREEN_TYPE_18_9,SCREEN_TYPE_FULL,SCREEN_MATCH_FULL
scaleType: "SCREEN_TYPE_DEFAULT",
//播放模式,可选值:GLSURFACE:GLSurfaceView 主要用于OpenGL渲染的,如果支持滤镜,必须选择此模式,SURFACE:SurfaceView,与动画全屏的效果不是很兼容,TEXTURE:TextureView,默认
renderType: "GLSURFACE",
//水印图片,只支持本地图片,需放置到res/mipmap下
waterImage: {
//图片名称,不需要加扩展名
image: "uni_icon",
//图片宽度
width: 100,
//图片高度
height: 100,
//透明度
alpha: 0.6,
//水印位置,0:右上角,1.右下角,2.左上角,3.左下角,4.居中,5.右中,6.上中,7.下中,8.左中
position: 3,
//位置偏移量,默认:1.0
offset: 1.5
},
//默认播放内核
kernel: 2,
//是否静音播放
isMute: false,
//gif的帧之间延时,默认:0
delay: 0,
//生成gif采样率,默认:1
sampleSize: 1,
//生成gif缩放比例,默认:5
scaleSize: 5,
//生成gif截图频率,毫秒,默认:50
frequencyCount: 50,
//弹幕配置
danmakuParams: {
//是否开启弹幕
danmakuShow: true,
//初始化弹幕文件,xml文件,如果是raw文件的话不需要加扩展名,其他需要加上扩展名
//http://www.yeyuboke.com/uniplugin/player/danmaku.xml
///storage/emulated/0/Download/WeiXin/danmaku.xml
danmakuFile: "comments",
//弹幕文件类型,url:网络地址,path:本地路径,raw:raw文件
danmakuFileType: "raw",
//最大显示行数
maxLines: 3,
//防弹幕重叠
preventOverlapping: true,
//描边样式
danmakuStyle: {
//样式,可选值:
//DANMAKU_STYLE_DEFAULT:自动
//DANMAKU_STYLE_NONE:无
//DANMAKU_STYLE_SHADOW:阴影
//DANMAKU_STYLE_STROKEN:描边(默认)
//DANMAKU_STYLE_PROJECTION:投影
style: "DANMAKU_STYLE_STROKEN",
//描边值,DANMAKU_STYLE_SHADOW 阴影模式下,values传入阴影半径
//DANMAKU_STYLE_STROKEN 描边模式下,values传入描边宽度
//DANMAKU_STYLE_PROJECTION 投影模式下,values传入offsetX, offsetY, alpha offsetX/offsetY: x/y 方向上的偏移量 alpha: 投影透明度 [0...255]
values: [3]
},
//是否启用合并重复弹幕,默认:true
duplicateMergingEnabled: true,
//设置弹幕滚动速度系数,只对滚动弹幕有效,默认:1.0
scrollSpeedFactor: 1.2,
//设置弹幕文本大小,默认:1.0
scaleTextSize: 1.2
},
//加载完成是否自动播放
autoPlay: true
},
// 内核
kernelType: [{
text: "IJK内核",
value: 1
}, {
text: "EXO内核",
value: 2
}, {
text: "系统内核",
value: 3
}],
// 播放比例列表
sizeList: [{
text: "默认",
value: "SCREEN_TYPE_DEFAULT"
}, {
text: "16:9",
value: "SCREEN_TYPE_16_9"
}, {
text: "4:3",
value: "SCREEN_TYPE_4_3"
}, {
text: "18:9",
value: "SCREEN_TYPE_18_9"
}, {
text: "全屏",
value: "SCREEN_TYPE_FULL"
}, {
text: "全屏拉伸",
value: "SCREEN_MATCH_FULL"
}],
//倍速播放
speedList: [{
text: "0.5倍",
value: 0.5
}, {
text: "0.75倍",
value: 0.75
}, {
text: "正常倍速",
value: 1
}, {
text: "1.5倍",
value: 1.5
}, {
text: "2倍",
value: 2
}],
//是否全屏播放
isFullScreen: false,
//翻转类型
transform: 0,
//滤镜
filterValue: 0,
//音轨列表
mediaTrackList: [],
//当前的音轨索引
mediaTrackIndex: 0
}
},
onReady() {
//申请权限
module.requestPermissions({
//参数
params: {
permissions: [
'android.permission.WRITE_EXTERNAL_STORAGE',
'android.permission.READ_EXTERNAL_STORAGE'
]
},
success: (res) => {
console.log(res)
},
fail: (res) => {
console.log(res)
},
//接口调用完成返回函数,不管成功还是失败都会返回
// complete: (res) => {
// console.log(res)
// }
})
},
methods: {
//获取播放属性
getPlayerData() {
if (this.$refs.refVideoPlayer) {
this.$refs.refVideoPlayer.getPlayerData();
}
},
// 开始播放
play() {
this.$refs.refVideoPlayer.play(this.config);
},
// 暂停播放
pause() {
this.$refs.refVideoPlayer.pause();
},
// 继续播放
resume() {
this.$refs.refVideoPlayer.resume();
},
// 停止播放
stop() {
this.$refs.refVideoPlayer.stop();
},
// 视频截图
taskShotPic() {
if (this.$refs.refVideoPlayer) {
this.$refs.refVideoPlayer.taskShotPic();
}
},
// 是否播放中
isPlaying() {
if (this.$refs.refVideoPlayer) {
this.$refs.refVideoPlayer.isPlaying();
}
},
// 设置播放进度
seekTo() {
if (this.$refs.refVideoPlayer) {
this.$refs.refVideoPlayer.seekTo({
//播放进度,单位:毫秒
position: 30000
});
}
},
// 全屏播放
fullScreen() {
if (this.$refs.refVideoPlayer) {
this.$refs.refVideoPlayer.fullScreen();
}
},
// 小窗口播放
smallVideo() {
if (this.$refs.refVideoPlayer) {
this.$refs.refVideoPlayer.smallVideo({
//小窗口大小
size: [150, 150]
});
}
},
//设置播放比例
setScreenScaleType() {
if (this.$refs.refSelectSizePop) {
this.$refs.refSelectSizePop.open();
}
},
//播放比例的选择
selectSizeItem(item) {
if (this.$refs.refVideoPlayer) {
this.$refs.refVideoPlayer.setScreenScaleType({
value: item.value
})
}
},
//播放音量
setVolume() {
this.$refs.refVideoPlayer.setVolume({
//音量取值范围:0.0-1.0
left: 0.3,
right: 0.3
})
},
//倍速播放
setSpeed() {
if (this.$refs.refSpeedPop) {
this.$refs.refSpeedPop.open();
}
},
//倍速播放的选择
selectSpeedItem(item) {
if (this.$refs.refVideoPlayer) {
this.$refs.refVideoPlayer.setSpeed({
value: item.value
})
}
},
//设置是否静音播放
setMute() {
this.config.isMute = !this.config.isMute
this.$refs.refVideoPlayer.setMute({
value: this.config.isMute
})
},
//获取视频时长
getDuration() {
this.$refs.refVideoPlayer.getDuration()
},
//获取当前播放的位置
getCurrentPosition() {
this.$refs.refVideoPlayer.getCurrentPosition()
},
//获取当前缓冲百分比
getBufferedPercentage() {
this.$refs.refVideoPlayer.getBufferedPercentage()
},
//获取视频的尺寸
getSize() {
this.$refs.refVideoPlayer.getSize()
},
//旋转视频画面
setRotation() {
this.$refs.refVideoPlayer.setRotation({
rotation: 90
})
},
//镜像翻转
setTransform() {
this.transform += 1;
if (this.transform > 2) {
this.transform = 0;
}
this.$refs.refVideoPlayer.setTransform({
//翻转类型,0:正常,1.上下翻转,2.左右翻转
transform: this.transform
})
},
//设置滤镜
setFilter() {
this.filterValue += 1;
if (this.filterValue > 26) {
this.filterValue = 0;
}
switch (this.filterValue) {
case 0:
//清除滤镜
this.$refs.refVideoPlayer.clearFilter()
break;
case 1:
//自动修正
this.$refs.refVideoPlayer.setFilterAutoFix({
//修正值,0-1
scale: 0.8
})
break;
case 2:
//马赛克
this.$refs.refVideoPlayer.setFilterPixelation({
//马赛克大小,1-100
pixel: 40
})
break
case 3:
//黑白滤镜
this.$refs.refVideoPlayer.setFilterBlackAndWhite()
break
case 4:
//对比度
this.$refs.refVideoPlayer.setFilterContrast({
//对比度值,0.1-2.0
contrast: 0.8
})
break
case 5:
//交叉线
this.$refs.refVideoPlayer.setFilterCrossProcess()
break
case 6:
//纪录片
this.$refs.refVideoPlayer.setFilterDocumentary()
break
case 7:
//双色调
this.$refs.refVideoPlayer.setFilterDuotone({
firstColor: "#0000FF",
secondColor: "#FFFF00"
})
break
case 8:
//补光
this.$refs.refVideoPlayer.setFilterFillLight({
//光强度,0.0 - 1.0
strength: 0.8
})
break
case 9:
//伽马线
this.$refs.refVideoPlayer.setFilterGamma({
//值,0.0 - 2.0
value: 0.8
})
break
case 10:
//纹理
this.$refs.refVideoPlayer.setFilterGrain({
//强度值,0.0 - 1.0
strength: 0.8
})
break
case 11:
//灰度
this.$refs.refVideoPlayer.setFilterGrayscale()
break
case 12:
//色度
this.$refs.refVideoPlayer.setFilterHue({
//值,0.0 - 1.0
value: 0.8
})
break
case 13:
//反色
this.$refs.refVideoPlayer.setFilterInvertColors()
break
case 14:
//简单风格
this.$refs.refVideoPlayer.setFilterLamoish()
break
case 15:
//色调分离
this.$refs.refVideoPlayer.setFilterPosterize()
break
case 16:
//Barrel类型模糊
this.$refs.refVideoPlayer.setFilterBarrelBlur({
//模糊数量值
countLevel: 5
})
break
case 17:
//饱和度
this.$refs.refVideoPlayer.setFilterSaturation({
//值,-1 - 1
value: 0.8
})
break
case 18:
//怀旧
this.$refs.refVideoPlayer.setFilterSepia()
break
case 19:
//温度
this.$refs.refVideoPlayer.setFilterTemperature({
//值,0 - 1
value: 0.8
})
break
case 20:
//锐度
this.$refs.refVideoPlayer.setFilterSharpness({
//值,0 - 1
value: 0.8
})
break
case 21:
//色调
this.$refs.refVideoPlayer.setFilterTint({
//颜色值
color: "#00FF00"
})
break
case 22:
//晕影
this.$refs.refVideoPlayer.setFilterVignette({
//值 0 - 1.0
value: 0.8
})
break
case 23:
//重叠
this.$refs.refVideoPlayer.setFilterOverlay({
//值 0 - 1.0
value: 0.0015
})
break
case 24:
//简单模糊
this.$refs.refVideoPlayer.setFilterSampleBlur({
//值 1 - 10.0
value: 4.0
})
break
case 25:
//高斯模糊
this.$refs.refVideoPlayer.setFilterGaussianBlur({
//值 1 - 10.0
radius: 6.0,
//类型,可选值:TYPEX,TYPEY,TYPEXY
type: "TYPEXY"
})
break
case 26:
//亮度
this.$refs.refVideoPlayer.setFilterBrightness({
//值 0 - 1.0
value: 0.8,
})
break
}
},
//自定义滤镜
customFilter() {
let shader = this.getCustomFilterShader();
this.$refs.refVideoPlayer.customFilter({
//滤镜处理内容
shader: shader,
})
},
//开始生成gif
startGif() {
this.$refs.refVideoPlayer.startGif()
},
//结束生成gif
stopGif() {
this.$refs.refVideoPlayer.stopGif()
},
//清除缓存
clearCache() {
this.$refs.refVideoPlayer.clearCache()
},
//获取所有音轨
getAllMediaTrack() {
this.$refs.refVideoPlayer.getAllMediaTrack()
},
//切换音轨
changeMediaTrack() {
try {
if (this.mediaTrackList.length == 0) {
throw new Error("无音轨");
}
let mediaInfo = this.mediaTrackList[this.mediaTrackIndex];
this.$refs.refVideoPlayer.changeMediaTrack({
//音轨的id
id: mediaInfo.id
})
} catch (e) {
uni.$lv.func.toast(e.message);
}
},
//开启或关闭弹幕
toogleDanmaku() {
if (this.config.danmakuParams.danmakuShow) {
//关闭弹幕
this.config.danmakuParams.danmakuShow = false;
this.$refs.refVideoPlayer.danmakuHide()
} else {
//开启弹幕
this.config.danmakuParams.danmakuShow = true;
this.$refs.refVideoPlayer.danmakuShow()
}
},
//添加弹幕
addDanmaku() {
//添加弹幕
this.$refs.refVideoPlayer.addDanmaku({
//文本
text: "这是一条刚刚发送的测试弹幕",
//内边距
padding: 5,
//弹幕优先级,0为低优先级,>0为高优先级不会被过滤器过滤
priority: 8,
//是否是直播弹幕
isLive: true,
//弹幕出现时间,弹幕当前时间延迟时间,单位:毫秒
time: 500,
//字体大小
textSize: 45,
//文本颜色
textColor: "#FF0000",
//阴影/描边颜色
textShadowColor: "#FFFFFF",
//边框的颜色
borderColor: "#00FF00"
})
},
// 系统错误
onError(e) {
this.writeLog("onError:" + JSON.stringify(e))
},
// 事件
onEvent(e) {
// let detail = e.detail;
// this.writeLog("onEvent:" + JSON.stringify(detail))
},
// 加载成功
onEventMethod(e) {
let detail = e.detail;
// this.writeLog("onEventMethod:" + JSON.stringify(detail))
let type = detail.type;
let data = detail.data;
if (type == "setScreenScaleType") {
//设置播放比例
if (this.$refs.refSelectSizePop) {
this.$refs.refSelectSizePop.close();
}
} else if (type == "getPlayerData") {
//获取播放属性
this.writeLog("onEventMethod:" + JSON.stringify(detail))
} else if (type == "setSpeed") {
this.$refs.refSpeedPop.close();
} else if (type == "taskShotPic") {
//视频截图
let path = data.data.path;
uni.showToast({
title: "图片保存地址:" + path,
duration: 5000,
icon: "none"
})
} else if (type == "isPlaying") {
console.log(data.data.isPlaying)
} else if (type == "fullScreen") {
//10秒后退出全屏
setTimeout(() => {
this.$refs.refVideoPlayer.quitFullScreen();
}, 10000)
} else if (type == "smallVideo") {
//10秒后退出小窗口
setTimeout(() => {
this.$refs.refVideoPlayer.quitSmallVideo();
}, 10000)
} else if (type == "getDuration") {
//获取视频时长
console.log(data.data.duration)
} else if (type == "getCurrentPosition") {
//当前播放位置
console.log(data.data.position)
} else if (type == "getBufferedPercentage") {
//获取当前缓冲百分比
console.log(data.data.process)
} else if (type == "getSize") {
//获取视频尺寸
console.log(data.data)
} else if (type == "startGif") {
//开始生成gif
console.log(data.data)
} else if (type == "stopGif") {
//结束生成gif
console.log(data.data)
} else if (type == "getAllMediaTrack") {
//获取所有音轨
this.mediaTrackList = data.data.list;
} else if (type == "changeMediaTrack") {
//切换音轨
this.mediaTrackIndex += 1;
if (this.mediaTrackIndex >= this.mediaTrackList.length) {
this.mediaTrackIndex = 0;
}
}
},
//自定义滤镜内容
getCustomFilterShader() {
//以反色为例
let shader = "#extension GL_OES_EGL_image_external : require\n";
shader += "precision mediump float;\n";
shader += "varying vec2 vTextureCoord;\n";
shader += "uniform samplerExternalOES sTexture;\n";
shader += "void main() {\n";
shader += " vec4 color = texture2D(sTexture, vTextureCoord);\n";
shader += " float colorR = (1.0 - color.r) / 1.0;\n";
shader += " float colorG = (1.0 - color.g) / 1.0;\n";
shader += " float colorB = (1.0 - color.b) / 1.0;\n";
shader += " gl_FragColor = vec4(colorR, colorG, colorB, color.a);\n";
shader += "}\n";
return shader;
},
// 写日志
writeLog(str) {
console.log(str);
// let logStr = uni.$lv.date.format(null, "yyyy-mm-dd hh:MM:ss") + " " + str + "\n";
// this.logStr = logStr + this.logStr;
}
}
}
</script>
<style>
.view-button {
background-color: #007aff;
border-radius: 5px;
height: 50px;
justify-content: center;
align-items: center;
margin-bottom: 5px;
}
.button-text {
color: #FFFFFF;
}
</style>vue
<template>
<!-- #ifdef APP -->
<scroll-view style="flex:1">
<!-- #endif -->
<view style="width: 750rpx; height: 300px; position: relative;">
<leven-uts-videoPlayer ref="refLevenPlayer" style="flex:1; height: 300px;" :configX="config" @onError="onError"
@onEvent="onEvent" @onEventMethod="onEventMethod">
</leven-uts-videoPlayer>
</view>
<rice-collapse v-model="collapseOpened">
<rice-collapse-item name="kernel" title="内核">
<rice-radio-group v-model="kernel" direction="row" @change="changeKernel">
<rice-radio :value="1" label="IJK"></rice-radio>
<rice-radio :value="2" label="EXO"></rice-radio>
<rice-radio :value="3" label="系统内核"></rice-radio>
</rice-radio-group>
</rice-collapse-item>
<rice-collapse-item name="url" title="播放地址">
<rice-input v-model="url" placeholder="请输入播放地址" @blur="changeUrl" />
</rice-collapse-item>
</rice-collapse>
<leven-ui-card title="组件方法">
<button type="primary" @click="addDanmaku">添加一条弹幕</button>
<button type="primary" @click="toogleDanmaku">开启/关闭弹幕</button>
<button type="primary" @click="changeMediaTrack">切换音轨</button>
<button type="primary" @click="getAllMediaTrack">获取所有音轨</button>
<button type="primary" @click="clearCache">清除缓存</button>
<button type="primary" @click="stopGif">结束生成gif</button>
<button type="primary" @click="startGif">开始生成gif</button>
<button type="primary" @click="customFilter">自定义滤镜</button>
<button type="primary" @click="setFilter">设置滤镜</button>
<button type="primary" @click="setTransform">镜像翻转</button>
<button type="primary" @click="setRotation">镜像旋转</button>
<button type="primary" @click="getSize">获取视频的尺寸</button>
<button type="primary" @click="getBufferedPercentage">获取当前缓冲百分比</button>
<button type="primary" @click="getCurrentPosition">获取当前播放的位置</button>
<button type="primary" @click="getDuration">获取视频时长</button>
<button type="primary" @click="setMute">设置是否静音播放</button>
<button type="primary" @click="smallVideo">小窗口播放</button>
<button type="primary" @click="fullScreen">全屏播放</button>
<button type="primary" @click="isPlaying">是否播放中</button>
<button type="primary" @click="taskShotPic">视频截图</button>
<button type="primary" @click="popOpen('setSpeed', '设置播放倍速')">倍速播放</button>
<button type="primary" @click="seekTo">设置播放进度</button>
<button type="primary" @click="setVolume">播放音量</button>
<button type="primary" @click="getPlayerData">获取播放属性</button>
<button type="primary" @click="popOpen('setScreenScaleType', '设置播放比例')">播放比例</button>
<button type="primary" @click="stop">停止播放</button>
<button type="primary" @click="play">开始播放</button>
<button type="primary" @click="pause">暂停播放</button>
<button type="primary" @click="resume">继续播放</button>
</leven-ui-card>
<rice-popup v-model:show="popShow">
<view class="popup-contaner">
<view class="popup-contaner-title">{{popTitle}}</view>
<view class="popup-contaner-content">
<template v-if="popType == 'setScreenScaleType'">
<rice-radio-group v-model="size" direction="row" @change="changeSize">
<rice-radio v-for="(item, index) in sizeList" :key="index" :value="item.value"
:label="item.text"></rice-radio>
</rice-radio-group>
</template>
<template v-else-if="popType == 'setSpeed'">
<rice-radio-group v-model="speed" direction="row" @change="changeSpeed">
<rice-radio v-for="(item, index) in speedList" :key="index" :value="item.value"
:label="item.text"></rice-radio>
</rice-radio-group>
</template>
</view>
</view>
</rice-popup>
<!-- #ifdef APP -->
</scroll-view>
<!-- #endif -->
</template>
<script lang="uts" setup>
import JSONObject from 'com.alibaba.fastjson.JSONObject'
//组件初始化配置
const config = ref({
//播放地址,rtmp://liteavapp.qcloud.com/live/liteavdemoplayerstreamid
//http://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear1/prog_index.m3u8
//rtsp://rtspstream:effd2f46af6aef62a77b62104ceafbc0@zephyr.rtsp.stream/movie
//http://alvideo.ippzone.com/zyvd/98/90/b753-55fe-11e9-b0d8-00163e0c0248
// url: "http://vod.ulunix.cn/media_hls/X6-1-wAD-1yQ7R2q-bCJbio780yeu41irzHjQdxj0K42NQp24MULgIW8skzG9y2Cb_C7H3eq1BJFtf2exyVNUP6y69Y80TK7tNV0lCk3TcTiYq0Dmv4Sy2Yly6ZzRGECdsWtL6-fxe2ES3iUQKVtwZubE-ZG6tqe919YIlic2Soc1c1c1c1.m3u8",
//https://res.exexm.com/cw_145225549855002
//https://aliyuncdnsaascloud.xjhktv.com/video/A%20Lin%2B%E5%80%AA%E5%AD%90%E5%86%88-%E4%B8%8D%E5%B1%91%E5%AE%8C%E7%BE%8E%5B%E5%9B%BD%5D%5B1080P%5D.mp4
url: "https://aliyuncdnsaascloud.xjhktv.com/video/A%20Lin%2B%E5%80%AA%E5%AD%90%E5%86%88-%E4%B8%8D%E5%B1%91%E5%AE%8C%E7%BE%8E%5B%E5%9B%BD%5D%5B1080P%5D.mp4",
//播放器预览背景图片,支持网络地址
//http://www.yeyuboke.com/svga/image_default.jpg
backgroundImage: "",
//视频帧背景图片,以视频帧作为图片,单位:微秒
frame: 1000000,
//视频帧图片加载失败显示的图片,需放置到res/mipmap中
error: "error",
//图片预加载资源图片,需放置到res/mipmap中
placeholder: "placeholder",
//是否边播放边缓存
cacheWithPlay: true,
//标题是否显示
titleVisible: false,
//视频标题
title: "安卓高质量视频播放器原生插件",
//返回按钮是否显示
backButtonVisible: false,
//是否可以滑动界面改变进度,声音等
isTouchWidget: true,
//是否需要流量提示
needShowWifiTip: true,
//是否循环播放
loop: false,
//是否显示底部控制条
bottomContainer: true,
//是否显示开始播放按钮
startButtonVisible: false,
//开始播放位置,目前有时候前几秒有跳动问题,毫秒
startPosition: 0,
//请求头信息
header: {
ee: "333",
allowCrossProtocolRedirects: "true",
"User-Agent": "LEVEN"
},
//是否开启硬解码
enableMediaCodec: false,
//是否开启硬解码渲染优化
isMediaCodecTexture: false,
//视频播放比例,可选值:
//SCREEN_TYPE_DEFAULT,SCREEN_TYPE_16_9,SCREEN_TYPE_4_3
//SCREEN_TYPE_18_9,SCREEN_TYPE_FULL,SCREEN_MATCH_FULL
scaleType: "SCREEN_TYPE_DEFAULT",
//播放模式,可选值:GLSURFACE:GLSurfaceView 主要用于OpenGL渲染的,如果支持滤镜,必须选择此模式,SURFACE:SurfaceView,与动画全屏的效果不是很兼容,TEXTURE:TextureView,默认
renderType: "GLSURFACE",
//水印图片,只支持本地图片,需放置到res/mipmap下
waterImage: {
//图片名称,不需要加扩展名
image: "uni_icon",
//图片宽度
width: 100,
//图片高度
height: 100,
//透明度
alpha: 0.6,
//水印位置,0:右上角,1.右下角,2.左上角,3.左下角,4.居中,5.右中,6.上中,7.下中,8.左中
position: 3,
//位置偏移量,默认:1.0
offset: 1.5
},
//默认播放内核,可选值:1.IJK内核,2.EXO内核,3.系统内核
kernel: 2,
//是否静音播放
isMute: false,
//gif的帧之间延时,默认:0
delay: 0,
//生成gif采样率,默认:1
sampleSize: 1,
//生成gif缩放比例,默认:5
scaleSize: 5,
//生成gif截图频率,毫秒,默认:50
frequencyCount: 50,
//弹幕配置
danmakuParams: {
//是否开启弹幕
danmakuShow: true,
//初始化弹幕文件,xml文件,如果是raw文件的话不需要加扩展名,其他需要加上扩展名
//http://www.yeyuboke.com/uniplugin/player/danmaku.xml
///storage/emulated/0/Download/WeiXin/danmaku.xml
danmakuFile: "comments",
//弹幕文件类型,url:网络地址,path:本地路径,raw:raw文件
danmakuFileType: "raw",
//最大显示行数
maxLines: 3,
//防弹幕重叠
preventOverlapping: true,
//描边样式
danmakuStyle: {
//样式,可选值:
//DANMAKU_STYLE_DEFAULT:自动
//DANMAKU_STYLE_NONE:无
//DANMAKU_STYLE_SHADOW:阴影
//DANMAKU_STYLE_STROKEN:描边(默认)
//DANMAKU_STYLE_PROJECTION:投影
style: "DANMAKU_STYLE_STROKEN",
//描边值,DANMAKU_STYLE_SHADOW 阴影模式下,values传入阴影半径
//DANMAKU_STYLE_STROKEN 描边模式下,values传入描边宽度
//DANMAKU_STYLE_PROJECTION 投影模式下,values传入offsetX, offsetY, alpha offsetX/offsetY: x/y 方向上的偏移量 alpha: 投影透明度 [0...255]
values: [3]
},
//是否启用合并重复弹幕,默认:true
duplicateMergingEnabled: true,
//设置弹幕滚动速度系数,只对滚动弹幕有效,默认:1.0
scrollSpeedFactor: 1.2,
//设置弹幕文本大小,默认:1.0
scaleTextSize: 1.2
},
//加载完成是否自动播放
autoPlay: true
})
//选择的内核
const kernel = ref(2)
//折叠面板展开状态
const collapseOpened = ref(['kernel', 'url'])
//输入的播放地址
const url = ref("https://aliyuncdnsaascloud.xjhktv.com/video/A%20Lin%2B%E5%80%AA%E5%AD%90%E5%86%88-%E4%B8%8D%E5%B1%91%E5%AE%8C%E7%BE%8E%5B%E5%9B%BD%5D%5B1080P%5D.mp4")
//组件引用
const refLevenPlayer = ref<LevenUtsVideoPlayerElement | null>(null)
//弹窗展示状态
const popShow = ref(false)
//弹出层标题
const popTitle = ref("")
//弹出层类型
const popType = ref("")
//播放比例列表
const sizeList = [{
text: "默认",
value: "SCREEN_TYPE_DEFAULT"
}, {
text: "16:9",
value: "SCREEN_TYPE_16_9"
}, {
text: "4:3",
value: "SCREEN_TYPE_4_3"
}, {
text: "18:9",
value: "SCREEN_TYPE_18_9"
}, {
text: "全屏",
value: "SCREEN_TYPE_FULL"
}, {
text: "全屏拉伸",
value: "SCREEN_MATCH_FULL"
}]
//当前选择的播放比例
const size = ref("SCREEN_TYPE_DEFAULT")
//倍速播放列表
const speedList = [{
text: "0.5倍",
value: 0.5
}, {
text: "0.75倍",
value: 0.75
}, {
text: "正常倍速",
value: 1
}, {
text: "1.5倍",
value: 1.5
}, {
text: "2倍",
value: 2
}];
//当前选择的倍速播放
const speed = ref(1)
//翻转类型
const transform = ref(0)
//滤镜
const filterValue = ref(0)
//自定义滤镜内容
const CUSTOM_FILTER_CONTENT = '#extension GL_OES_EGL_image_external : require\n'
+ 'precision mediump float;\n'
+ 'varying vec2 vTextureCoord;\n'
+ 'uniform samplerExternalOES sTexture;\n'
+ 'void main() {\n'
+ ' vec4 color = texture2D(sTexture, vTextureCoord);\n'
+ ' float colorR = (1.0 - color.r) / 1.0;\n'
+ ' float colorG = (1.0 - color.g) / 1.0;\n'
+ ' float colorB = (1.0 - color.b) / 1.0;\n'
+ ' gl_FragColor = vec4(colorR, colorG, colorB, color.a);\n'
+ '}\n';
//音轨列表
const mediaTrackList = ref<UTSJSONObject[] | null>(null)
//当前音轨索引
const mediaTrackIndex = ref(0)
//添加弹幕
function addDanmaku() {
let options = {
//文本
text: "这是一条刚刚发送的测试弹幕",
//内边距
padding: 5,
//弹幕优先级,0为低优先级,>0为高优先级不会被过滤器过滤
priority: 8,
//是否是直播弹幕
isLive: true,
//弹幕出现时间,弹幕当前时间延迟时间,单位:毫秒
time: 500,
//字体大小
textSize: 45,
//文本颜色
textColor: "#FF0000",
//阴影/描边颜色
textShadowColor: "#FFFFFF",
//边框的颜色
borderColor: "#00FF00"
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.addDanmaku(params);
}
//开启/关闭弹幕
function toogleDanmaku() {
let danmakuParams = config.value.get("danmakuParams") as UTSJSONObject
let danmakuShow = danmakuParams.get("danmakuShow") as boolean
danmakuParams.set("danmakuShow", !danmakuShow)
config.value.set("danmakuParams", danmakuParams)
if (danmakuShow) {
//关闭弹幕
refLevenPlayer.value?.danmakuHide();
} else {
//开启弹幕
refLevenPlayer.value?.danmakuShow();
}
}
//切换音轨
function changeMediaTrack() {
try {
if (mediaTrackList.value == null || mediaTrackList.value.length == 0) {
throw new Error("暂无音轨");
}
let mediaInfo = mediaTrackList.value![mediaTrackIndex.value];
let options = {
//音轨的id
id: mediaInfo.get("id")
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.changeMediaTrack(params);
} catch (e : Error) {
uni.showToast({
title: e.message,
icon: "none"
})
}
}
//获取所有音轨
function getAllMediaTrack() {
refLevenPlayer.value?.getAllMediaTrack();
}
//清除缓存
function clearCache() {
refLevenPlayer.value?.clearCache();
}
//结束生成gif
function stopGif() {
refLevenPlayer.value?.stopGif();
}
//开始生成gif
function startGif() {
refLevenPlayer.value?.startGif();
}
//自定义滤镜
function customFilter() {
let options = {
//滤镜处理内容
shader: CUSTOM_FILTER_CONTENT,
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.customFilter(params);
}
//设置滤镜
function setFilter() {
filterValue.value += 1;
if (filterValue.value > 26) {
filterValue.value = 0;
}
switch (filterValue.value) {
case 0:
//清除滤镜
refLevenPlayer.value?.clearFilter();
break
case 1:
//自动修正
let options = {
//修正值,0-1
scale: 0.8
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterAutoFix(params);
break;
case 2:
//马赛克
let options = {
//马赛克大小,1-100
pixel: 40
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterPixelation(params);
break
case 3:
//黑白滤镜
refLevenPlayer.value?.setFilterBlackAndWhite();
break
case 4:
//对比度
let options = {
//对比度值,0.1-2.0
contrast: 0.8
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterContrast(params);
break
case 5:
//交叉线
refLevenPlayer.value?.setFilterCrossProcess();
break
case 6:
//纪录片
refLevenPlayer.value?.setFilterDocumentary();
break
case 7:
//双色调
let options = {
firstColor: "#0000FF",
secondColor: "#FFFF00"
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterDuotone(params);
break
case 8:
//补光
let options = {
//光强度,0.0 - 1.0
strength: 0.8
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterFillLight(params);
break
case 9:
//伽马线
let options = {
//值,0.0 - 2.0
value: 0.8
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterGamma(params);
break
case 10:
//纹理
let options = {
//强度值,0.0 - 1.0
strength: 0.8
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterGrain(params);
break
case 11:
//灰度
refLevenPlayer.value?.setFilterGrayscale();
break
case 12:
//色度
let options = {
//值,0.0 - 1.0
value: 0.8
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterHue(params);
break
case 13:
//反色
refLevenPlayer.value?.setFilterInvertColors();
break
case 14:
//简单风格
refLevenPlayer.value?.setFilterLamoish();
break
case 15:
//色调分离
refLevenPlayer.value?.setFilterPosterize();
break
case 16:
//Barrel类型模糊
let options = {
//模糊数量值
countLevel: 5
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterBarrelBlur(params);
break
case 17:
//饱和度
let options = {
//值,-1 - 1
value: 0.8
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterSaturation(params);
break
case 18:
//怀旧
refLevenPlayer.value?.setFilterSepia();
break
case 19:
//温度
let options = {
//值,0 - 1
value: 0.8
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterTemperature(params);
break
case 20:
//锐度
let options = {
//值,0 - 1
value: 0.8
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterSharpness(params);
break
case 21:
//色调
let options = {
//颜色值
color: "#00FF00"
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterTint(params);
break
case 22:
//晕影
let options = {
//值 0 - 1.0
value: 0.8
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterVignette(params);
break
case 23:
//重叠
let options = {
//值 0 - 1.0
value: 0.0015
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterOverlay(params);
break
case 24:
//简单模糊
let options = {
//值 1 - 10.0
value: 4.0
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterSampleBlur(params);
break
case 25:
//高斯模糊
let options = {
//值 1 - 10.0
radius: 6.0,
//类型,可选值:TYPEX,TYPEY,TYPEXY
type: "TYPEXY"
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterGaussianBlur(params);
break
case 26:
//亮度
let options = {
//值 0 - 1.0
value: 0.8,
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setFilterBrightness(params);
break
}
}
//镜像翻转
function setTransform() {
transform.value += 1;
if (transform.value > 2) {
transform.value = 0;
}
console.log(transform.value)
let options = {
//翻转类型,0:正常,1.上下翻转,2.左右翻转
transform: transform.value
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setTransform(params);
}
//镜像旋转
function setRotation() {
let options = {
rotation: 90
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setRotation(params);
}
//获取视频尺寸
function getSize() {
refLevenPlayer.value?.getSize();
}
//获取当前缓冲百分比
function getBufferedPercentage() {
refLevenPlayer.value?.getBufferedPercentage();
}
//获取当前播放位置
function getCurrentPosition() {
refLevenPlayer.value?.getCurrentPosition();
}
//获取视频时长
function getDuration() {
refLevenPlayer.value?.getDuration();
}
//是否静音播放
function setMute() {
let isMute : boolean = config.value.get("isMute") as boolean
config.value.set("isMute", !isMute)
let options = {
//小窗口大小
value: !isMute
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setMute(params);
}
//小窗口播放
function smallVideo() {
let options = {
//小窗口大小
size: [150, 150]
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.smallVideo(params);
}
//全屏播放
function fullScreen() {
refLevenPlayer.value?.fullScreen();
}
//是否播放中
function isPlaying() {
refLevenPlayer.value?.isPlaying();
}
//视频截图
function taskShotPic() {
refLevenPlayer.value?.taskShotPic();
}
//倍速播放
function changeSpeed(value : number) {
let options = {
value: value
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setSpeed(params);
}
//播放进度
function seekTo() {
let options = {
//播放进度,单位:毫秒
position: 30000
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.seekTo(params);
}
//播放音量
function setVolume() {
let options = {
//音量取值范围:0.0-1.0
left: 0.3,
right: 0.3
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setVolume(params);
}
//获取播放属性
function getPlayerData() {
refLevenPlayer.value?.getPlayerData();
}
//选择播放比例
function changeSize(value : string) {
let options = {
value: value
};
let params : JSONObject = JSONObject.parse(JSON.stringify(options)) as JSONObject
refLevenPlayer.value?.setScreenScaleType(params);
}
//显示弹窗
function popOpen(type : string, title : string) {
popTitle.value = title
popType.value = type
popShow.value = true
}
//内核的改变事件
function changeKernel(value : number) {
config.value.set("kernel", value)
}
//播放地址改变事件
function changeUrl() {
config.value.set("url", url.value)
}
//继续播放
function resume() {
refLevenPlayer.value?.resume();
}
//暂停播放
function pause() {
refLevenPlayer.value?.pause();
}
//开始播放
function play() {
let params : JSONObject = JSONObject.parse(JSON.stringify(config.value)) as JSONObject
refLevenPlayer.value?.play(params);
}
//停止播放
function stop() {
refLevenPlayer.value?.stop();
}
//错误事件
function onError(e : JSONObject) {
console.log(e)
}
//事件
function onEvent(e : JSONObject) {
// console.log(e)
}
//方法事件
function onEventMethod(e : JSONObject) {
// console.log(e)
//类型
let type : string = e.getString("type");
//数据
let data : JSONObject = e.getJSONObject("data");
//状态
let code : number = data.getInteger("code");
//实际数据
let resultData : JSONObject = data.getJSONObject("data");
//错误消息提示
let message : string = data.getString("message");
if (code != 0) {
uni.showToast({
title: message,
icon: "none"
})
return;
}
if (type == "getPlayerData") {
// console.log(resultData)
} else if (type == "taskShotPic") {
//视频截图
// console.log(resultData)
let path : string = resultData.getString("path");
uni.showToast({
title: "图片保存地址:" + path,
duration: 5000,
icon: "none"
})
} else if (type == "isPlaying") {
//是否播放中
let isPlaying = resultData.getBoolean("isPlaying");
console.log(isPlaying)
} else if (type == "fullScreen") {
//全屏播放
setTimeout(() => {
//退出全屏
refLevenPlayer.value?.quitFullScreen();
}, 5000)
} else if (type == "smallVideo") {
//小窗口播放
setTimeout(() => {
//退出小窗口
refLevenPlayer.value?.quitSmallVideo();
}, 5000)
} else if (type == "getDuration") {
//获取视频时长
// console.log(resultData)
let duration : number = resultData.getInteger("duration");
console.log(duration)
} else if (type == "getCurrentPosition") {
//获取当前播放位置
console.log(resultData)
} else if (type == "getBufferedPercentage") {
//获取当前缓冲百分比
console.log(resultData)
} else if (type == "getSize") {
//获取视频尺寸
console.log(resultData)
} else if (type == "setTransform") {
//镜像翻转
console.log(data)
} else if (type == "startGif") {
//开始生成gif
console.log(resultData)
} else if (type == "stopGif") {
//结束生成gif
console.log(resultData)
} else if (type == "getAllMediaTrack") {
//获取所有音轨
let resultDataJson : UTSJSONObject = JSON.parse(resultData.toJSONString()) as UTSJSONObject
mediaTrackList.value = resultDataJson.getArray("list") as UTSJSONObject[];
} else if (type == "changeMediaTrack") {
//切换音轨
mediaTrackIndex.value += 1
if (mediaTrackList.value != null && mediaTrackIndex.value >= mediaTrackList.value.length) {
mediaTrackIndex.value = 0;
}
}
}
</script>
<style lang="scss">
.popup-contaner {
background-color: #FFFFFF;
border-radius: 8px 8px 0 0;
&-title {
padding: 16px;
border-bottom: 1px solid #f2f2f2;
flex-direction: row;
justify-content: center;
align-items: center;
}
&-content {
padding: 16px;
max-height: 500px;
}
}
</style>