更新记录

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 时需引导去系统设置
        }
    }
}

隐私、权限声明

1. 本插件需要申请的系统权限列表:

"android.permission.INTERNET", "android.permission.ACCESS_NETWORK_STATE", "android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE"

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

插件不采集任何数据

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

无

暂无用户评论。