更新记录
1.0.0(2026-10-30)
- VLC 视频播放器组件(Android / nvue)
- 支持网络流(rtsp / rtmp / http-flv / hls)、本地文件、assets 资源播放
- 提供 play / pause / resume / stop / setVolume / setTime / setRate / setVideoScale / getPlayerData / isPlaying / takeSnapShot / startRecording / stopRecording / changeScreenDirection / checkMediaValid / checkPermissions / requestPermissions / release / setConfig 等方法
- 提供 onPlayStatus / onError / onResult 事件
平台兼容性
uni-app(4.72)
| Vue2 | Vue2插件版本 | Vue3 | Vue3插件版本 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.0.0 | √ | 1.0.0 | × | × | × | × | × | × | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
其他
| 多语言 | 暗黑模式 | 宽屏模式 | 蒸汽模式 |
|---|---|---|---|
| × | × | √ | × |
zy-vlc-play
基于VLC的安卓视频播放器 UTS 原生组件,支持网络流(rtsp / rtmp / http-flv / hls)、本地文件、assets 资源,延迟低,提供播放控制、倍速、音量、进度、画面比例、截图、录制、全屏切换和播放源有效性检测。
平台支持
- uni-app(app-android / nvue 页面)
- 组件只能在
nvue页面中使用,不支持vue页面 - 需自定义基座或云打包验证制作自定义基座,标准基座不包含该库。
权限
android.permission.INTERNET
android.permission.ACCESS_NETWORK_STATE
android.permission.READ_EXTERNAL_STORAGE
android.permission.WRITE_EXTERNAL_STORAGE
截图、录像默认保存到应用外部私有目录(
getExternalFilesDir()/zyVlcPlay/pictures|videos),不需要存储权限;只有显式指定imageDir/videoDir到公共目录时才需要存储权限。
基础用法
<template>
<view style="flex:1">
<zy-vlc-play ref="player" style="flex:1;height:400rpx" @onPlayStatus="onPlayStatus" @onError="onError"
@onResult="onResult"></zy-vlc-play>
</view>
</template>
<script>
export default {
onReady() {
// 组件挂载后下发配置,带 url 且 isAutoPlay 不为 false 时自动播放
this.$refs.player.setConfig({
url: 'https://example.com/demo.mp4',
isAutoPlay: true,
useSurfaceView: false,
fullScreenIsLandscape: true,
scaleType: 'SURFACE_BEST_FIT'
})
},
methods: {
onPlayStatus(e) { console.log('播放状态', e) },
onError(e) { console.log('错误', e) },
onResult(e) { console.log('方法结果', e) }
}
}
</script>
调用组件方法:
this.$refs.player.play({ url: 'rtsp://127.0.0.1/live/test' })
this.$refs.player.pause()
配置项(setConfig 参数 / play 参数)
| 字段 | 类型 | 说明 |
|---|---|---|
| url | string | 播放地址(必传,本地路径、网络地址、assets 内的相对路径) |
| isAutoPlay | boolean | 应用配置后是否自动播放,默认 true |
| sourceType | string | URL(默认)/ PATH(本地绝对路径)/ ASSETS(assets 内文件) |
| options | string[] | LibVLC 实例参数,如 ["--network-caching=300"] |
| mediaOptions | string[] | Media 参数(media.addOption) |
| decoderEnabled | boolean | 是否启用硬解码(setHWDecoderEnabled),默认不设置 |
| decoderForce | boolean | 是否强制硬解码,默认 false |
| time | number | 起播/续播位置(毫秒) |
| scaleType | string | 画面比例,见下文取值 |
| useSurfaceView | boolean | 是否使用 SurfaceView,默认 false(TextureView,支持截图/动画) |
| fullScreenIsLandscape | boolean | 全屏时是否强制横屏,默认 false |
| imageDir | string | 截图保存目录,需以 / 结尾或自动补 |
| videoDir | string | 录像保存目录,需以 / 结尾或自动补 |
scaleType 取值:SURFACE_BEST_FIT(默认,等比适应)、SURFACE_FIT_SCREEN(等比撑满并缩放)、SURFACE_FILL(拉伸铺满)、SURFACE_16_9、SURFACE_4_3、SURFACE_ORIGINAL(原始尺寸)。
方法
所有方法都是异步的,结果统一通过 onResult 事件回传:
{ type: '方法名', code: 0, msg: '提示信息', data: { ... } }
code == 0 表示成功,其余为失败。
| 方法 | 参数 | 说明 | 成功时 data |
|---|---|---|---|
| play | { url, sourceType?, options?, mediaOptions?, decoderEnabled?, decoderForce?, time?, scaleType? } |
播放(重新创建 LibVLC 实例) | — |
| pause | — | 暂停 | — |
| resume | — | 继续播放 | — |
| stop | — | 停止播放 | — |
| setVolume | { volume } |
音量 0-100 | — |
| setTime | { time } |
跳转到指定位置(毫秒,超出时长自动截断) | — |
| setRate | { rate } |
播放倍速,如 0.5 / 1 / 2 | — |
| setVideoScale | { scaleType } |
设置画面比例 | — |
| getPlayerData | — | 获取播放属性 | { url, scaleType, isPlaying, vlcVersion, volume, length, time, width, height } |
| isPlaying | — | 是否正在播放 | { isPlaying } |
| takeSnapShot | — | 截图 | { path } |
| startRecording | — | 开始录制(写入 videoDir) | — |
| stopRecording | — | 结束录制 | { path } |
| changeScreenDirection | — | 全屏/退出全屏切换 | — |
| checkMediaValid | { url } |
检测播放源是否可用(最大等待 3 秒) | { isValid } |
| checkPermissions | permissions?: string[] |
检查运行时权限,不传时按 targetSdkVersion 自动选择 | { granted, deniedPermissions } |
| requestPermissions | permissions?: string[] |
申请运行时权限(弹系统对话框;结果回调由框架托管),不传时按 targetSdkVersion 自动选择 | { granted, deniedPermissions, doNotAskAgain } |
| release | — | 释放播放器资源 | — |
| setConfig | config 对象 | 应用配置(带 url 且 isAutoPlay 时自动播放,见上文配置项) | — |
checkMediaValid 播放源无效时 code = -103;其余失败 code = -1。
事件
| 事件 | 参数 | 说明 |
|---|---|---|
| onPlayStatus | { status, length, time } |
播放器状态回调,status 取值:Opening、Buffering、Playing、Paused、Stopped、EndReached、EncounteredError、TimeChanged、LengthChanged、PositionChanged、SeekableChanged、PausableChanged、MediaChanged、Vout、ESAdded、ESDeleted、ESSelected、RecordChanged |
| onError | { code, msg } |
播放器内部错误 |
| onResult | { type, code, msg, data } |
方法调用结果 |
nvue 里事件参数取值(必读)
$emit 出来的对象在 nvue 里是 UTS 代理对象({ dynamicJSONFields: {...}, jSONArray: false }),且 nvue 自定义组件回调拿到的是 weex 事件对象,真实内容在 e.detail 里。直接 e.type / e.detail.type 都取不到值,需要还原:
function unwrapUTS(obj) {
if (obj === null || obj === undefined) return obj
if (typeof obj !== 'object') return obj
if (Array.isArray(obj)) return obj.map(unwrapUTS)
if (obj.dynamicJSONFields !== undefined) {
const fields = obj.dynamicJSONFields
if (obj.jSONArray === true) {
return Object.keys(fields).map(function (key) { return unwrapUTS(fields[key]) })
}
return unwrapUTS(fields)
}
const result = {}
Object.keys(obj).forEach(function (key) { result[key] = unwrapUTS(obj[key]) })
return result
}
// 用法
onResult(e) { const payload = unwrapUTS(e.detail) }, // { type, code, msg, data }
onPlayStatus(e) { const data = unwrapUTS(e.detail) }, // { status, length, time }
onError(e) { const data = unwrapUTS(e.detail) } // { code, msg }
权限
插件 config.json 已声明:
android.permission.INTERNET // 安装时权限,网络播放自动授予,无需申请
android.permission.ACCESS_NETWORK_STATE // 安装时权限
android.permission.READ_EXTERNAL_STORAGE // Android 6+ 危险权限,按需申请
android.permission.WRITE_EXTERNAL_STORAGE// Android 6+ 危险权限,按需申请
- 默认播放网络流、播放应用私有目录文件、默认目录(
Android/data/<包名>/files/zyVlcPlay/...)截图录像,都不需要运行时权限。 - 只有把
imageDir/videoDir指到公共目录(如/storage/emulated/0/Pictures/...)时才需要存储权限;Android 13+ 这两个权限已失效,建议改用MediaStore或应用私有目录。 checkPermissions/requestPermissions不传permissions时按 targetSdkVersion 自动选择:<=29申请读写存储、30~32只申请读、>=33不申请(直接返回已授予)。注意 targetSdk ≥ 33 时显式传READ_EXTERNAL_STORAGE会被系统框架拒绝(IllegalArgumentException),此时应改用READ_MEDIA_IMAGES/READ_MEDIA_VIDEO或继续使用应用私有目录。- 需要时用组件方法申请,结果走
onResult:
// 检查(不传则按 targetSdkVersion 自动选择)
this.$refs.player.checkPermissions(null)
// 申请(权限结果回调由框架托管,插件不接管 onRequestPermissionsResult)
this.$refs.player.requestPermissions([
'android.permission.READ_EXTERNAL_STORAGE',
'android.permission.WRITE_EXTERNAL_STORAGE'
])
onResult(e) {
const payload = unwrapUTS(e.detail)
if (payload.type == 'requestPermissions') {
if (!payload.data.granted) {
// payload.data.deniedPermissions 为被拒项;payload.data.doNotAskAgain 为 true 时需引导去系统设置
}
}
}

收藏人数:
购买源码授权版(
试用
使用 HBuilderX 导入示例项目
赞赏(0)
下载 62
赞赏 0
下载 12729937
赞赏 1959
赞赏
京公网安备:11010802035340号