更新记录

5.1.0(2026-09-01)

新增功能

  • 新增 Seek 模式选择:支持精确模式(Accurate)与快速模式(Inaccurate)两种 Seek 策略,接入方可按需选择,兼顾精度与响应速度
  • 新增播放器日志级别控制(setPlayerLogLevel),生产环境可一键降噪,仅输出关键日志
  • 新增 iOS 端下载通知管理:下载进度与完成/失败通知实时推送,与 Android 体验对齐
  • 新增 Android 端延迟创建机制:播放器实例按需创建,减少页面启动耗时,提升起播速度

体验优化

  • Android 小窗/画中画稳定性全面增强:引入确定性准入机制,系统拒绝后自动降级应用内浮窗,能力恢复后自动回升,消除"时拒时成" 的随机体验
  • Android 浮窗关闭逻辑优化:关窗即结束播放,避免资源残留
  • iOS 手势快进快退体验与 Android 完全对齐:灵敏度随时长自适应、基准位置锁定、进度条拖动防抖
  • 封面加载中断处理优化:快速切集时及时取消前一次封面请求,避免旧封面覆盖新封面
  • Android 事件载荷传输机制优化:事件数据传递更稳定、更完整

问题修复

  • 修复画中画模式下播放/暂停、快进快退按钮不显示或点击无响应的问题
  • 修复画中画模式下快进快退导致 UI 闪烁的问题
  • 修复 Android 浮窗态播放被意外暂停的问题:离屏暂停守卫补全小窗接管感知,浮窗全程持续播放
  • 修复 Android 纯音频模式下封面截取不显示的问题
  • 修复 Android 端播放器线程安全问题
  • 修复锁屏/息屏时播放器自动进入小窗的问题
  • 修复 iOS 全屏态进入画中画后停留横屏的问题
  • 修复 iOS 定时关闭选择"播完当前"不生效的问题
  • 修复 iOS 更多菜单及弹层按钮无法点击的问题
  • 修复播放器实例切换时 viewready 事件发射异常的问题
  • 修复竖屏模式下进度条拖动失效的问题
  • 修复悬浮窗关闭逻辑异常:现关窗即结束播放,行为符合预期
  • 修复 Android 端播放器 ID 重复注册导致事件异常的问题

环境要求

项目 要求
HBuilderX 3.99+
Android 8.0+(API 26,画中画要求)
iOS 13.0+(系统画中画需 iOS 15+)
打包方式 自定义调试基座 / 云打包正式包(不支持标准基座)
License 阿里云播放器 SDK 7.0.0+ 需配置 LicenseKey 与证书,详见 readme「License 配置」章节


平台兼容性

uni-app(3.99)

Vue2 Vue3 Chrome Safari app-vue app-nvue Android Android插件版本 iOS iOS插件版本 鸿蒙
- - - - - - 8.0 5.1.0 13 5.1.0 -
微信小程序 支付宝小程序 抖音小程序 百度小程序 快手小程序 京东小程序 鸿蒙元服务 QQ小程序 飞书小程序 小红书小程序 快应用-华为 快应用-联盟
- - - - - - - - - - - -

阿里云播放器SDK(ApsaraVideo Player)

uni-app 版阿里云播放器组件:基于 ApsaraVideo Player SDK 封装的 UTS 插件(组件 + 模块混合形态),Android / iOS 双端能力对齐。 内置企业级控制栏与手势交互,提供小窗播放、投屏、后台播放、纯音频、倍速、定时关闭、下载等开箱即用的播放能力。 仅支持 App 端(Android + iOS),H5 / 小程序请使用阿里云官方 Web 播放器。

核心接入方式:

  1. 在模板中放置 <ali-player-view> 组件(承载视频渲染 + 内置控制栏)
  2. 通过 Props 设置播放源(src / vid + playAuth / vid + STS)和参数
  3. 通过 ref 调用组件方法(prepare()play()seekTo() 等)
  4. 事件通过组件的 @ready / @play / @ended 等回调接收(双端事件负载统一使用 detail 键包裹,业务层通过 e.detail || e 提取)
  5. 竖屏返回按钮通过 @back 事件通知 Vue 层(通常执行 uni.navigateBack()

目录


功能概览

功能类别 支持能力
播放方式 URL 直播/点播、VidAuth(推荐)、VidSts
视频格式 MP4、HLS (M3U8)、FLV、RTMP、RTS 超低延时直播
播放控制 播放/暂停/停止/Seek/重加载/续播
画面控制 缩放模式、旋转、镜像
音频控制 音量、静音
内置控制栏 播放/暂停、进度条、全屏切换、倍速、纯音频、画中画、返回
“更多”抽屉 分享/收藏/倍速/定时关闭/下载,条目与顺序可配置(moreActions
倍速播放 弹层宫格 + 自定义滑杆(0.5~4.0),预设档位可配置(speedPresets
定时关闭 不开启/播完当前/倒计时,倒计时档位可配置(sleepTimerPresets
视频下载 vid 源走阿里云 SDK 下载器;URL 源插件自实现 HTTP 下载(m3u8 逐分片合并 .ts)
UI 定制 主题色 themeColor 一键换色、全部内置文案 texts 可覆盖(多语言)
画中画(PiP) Android 8.0+ / iOS 15+ 系统级画中画,画面自适应、进出过渡自然
小窗播放 统一入口 enterSmallWindow():Android 腾讯视频式分层浮窗(系统画中画 + 应用内浮窗兜底),iOS 系统画中画,支持离开 App 自动起窗
投屏 Android DLNA/UPnP(设备搜索 + URL 推送)、iOS 系统 AirPlay
熄屏/锁屏播放 Android WakeLock + AudioFocus、iOS AVAudioSession 后台音频
后台播放(Android) 后台保活、媒体通知栏 + 锁屏 MediaSession 控制、后台自动切纯音频
纯音频模式 听视频功能(仅播放音频不渲染画面)
性能 本地缓存(边播边缓存)、网络自适应码率(HLS ABR)
安全 HLS AES-128 加密、阿里云私有加密
截图 截取当前帧并返回本地文件路径

平台支持

平台 支持 最低版本
Android minSdkVersion 26(Android 8.0,PiP 要求)
iOS deploymentTarget 13.0(系统画中画要求 iOS 15+)
H5 请使用 Aliplayer Web SDK
微信小程序
HarmonyOS

本插件通过 // #ifdef APP-PLUS 条件编译自动屏蔽非 App 端,不影响其他平台构建。


安装方式

方式一:从 uni-app 插件市场安装(推荐)

  1. 前往 DCloud 插件市场 搜索「阿里云播放器SDK」
  2. 点击「使用 HBuilderX 导入插件」,自动复制到项目 uni_modules/lord-aliyun-player/
  3. 完成 集成配置 后制作自定义基座

方式二:手动拷贝

本插件为标准 component-uts 格式 UTS 插件,导入项目 uni_modules/ 后开箱即用。

uni_modules/lord-aliyun-player/
├── utssdk/
│   ├── interface.uts          # 类型定义与 Module API 契约
│   ├── app-android/           # Android 平台实现(含 License 证书与配置)
│   └── app-ios/               # iOS 平台实现(含 License 证书与配置)
├── pages/demo/                # 可运行示例 Demo
├── pages_init.json            # Demo 路由自动注册清单
├── docs/                      # 集成指南等使用者文档
├── changelog.md               # 更新日志(面向使用者)
├── package.json
└── readme.md                  # 本文档(插件详情页正文)

集成配置

⚠️ 原生插件必须通过「自定义基座」或「正式打包」才能运行,不支持标准基座。

Android 配置

使用 UTS 插件格式(本插件)无需手动配置 build.gradle:

插件内部的 utssdk/app-android/config.json 已自动声明阿里云播放器 SDK 的 Maven 依赖(AliyunPlayer:7.14.0-full)与阿里云 Maven 仓库,HBuilderX 云打包时自动处理。

License 配置同样已内置:AndroidManifest.xmllicensekey / licensefile 两条 meta-data 与证书文件(assets/cert/AliVideoCert.crt)均已就位,详见 License 配置

使用者仅需按需补充以下两处配置:

1. AndroidManifest.xml 添加权限

<!-- 网络相关(必须) -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

<!-- 本地缓存/截图(需要访问外部存储时加) -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="28" />

<!-- 后台播放(如使用前台 Service) -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />

<!-- 熄屏播放保活(PARTIAL_WAKE_LOCK,不点亮屏幕) -->
<uses-permission android:name="android.permission.WAKE_LOCK" />

2. 开启 PiP(画中画)支持

manifest.jsonApp原生配置AndroidManifest.xml 配置 中,为主 Activity 添加:

<activity
    android:name="io.dcloud.PandoraEntry"
    android:supportsPictureInPicture="true"
    android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboardHidden|keyboard|navigation|fontScale|locale|uiMode|colorMode"
    android:exported="true"
    android:hardwareAccelerated="true"
    android:launchMode="singleTask"
    android:windowSoftInputMode="adjustResize" />

iOS 配置

使用 UTS 插件格式(本插件)无需手动编辑 Podfile:

插件内部的 utssdk/app-ios/config.json 已自动声明 CocoaPods 依赖(AliPlayerSDK_iOS 7.16.0)、deploymentTarget(13.0)与所需系统 frameworks / libraries,HBuilderX 云打包时自动处理。

License 配置同样已内置:Info.plistAlivcLicenseKey / AlivcLicenseFile 与证书文件(Resources/AliVideoCert.crt)均已就位,详见 License 配置

使用者仅需按需补充以下配置:

1. 后台播放/PiP 与 HTTP 访问(manifest.json)

manifest.json → App 原生配置 → iOS Info.plist 配置 节点中添加以下内容(HBuilderX 云打包自动合并进原生工程,无需在 Xcode 中操作):

<!-- 允许 HTTP(如视频地址是 HTTP) -->
<key>NSAppTransportSecurity</key>
<dict>
    <key>NSAllowsArbitraryLoads</key>
    <true/>
</dict>

<!-- 熄屏/锁屏后台播放 + PiP(画中画)必须添加 -->
<key>UIBackgroundModes</key>
<array>
    <string>audio</string>
</array>

不配置此项,iOS 熄屏后播放会被系统中止,PiP 也无法进入后台浮窗。


快速开始

基础播放示例

<template>
  <view class="container">
    <!-- 播放器视图组件(仅 APP 端渲染) -->
    <!-- #ifdef APP-PLUS -->
    <ali-player-view
      ref="player"
      :src="videoUrl"
      :autoplay="true"
      :show-controls="true"
      :auto-hide-controls="true"
      @ready="onReady"
      @play="onPlay"
      @pause="onPause"
      @ended=""
      @error="onError"
      @timeupdate=""
      @fullscreenchange=""
      @pipchange="onPipChange"
      @back="onPlayerBack"
    />
    <!-- #endif -->
  </view>
</template>

<script>
export default {
  data() {
    return {
      videoUrl: 'https://example.com/video.mp4'
    }
  },
  methods: {
    // 准备完成,可获取时长等信息
    onReady(e) {
      console.log('播放器准备完成,时长:', e.duration)
    },

    onPlay() {
      console.log('开始播放')
    },

    onPause() {
      console.log('暂停播放')
    },

    () {
      console.log('播放完成')
    },

    onError(e) {
      console.error('播放错误:', e.code, e.message)
      uni.showToast({ title: '播放失败', icon: 'none' })
    },

    (e) {
      // e.currentTime 和 e.duration 为 Long 类型(毫秒)
      console.log('播放进度:', e.currentTime, '/', e.duration)
    },

    (e) {
      console.log('全屏状态:', e.fullScreen === 1 ? '全屏' : '竖屏')
    },

    onPipChange(e) {
      console.log('PiP 状态:', e.isInPip === 1 ? '已进入' : '已退出')
    },

    // 竖屏时点击返回按钮触发,通常执行页面返回
    onPlayerBack() {
      uni.navigateBack()
    },

    // 通过 ref 调用组件方法
    togglePlay() {
      this.$refs.player.togglePlayPause()
    },

    seekTo(positionMs) {
      this.$refs.player.seekTo(positionMs)
    },

    enterPip() {
      this.$refs.player.enterPip()
    },

    toggleFullScreen() {
      this.$refs.player.toggleFullScreen()
    }
  }
}
</script>

<style>
.container {
  flex: 1;
  background-color: #000;
}
</style>

VidAuth 播放示例

<template>
  <!-- #ifdef APP-PLUS -->
  <ali-player-view
    ref="player"
    vid="your-video-id"
    play-auth="your-play-auth-token"
    region="cn-shanghai"
    :autoplay="true"
    @ready="onReady"
    @back="onPlayerBack"
  />
  <!-- #endif -->
</template>

VidSts 播放示例

<template>
  <!-- #ifdef APP-PLUS -->
  <ali-player-view
    ref="player"
    vid="your-video-id"
    access-key-id="STS_KEY_ID"
    access-key-secret="STS_KEY_SECRET"
    security-token="STS_TOKEN"
    region="cn-shanghai"
    :autoplay="true"
    @ready="onReady"
    @back="onPlayerBack"
  />
  <!-- #endif -->
</template>

Props 属性

属性 类型 默认值 说明
src String '' 播放 URL(URL 播放模式)
vid String '' 视频 ID(VidAuth / VidSts 模式)
playAuth String '' VidAuth 播放凭证
accessKeyId String '' VidSts AccessKeyId
accessKeySecret String '' VidSts AccessKeySecret
securityToken String '' VidSts SecurityToken
title String '' 视频标题
subtitle String '' 视频副标题(控制栏标题下方第二行/媒体通知栏副标题)
autoplay Boolean false 是否自动播放
muted Boolean false 是否静音
loop Boolean false 是否循环播放
playbackSpeed Number 1.0 初始播放速度
playerId String '' 播放器实例 ID(插件路由键)。组件自动管理:未传时自动生成全局唯一 id,并经 ready/viewready 事件 playerId 字段回传;多实例场景也可显式传入全局唯一 id(显式重复 id 会被拒绝注册并告警)
region String 'cn-shanghai' 接入地域(VidAuth/VidSts 模式)
showControls Boolean true 是否显示控制栏
autoHideControls Boolean true 是否自动隐藏控制栏(播放5秒后)
coverImage String '' 封面图 URL。传入时作为海报(poster)在首帧渲染前全幅展示,首帧后自动隐藏;未传入时插件自动在播放前采样生成最优封面(同一视频再次进入秒显且画面一致);置空串可清除外部封面并回退自动生成封面
pipOption Object { width: 0, height: 0 } 画中画宽高比配置(0=自动从视频尺寸计算),保留参数,双端均由系统自动管理
episodes Array [] 选集列表(标准结构 EpisodeItem[],见下方说明)。长度 >1 且横屏全屏时,底部控制栏“选集”按钮替换全屏按钮,点击弹出右侧选集面板
episodesJson String '' 选集列表 JSON 字符串(EpisodeItem[] 序列化,与 episodes 等价的保底通道)。部分兼容场景下对象数组 prop 响应可能不稳定,字符串形态更可靠;非空时优先于 episodes 生效,推荐两者同时绑定(重复下发会被插件自动去重)
episodeIndex Number 0 当前播放集索引(0 基,选集面板高亮回显用)。切集后由调用者回灌保持同步
favorited Boolean false 当前视频是否已收藏(驱动“更多”抽屉收藏图标空心/实心)。收藏业务由调用者实现:监听 @moreaction(action='favorite')调业务接口,成功后回写此 prop 完成图标回显
moreActions Array ['share','favorite','speed','timer','download'] “更多”抽屉条目与顺序(未知标识自动过滤)。空数组隐藏控制栏“更多”按钮;默认全量五项
speedPresets Array [4.0,3.0,2.0,1.5,1.25,1.0,0.75] 倍速弹层预设档位(顺序即宫格展示顺序,非正数档位自动过滤)
sleepTimerPresets Array [30,60] 定时关闭倒计时档位分钟数(“不开启/播完当前”固定项不受影响)
themeColor String '#00A8F6' 主题色(#RRGGBB/#AARRGGBB):控制栏进度条/投屏高亮/抽屉高亮/选集当前集同源换色
texts Object {} UI 文案覆盖表(key 见下方文案定制,未覆盖项用默认中文文案)

选集数据标准结构(EpisodeItem)

episodes 数组每项为一个 EpisodeItem 对象(类型定义见 utssdk/interface.uts):

[
  {
    "title": "第1集 开篇",
    "url": "https://example.com/ep1.mp4",
    "vid": "",
    "coverUrl": "https://example.com/ep1.jpg",
    "duration": 1260,
    "extra": { "materialId": "10001" }
  },
  { "title": "第2集 进阶" }
]
字段 类型 必填 说明
title String 集标题(选集面板行文本,缺省回退“第X集”)
url String 该集播放地址(URL 模式换源用,插件透传不消费)
vid String 该集视频 ID(VidAuth/VidSts 模式换源用,插件透传不消费)
coverUrl String 该集封面图 URL(透传)
duration Number 该集时长(秒,透传)
extra Any 业务自定义数据(episodeselect 事件原样回传)

设计原则:插件仅消费 title 渲染选集面板,不自动换源——播放模式(URL / VidAuth / VidSts)由业务层决定。 用户点选后插件派发 episodeselect 事件(携带 index 与完整 episode 条目),由调用者取源切集并回灌 episodeIndex 保持高亮同步;播完自动连播同理只需回灌 episodeIndex

// 典型接入:点选后取 episode.url 换源,并回灌 episodeIndex
onEpisodeSelect(e) {
  const { index, episode } = e.detail || e;
  this.currentEpisode = index;          // 回灌 :episodeIndex
  this.src = episode.url;              // 或按 episode.vid 走 VidAuth/VidSts 换源
}

组件方法(通过 ref 调用)

平台列:双端 = Android + iOS 均支持;Android / iOS = 仅对应平台生效。标注 @deprecated 的方法仍可用,但建议改用统一入口。

方法 参数 平台 说明
play() 双端 播放
pause() 双端 暂停
stop() 双端 停止
prepare() 双端 准备播放(设置播放源后调用)
seekTo(positionMs, seekMode) Long, String 双端 跳转到指定位置(毫秒);seekMode:'accurate' 精确 / 'inaccurate' 快速(缺省精确)
setUrl(url) String 双端 设置 URL 播放源
setAutoPlay(autoPlay) Boolean 双端 设置自动播放
setSpeed(speed) Number 双端 设置播放速度
setAudioOnlyMode(enabled) Boolean 双端 设置纯音频模式
exitAudioOnlyMode() 双端 退出纯音频模式(恢复视频播放)
setCoverImageUrl(url) String 双端 设置封面图(避免与 coverImage prop 自动 setter 冲突);传空串清除外部封面并回退首帧快照兜底(播放前窗口采帧择优结果)
enableKeepPlayingOnScreenOff() 双端 开启熄屏播放
disableKeepPlayingOnScreenOff() 双端 关闭熄屏播放
snapshot() 双端 截图(结果通过 snapshot 事件返回)
toggleControls() 双端 切换控制栏显隐
togglePlayPause() 双端 切换播放/暂停
toggleFullScreen() 双端 切换全屏
getCurrentPosition(callback) Function 双端 获取当前播放位置(毫秒),callback 回调
getDuration(callback) Function 双端 获取视频总时长(毫秒),callback 回调
enterSmallWindow() 双端 进入小窗(推荐统一入口,返回 Boolean)。Android 分层浮窗(系统画中画 + 应用内浮窗兜底),iOS 系统画中画
exitSmallWindow() 双端 退出小窗(自动识别当前小窗类型)
isInSmallWindow() 双端 查询是否处于小窗(返回 Boolean)
setAutoSmallWindowOnLeave(enabled) Boolean 双端 设置“离开 App 自动进小窗”开关(默认开启)
setSmallWindowRequirePermission(enabled) Boolean 双端 @deprecated 历史“小窗强依赖悬浮窗权限”开关;当前版本小窗已统一为系统画中画,为空实现占位,仅为兼容保留
enterPip() 双端 进入画中画(返回 Boolean)。@deprecated 请用 enterSmallWindow()
exitPip() 双端 退出画中画。@deprecated 请用 exitSmallWindow()
isInPipMode() 双端 查询是否处于画中画(返回 Boolean)。@deprecated 请用 isInSmallWindow()
enterPipWithRatio(videoWidth, videoHeight) Number, Number Android 进入画中画并指定宽高比(0=自动计算)
showFloatWindow() Android 显示悬浮窗。@deprecated 请用 enterSmallWindow()
hideFloatWindow() Android 隐藏悬浮窗。@deprecated 请用 exitSmallWindow()
setMediaNotificationEnabled(enabled) Boolean Android 媒体通知栏 + 锁屏 MediaSession 控制开关(默认开启)
setKeepPlayingInBackground(enabled) Boolean Android App 退到后台是否继续播放(默认 true,不自动暂停)
setBackgroundAudioEnabled(enabled) Boolean Android 后台自动切纯音频开关(默认开启,回前台自动恢复视频)
showDlnaDeviceList() 双端 打开投屏入口(Android:设备列表弹窗;iOS:系统 AirPlay 选择器)
startDlnaCasting(deviceId, deviceName) String, String 双端 开始投屏(iOS 忽略参数,直接调起系统选择器)
stopDlnaCasting() 双端 停止投屏(iOS 无法强制断开,调起系统选择器由用户断开)
isDlnaCasting() 双端 查询是否正在投屏(返回 Boolean)
pauseDlnaCasting() 双端 暂停投屏播放(iOS 映射为本地播放器暂停)
resumeDlnaCasting() 双端 继续投屏播放(iOS 映射为本地播放器继续)
seekDlnaCasting(positionMs) Long 双端 投屏 seek(毫秒,iOS 映射为本地播放器 seek)
setDlnaVolume(level) Int 双端 设置投屏音量(0-100,iOS 映射为本地播放器音量)
showSleepTimerSheet() 双端 弹出“定时关闭”选择弹层
setSleepTimer(mode, minutes) String, Number 双端 设置定时关闭(mode: off/current/countdown,minutes 仅 countdown 有效)
showSpeedSelectSheet() 双端 弹出“倍速设置”选择弹层
startDownload() 双端 开始下载当前视频(抽屉“下载”条目点击时原生已自动处理,此方法供自定义 UI 主动发起)
stopDownload() 双端 停止当前下载任务
isDownloading() 双端 查询是否有下载任务进行中(返回 Boolean)
setSecureDownloadKeyFile(path) String 双端 配置安全下载密钥文件(encryptedApp.dat 本地绝对路径,加密视频下载必需,全局一次即可)

Module API(跨页面调用)

除上述 ref 方法外,插件另导出一套同步 Module API(共 70 个)。二者底层驱动同一个原生 View,选用原则:

  • 优先用 ref 方法:同页面内调用,无需关心 playerId
  • 用 Module API:调用方与播放器组件不在同一页面时(如独立投屏页、全局音频控制器),此时拿不到 ref
import { play, pause, setAudioOnly, getCurrentPosition } from '@/uni_modules/lord-aliyun-player'

// 入参统一为单个 options 对象,playerId 缺省 'default'(需与组件的 player-id 属性一致)
play({ playerId: 'main-player' })
setAudioOnly({ playerId: 'main-player', enabled: true })

// 出参统一 { code, message?, ...data },code === 0 为成功
const res = getCurrentPosition({ playerId: 'main-player' })
if (res.code === 0) {
  console.log('当前位置', res.position)
}

// 日志降噪(全局生效,与 playerId 无关):release 环境建议 'warn' 或 'off'
import { setPlayerLogLevel } from '@/uni_modules/lord-aliyun-player'
setPlayerLogLevel({ level: 'warn' })

调用前提:绝大多数 API 需播放器 View 已挂载(组件已渲染),View 不存在时返回 { code: -1, message: 'View not found for playerId: xxx' }。完整函数清单、参数与返回结构见 utssdk/interface.uts

事件列表

平台列:双端 = Android + iOS 均派发;Android = 仅 Android 派发(iOS 不派发,调用方不应在 iOS 上依赖)。 注意:为保证双端序列化一致,布尔字段统一以 Int(1/0)传递,判断时用 e.xxx === 1 或直接真值判断。

事件名 detail 结构 平台 说明
play 双端 播放
pause 双端 暂停
timeupdate { currentTime: Long, duration: Long } 双端 播放进度更新
ended 双端 播放完成
error { code: Int, message: String } 双端 播放错误
fullscreenchange { fullScreen: Int(1/0), direction: String } 双端 全屏状态变化
ready { duration: Long, playerId: String } 双端 准备完成;playerId 为生效的路由 id,供 Module API 使用
viewready { playerId: String, initOk: Int(1/0) } 双端 原生视图就绪:原生视图初始化完成、事件通道已挂接时发射,早于一切播放事件。Module API 调用建议据此门控;initOk=0 表示实例创建失败,不应再重试
pipchange { isInPip: Int(1/0) } 双端 PiP 状态变化
smallwindowchange { active: Int(1/0), mode: String } 双端 小窗状态变化(mode'pip' 系统画中画 / 'float' 应用内浮窗;iOS 恒为 'pip',Android 按权限择优)
audioonlychange { isAudioOnly: Int(1/0) } 双端 纯音频模式变化
exitaudioonly 双端 退出纯音频模式
audiofocuschange { focusChange: String } 双端 音频焦点/会话打断变化(Android AudioFocus;iOS 来电、闹钟、其他 App 抢占,取值口径与 Android 对齐:LOSS_TRANSIENT/GAIN
mutedchange { isMuted: Int(1/0) } 双端 静音状态变化(手势调音量自动取消静音时通知)
loading { isLoading: Int(1/0) } 双端 缓冲状态
seekcomplete 双端 Seek 完成
videosizechanged { width: Int, height: Int } 双端 视频尺寸变化
statechanged { state: Int, stateName: String } 双端 播放器状态变化
snapshot { path: String } 双端 截图完成
trackchanged { success: Int(1/0), trackIndex: Int, trackType: String, errorCode: Int, errorMsg: String } 双端 轨道切换
renderingstart 双端 首帧渲染
controlchange { show: Int(1/0) } 双端 控制栏显隐变化
back 双端 竖屏返回按钮点击(通常执行 uni.navigateBack()
castingstart { deviceName: String } 双端 投屏已开始
castingstop 双端 投屏已停止
castingerror { code: Int, message: String } 双端 投屏出错(code 对应 CastingErrorCode
castingstatechange { state: Int, stateName: String, deviceName: String, code: Int, message: String } 双端 统一投屏会话状态变更(推荐监听state 对应 CastState
castprogress { currentTime: Long, duration: Long } 双端 投屏播放进度回传(毫秒)
episodeselect { index: Int, episode: EpisodeItem } 双端 选集面板点选非当前集。index 为 0 基集索引,episodeepisodes 中对应条目原样回传(含 url/vid/extra 等透传字段);插件不自动换源,由调用者切集后回灌 episodeIndex
moreaction { action: String } 双端 “更多”抽屉条目点击(share/favorite/speed/timer/download)。speed/timer/download 原生已自动处理(仍派发通知);share/favorite 需调用者实现业务
ratechange { rate: Number } 双端 倍速变更(弹层宫格/自定义滑杆/setSpeed 调用均派发)
sleeptimerchange { mode: String, remainingMs: Long } 双端 定时关闭状态变更(mode: off/current/countdown,非 countdown 时 remainingMs 为 0)
sleeptimerfinish { mode: String } 双端 定时关闭已生效(倒计时到点已暂停 / 播完当前即将 ended)
downloadprogress { percent: Int } 双端 下载进度(0-100);Android 同步刷新通知栏常驻进度通知
downloadcomplete { filePath: String } 双端 下载完成(本地文件绝对路径)。Android 完成后自动导出到系统公共「下载」目录(Download/<应用名>/,文件管理器可见,filePath 为导出后路径),并展示可点击打开的完成通知;iOS 保存在沙盒 Documents/aliplayer_download,宿主工程开启 UIFileSharingEnabled + LSSupportsOpeningDocumentsInPlace 后可在「文件」App 中找到
downloaderror { code: String, message: String } 双端 下载失败(code 为字符串错误码,见 interface.utsDownloadErrorEventData

back 事件说明:内置控制栏的返回按钮行为根据横竖屏自动区分:

  • 横屏(全屏):点击返回 → 退出全屏回到竖屏
  • 竖屏:点击返回 → 触发 back 事件,由 Vue 层决定行为(通常 uni.navigateBack()

示例 Demo(随插件内置)

插件内置一个可直接运行的完整 Demo(位于插件包内,符合 uni_modules 目录规范):

文件 说明
pages/demo/index.nvue Demo 播放页:Props/事件/ref 方法全演示,含选集换源、断点续播、错误重试、生命周期释放等企业级写法
pages/demo/demo-data.json 示例数据(模拟服务端“视频详情接口”响应)
pages/demo/api.js 服务端接口封装示例(Mock/真实接口一键切换,基于 uni.request 自包含实现)
pages_init.json 页面注册清单(HBuilderX 3.5+ 导入插件时自动弹窗合并到项目 pages.json)
docs/lord-aliyun-player-integration-guide.md 初学者集成指南(含服务端 Node.js/Java 实现示例、上线 Checklist)

运行步骤:

  1. 通过 HBuilderX 导入插件时,根据 pages_init.json 弹窗确认即可自动注册 Demo 路由; 若未弹窗(或手动复制的插件),在项目 pages.json 手动添加:
{
  "path": "uni_modules/lord-aliyun-player/pages/demo/index",
  "style": { "navigationBarTitleText": "阿里云播放器Demo" }
}
  1. 制作自定义调试基座并真机运行(原生插件不在标准基座内);
  2. 任意入口跳转:uni.navigateTo({ url: '/uni_modules/lord-aliyun-player/pages/demo/index' })

Demo 默认 USE_MOCK = true(数据来自 demo-data.json),无需服务端即可跑通; 接入自己服务端后将 api.js 中开关改为 false 并替换 BASE_URL。 Demo 不依赖宿主项目任何文件,可随插件分发直接使用。


进阶用法

熄屏/锁屏播放

// 开始播放后调用,申请保活锁
this.$refs.player.enableKeepPlayingOnScreenOff()

// 暂停 / 完成 / 出错时释放
this.$refs.player.disableKeepPlayingOnScreenOff()

组件内已在 play() 时自动调用 enableKeepPlayingOnScreenOff,在播放完成/出错时自动释放,通常无需手动调用。

纯音频模式(听视频)

// 开启纯音频模式(仅播放音频不渲染画面)
this.$refs.player.setAudioOnlyMode(true)

// 关闭纯音频模式
this.$refs.player.setAudioOnlyMode(false)

监听纯音频模式变化:

<ali-player-view @audioonlychange="onAudioOnlyChange" />

<script>
methods: {
  onAudioOnlyChange(e) {
    console.log('纯音频模式:', e.isAudioOnly ? '已开启' : '已关闭')
  }
}
</script>

小窗播放(统一入口)

系统要求:Android 8.0+(API 26)/ iOS 15+。 Android 为腾讯视频式分层浮窗(已授悬浮窗权限时系统画中画,未授权时应用内浮窗,App 不退后台),iOS 为系统画中画;离开 App 自动起窗双端体验一致,接入方无需处理悬浮窗权限编排。

// 进入小窗(返回 Boolean 表示是否成功)
const ok = this.$refs.player.enterSmallWindow()

// 退出小窗(自动识别当前小窗类型)
this.$refs.player.exitSmallWindow()

// 查询是否处于小窗
const inSmall = this.$refs.player.isInSmallWindow()

统一监听 smallwindowchange(跨平台一致,mode 区分底层实现):

<ali-player-view
  ref="player"
  @smallwindowchange="onSmallWindowChange"
/>

<script>
methods: {
  onSmallWindowChange(e) {
    // e.active === 1 表示已进入小窗(mode: 'pip'=系统画中画 / 'float'=应用内浮窗;iOS 恒为 'pip')
    console.log('小窗状态:', e.active === 1 ? '已进入' : '已退出')
  }
}
</script>

离开 App 自动进小窗(默认开启):

// 关闭“离开 App 自动进小窗”(默认开启)
this.$refs.player.setAutoSmallWindowOnLeave(false)

画中画旧 APIenterPip() / exitPip() / isInPipMode() 已标记 @deprecated,仍可用但建议迁移到 enterSmallWindow() 系列。Android 如需指定宽高比可用 enterPipWithRatio(w, h)

后台播放与媒体通知栏(Android)

以下能力仅 Android 生效。iOS 后台音频由系统 UIBackgroundModes: audio + AVAudioSession 自动承载(见「熄屏/锁屏播放」)。

默认行为(无需额外调用):App 退到后台时继续播放,并自动切为纯音频 + 显示媒体通知栏(锁屏 MediaSession 控制),回到前台自动恢复视频。可按需覆盖默认开关:

// 媒体通知栏 + 锁屏 MediaSession 控制开关(默认开启)
// 开启后进入小窗/后台且正在播放/暂停时显示通知栏(播放·暂停 / 快退 / 快进 / 关闭),关闭时立即移除
this.$refs.player.setMediaNotificationEnabled(true)

// App 退到后台是否继续播放(默认 true)
// 设为 false 恢复旧行为:退到后台自动暂停、回到前台自动恢复
this.$refs.player.setKeepPlayingInBackground(true)

// 后台自动切纯音频开关(腾讯视频式,默认开启)
// 正在播放视频时退到后台(非小窗)自动切纯音频并显示通知栏,回前台自动恢复视频
this.$refs.player.setBackgroundAudioEnabled(true)

需在 AndroidManifest.xml 声明 FOREGROUND_SERVICEWAKE_LOCK 等权限(见 Android 配置)。手势调音量自动取消静音会派发 mutedchange 事件;音频焦点变化(如来电、其他 App 抢占)会派发 audiofocuschange 事件。注:这两个事件本身是双端的(iOS 由 AVAudioSession 打断通知驱动),仅上述后台/通知栏开关 API 为 Android 专属。

投屏(Android DLNA / iOS AirPlay)

组件对外提供统一的投屏 API,底层按平台自动路由:

平台 投屏通道 设备发现 URL 推送 说明
Android DLNA / UPnP ✅ 应用内设备列表 ✅ 推送播放 URL 到设备 走完整链路:搜索 → 选择 → 连接 → 投屏;仅 URL 播放源可投屏
iOS 系统 AirPlay ❌ 由系统选择器负责 ❌ 仅镜像/音频路由当前播放 由系统被动驱动,无法程序化搜索/断开;不受源模式限制

Android 投屏源限制: DLNA 需向电视下发可直接播放的媒体地址,因此仅 URL 播放源(http/https 直链) 支持投屏;投屏地址由组件自动取当前播放 URL,无需额外传入。VidAuth/VidSts 的真实播放地址由 AliPlayer SDK 内部解析、应用层无公开 API 获取,故不支持投屏;此时点击投屏按钮会提示“当前播放源不支持投屏”。iOS AirPlay 为屏幕镜像,不受此限制。

iOS 说明:阿里云 AVPPlayer 不支持真正的 AirPlay 视频外部播放(自有渲染管线),音频跟随 AirPlay 路由、视频由系统镜像;实际投屏状态以系统路由检测为准,因此 startDlnaCasting/stopDlnaCasting 均只是调起系统 AirPlay 选择器,真实开始/断开由用户在选择器中操作、由路由回调更新状态。

基本用法

// 打开投屏入口(Android 弹设备列表;iOS 弹系统 AirPlay 选择器)
this.$refs.player.showDlnaDeviceList()

// 查询是否正在投屏
const casting = this.$refs.player.isDlnaCasting()

// 投屏中的远端控制(AirPlay 场景映射为本地播放器操作)
this.$refs.player.pauseDlnaCasting()
this.$refs.player.resumeDlnaCasting()
this.$refs.player.seekDlnaCasting(60000) // 跳到 60s
this.$refs.player.setDlnaVolume(50)       // 音量 0-100

投屏页(组件默认实现)

点击控制栏投屏按钮即打开原生全屏投屏页(零配置,右侧滑入):

  • Android:设备搜索 / 设备列表 / “找不到投屏设备?”提示;已在投屏中时打开投屏控制页(遥控/切换/断开);
  • iOS:AirPlay 引导 + “打开 AirPlay”按钮(调起系统选择器);已在投屏中时改弹“断开投屏”确认。

监听投屏状态与进度

推荐统一监听 castingstatechange(状态机驱动,跨平台语义一致),旧事件 castingstart/castingstop/castingerror 并行保留做兼容:

<ali-player-view
  ref="player"
  @castingstatechange="onCastingStateChange"
  @castprogress="onCastProgress"
/>

<script>
methods: {
  onCastingStateChange(e) {
    // e.state 对应 CastState:0=Idle 4=Casting 5=Paused 6=Stopped -1=Error
    console.log('投屏状态:', e.stateName, '设备:', e.deviceName)
    if (e.state === -1) {
      console.error('投屏出错:', e.code, e.message) // code 对应 CastingErrorCode
    }
  },
  onCastProgress(e) {
    // 投屏播放进度(毫秒)
    console.log('投屏进度:', e.currentTime, '/', e.duration)
  }
}
</script>

跨平台对齐说明(iOS ↔ Android)

  • castprogress 进度回传:Android 由 DLNA 设备真实回传播放位置;iOS 因 AirPlay 镜像本地 AVPPlayer,本地播放位置即投屏位置,故复用进度 Timer 在投屏中并行派发 castprogress。两端事件负载 { currentTime, duration } 一致。
  • 投屏日志桥接 JS 控制台:投屏关键日志会桥接到前端 console,便于排查。Android 前缀 [DlnaCasting]、iOS 前缀 [AirPlayCasting];带错误标签(Android [DLNA-ERROR] / iOS [AIRPLAY-ERROR])的日志走 console.error,其余走 console.log
  • iOS AirPlay 自动重连(路由恢复):当用户经系统控制中心断开后再次接入同一 AirPlay 路由时,组件通过 AVAudioSession.routeChangeNotification 检测到路由恢复,会自动将投屏会话从 Error/Stopped 状态转回 Casting 并重新派发 castingstart/castingstatechange,无需应用层额外处理。

“更多”抽屉与 UI 定制

控制栏右上角“更多”按钮弹出底部抽屉,内置五个条目:分享、收藏、倍速播放、定时关闭、下载。 条目与顺序通过 moreActions 配置,主题色与全部文案均可定制,适配不同产品风格与多语言场景。

条目配置(moreActions)

<!-- 只保留倍速与定时关闭,隐藏分享/收藏/下载 -->
<ali-player-view :moreActions="['speed', 'timer']" />

<!-- 传空数组隐藏控制栏“更多”按钮 -->
<ali-player-view :moreActions="[]" />

条目行为分两类:

条目 点击行为
speed / timer / download 原生自动处理(弹层/下载),同时派发 moreaction 事件供埋点
share / favorite 仅派发 moreaction 事件,业务由调用者实现
<template>
  <ali-player-view :favorited="isFav" @moreaction="onMoreAction" />
</template>
<script>
export default {
  data() { return { isFav: false } },
  methods: {
    onMoreAction(e) {
      const { action } = e.detail || e
      if (action === 'favorite') {
        // 调业务收藏接口,成功后回写 favorited 完成图标回显
        this.isFav = !this.isFav
      } else if (action === 'share') {
        uni.share({ /* ... */ })
      }
    }
  }
}
</script>

主题色(themeColor)

<ali-player-view themeColor="#FF6B00" />

一处配置全局生效:控制栏进度条、投屏/纯音频激活态、抽屉高亮、选集当前集高亮同源换色。 支持 #RRGGBB / #AARRGGBB,非法值忽略并保留默认蓝色(#00A8F6)。

文案定制(texts)

全部内置 UI 文案可通过 texts 覆盖(未覆盖项用默认中文),双端 key 同名同义,类型定义见 interface.utsPlayerTextsConfig

<ali-player-view :texts="{
  share: 'Share',
  favorite: 'Favorite',
  favorited: 'Favorited',
  speed: 'Speed',
  sleepTimer: 'Sleep Timer',
  download: 'Download',
  cancel: 'Cancel',
  loading: 'Loading...',
  speedChangedToast: 'Switched to {rate}'
}" />
key 默认文案 说明
share 分享 抽屉条目
favorite 收藏 抽屉条目(未收藏态)
favorited 已收藏 抽屉条目(已收藏态)
speed 倍速播放 抽屉条目
sleepTimer 定时关闭 抽屉条目
download 下载 抽屉条目
cancel 取消 弹层通用按钮
sleepTimerOff 不开启 定时关闭弹层固定项
sleepTimerCurrent 播完当前 定时关闭弹层固定项
speedTitle 倍速播放 倍速弹层标题
speedCustom 自定义 倍速弹层自定义档位按钮
speedCustomTitle 自定义倍速 自定义滑杆标题
speedCustomHint 拖动滑块调节倍速 自定义滑杆提示
episodeTitle 选集 选集面板标题
episodeCount 共{count}集 选集面板副标题,{count}=总集数
loading 加载中... 控制栏缓冲提示
castSourceNotSupported 当前视频源不支持投屏 轻提示
sleepTimerCurrentToast 将在播完当前视频后停止播放 轻提示
sleepTimerCountdownToast 将在 {minutes} 分钟后停止播放 轻提示,{minutes}=分钟数
sleepTimerFiredToast 定时关闭已生效,播放已停止 轻提示
speedChangedToast 已切换至 {rate} 倍速播放 轻提示,{rate}=倍速文本
castSpeedSentToast 已发送 {rate} 倍速,部分电视可能不支持变速 投屏倍速系统 Toast,{rate}=倍速文本
castSpeedUnsupportedToast 电视不支持该倍速 投屏设备拒绝该档位时的系统 Toast
downloadSourceNotSupported 当前视频源不支持下载 轻提示
downloadInProgress 已有下载任务进行中 轻提示
downloadStarted 开始下载 轻提示
downloadComplete 下载完成 轻提示(未导出公共目录时兜底)
downloadEncrypted 加密视频需先配置安全下载密钥 轻提示
downloadFailed 下载失败:{message} 轻提示,{message}=失败原因
downloadNotificationDownloading 正在下载 Android 下载进度通知状态文案(拼接百分比)
downloadCompleteSaved 下载完成,已保存到手机「下载」目录 完成提示(Android 导出公共目录成功后;iOS 默认“可在「文件」App 本应用目录中查看”)

占位符({count}/{minutes}/{rate}/{message})由原生侧运行时替换,覆盖文案时请保留占位符。

倍速播放

内置倍速弹层:预设档位宫格 + 自定义滑杆(0.5~4.0 无级调节),横屏竖屏均可用。

<!-- 自定义预设档位(顺序即宫格展示顺序) -->
<ali-player-view :speedPresets="[2.0, 1.5, 1.0, 0.5]" @ratechange="" />
// 也可不走弹层,直接设速 / 主动唤起弹层
this.$refs.player.setSpeed(1.5)
this.$refs.player.showSpeedSelectSheet()

(e) {
  const { rate } = e.detail || e   // 所有设速路径(弹层/滑杆/API)均派发
}

定时关闭

内置“定时关闭”弹层:不开启 / 播完当前 / 倒计时档位(默认 30/60 分钟,可配置)。 到点自动暂停播放并派发 sleeptimerfinish

<!-- 自定义倒计时档位(“不开启/播完当前”固定项不受影响) -->
<ali-player-view :sleepTimerPresets="[15, 30, 60, 90]"
  @sleeptimerchange="Change" @sleeptimerfinish="Finish" />
// 不走弹层,直接设置 / 主动唤起弹层
this.$refs.player.setSleepTimer('countdown', 30)  // 30 分钟后停止
this.$refs.player.setSleepTimer('current', 0)     // 播完当前停止
this.$refs.player.setSleepTimer('off', 0)         // 取消
this.$refs.player.showSleepTimerSheet()

视频下载

抽屉“下载”条目点击后原生自动处理,无需 JS 层参与;也可通过组件方法在自定义 UI 中主动发起。

播放源 下载方式 保存位置
VidSts / VidAuth 阿里云 SDK 下载器(支持加密视频) Android 应用专属目录 / iOS 沙盒 Documents
URL(http/https) 插件自实现 HTTP 下载(直链流式;m3u8 逐分片合并为 .ts) 同上
<ali-player-view ref="player"
  @downloadprogress="" @downloadcomplete="onComplete" @downloaderror="onError" />
// 加密视频(vid 源):先配置密钥文件,全局一次即可
this.$refs.player.setSecureDownloadKeyFile('/data/user/0/xxx/files/encryptedApp.dat')

this.$refs.player.startDownload()                  // 开始下载当前视频
this.$refs.player.stopDownload()                   // 取消下载
const busy = this.$refs.player.isDownloading()     // 查询下载中

(e)  { const { percent } = e.detail || e }        // 0-100
onComplete(e)  { const { filePath } = e.detail || e }       // 本地绝对路径
onError(e)     { const { code, message } = e.detail || e }  // 字符串错误码

限制:同一播放器同时仅支持一个下载任务;HLS 加密流(EXT-X-KEY)不支持下载; 直播流(RTMP/RTS)不支持下载。不支持时原生轻提示并派发 downloaderror

截图

<ali-player-view ref="player" @snapshot="onSnapshot" />

<script>
methods: {
  async takeSnapshot() {
    // 触发截图,结果异步通过 snapshot 事件返回
    this.$refs.player.snapshot()
  },
  onSnapshot(e) {
    console.log('截图路径:', e.path)
    uni.saveImageToPhotosAlbum({
      filePath: e.path,
      success: () => uni.showToast({ title: '截图已保存' })
    })
  }
}
</script>

直播播放

<template>
  <!-- #ifdef APP-PLUS -->
  <ali-player-view
    ref="player"
    src="rtmp://live.example.com/live/stream"
    :autoplay="true"
    @ready="onReady"
    @error="onError"
  />
  <!-- #endif -->
</template>

支持格式:RTMP、HLS (M3U8)、FLV、RTS 超低延时直播。

切换播放源

// 方式1:通过 setUrl 方法
this.$refs.player.setUrl('https://example.com/new-video.mp4')
this.$refs.player.prepare()

// 方式2:通过修改 src prop(响应式)
this.videoUrl = 'https://example.com/new-video.mp4'

获取播放信息

// 获取当前播放位置(毫秒)
this.$refs.player.getCurrentPosition((pos) => {
  console.log('当前位置:', pos, 'ms')
})

// 获取视频总时长(毫秒)
this.$refs.player.getDuration((duration) => {
  console.log('总时长:', duration, 'ms')
})

License 配置(SDK 7.0.0+)

⚠️ 自 7.0.0 版本起,阿里云播放器 SDK 在 Android 与 iOS 两端均需要有效的 License 才能使用,否则会报 LICENSE_ERROR_INVALID 错误;且 7.6.0+ 版本必须同时配置 License 证书文件(仅配 LicenseKey 在弱网/无网环境下会鉴权失败)。

鉴权要素与双端存放规划

要素 作用 Android 位置 iOS 位置
LicenseKey SDK 启动时联网请求/刷新证书(必填) AndroidManifest.xmlcom.aliyun.alivc_license.licensekey Info.plistAlivcLicenseKey
License 证书文件(.crt) 弱网/离线时本地鉴权兜底(7.6.0+ 必填) assets/cert/AliVideoCert.crt Resources/AliVideoCert.crt
证书路径配置 告知 SDK 证书位置 AndroidManifest.xmlcom.aliyun.alivc_license.licensefile = assets/cert/AliVideoCert.crt Info.plistAlivcLicenseFile = AliVideoCert.crt

插件内的完整目录布局:

uni_modules/lord-aliyun-player/utssdk/
├── app-android/
│   ├── AndroidManifest.xml          ← licensekey + licensefile 两条 meta-data
│   └── assets/
│       └── cert/
│           └── AliVideoCert.crt     ← Android 证书(云打包合并到 APK assets/cert/)
└── app-ios/
    ├── Info.plist                   ← AlivcLicenseKey + AlivcLicenseFile(云打包合并进原生工程 Info.plist)
    └── Resources/
        └── AliVideoCert.crt         ← iOS 证书(云打包合并进 App main bundle)

设计说明(企业级规范)

  • 证书采用固定文件名 AliVideoCert.crt(而非阿里云下载时带日期戳的原始文件名),证书续期/权益变更时只需替换两端 .crt 文件本身,无需改动任何配置
  • Android 证书独立存放在 assets/cert/ 子目录,与控制栏图标(image/)、字体(fonts/)隔离,路径写法对齐阿里云官方文档示例(assets/cert/xxx.crt)。
  • 同一张 License 同时绑定 Android PackageName 与 iOS BundleId,双端共用同一个 LicenseKey 与同一份证书文件。

1. 申请 License

前往阿里云控制台申请:接入 License

申请时需要填写 App 的 Android PackageNameiOS BundleId(即 uni-app 打包时使用的包名),License 与应用标识强绑定。申请成功后可获得 LicenseKey 与 *License 证书文件(AliVideoCert-.crt)**。

2. Android 端配置

① 放置证书:将下载的 .crt 重命名为 AliVideoCert.crt,放入:

utssdk/app-android/assets/cert/AliVideoCert.crt

HBuilderX 打包时会自动将 UTS 插件 utssdk/app-android/assets/ 下的文件(含子目录)合并到 APK 的 assets/ 目录。

② 配置 meta-data:插件的 utssdk/app-android/AndroidManifest.xml 中已预置(<meta-data> 必须位于 <application> 节点内):

<meta-data
    android:name="com.aliyun.alivc_license.licensekey"
    android:value="你的LicenseKey" />
<meta-data
    android:name="com.aliyun.alivc_license.licensefile"
    android:value="assets/cert/AliVideoCert.crt" />

3. iOS 端配置

① 放置证书:将同一张证书(重命名为 AliVideoCert.crt)放入:

utssdk/app-ios/Resources/AliVideoCert.crt

按 UTS 插件规范,云打包时 Resources/ 下的文件会自动添加到应用 main bundle,无需手动操作 Xcode 工程。

② 配置 Info.plist:插件的 utssdk/app-ios/Info.plist 中已预置(云打包时自动合并进原生工程 Info.plist):

<key>AlivcLicenseKey</key>
<string>你的LicenseKey</string>
<key>AlivcLicenseFile</key>
<string>AliVideoCert.crt</string>

AlivcLicenseFile 填相对 main bundle 的路径;证书在 Resources/ 根目录时直接填文件名即可。

4. 证书续期 / 更换 License

场景 操作
证书续期、新开通增值服务(LicenseKey 不变) 仅替换两端证书文件:app-android/assets/cert/AliVideoCert.crtapp-ios/Resources/AliVideoCert.crt,配置零改动
更换 License(如换包名/换主体,LicenseKey 变化) 替换两端证书文件 + 同步修改 AndroidManifest.xmllicensekeyInfo.plistAlivcLicenseKey

修改后需重新制作自定义基座才能生效。

5. 验证与排查

  • 鉴权失败时播放器会派发 @error 事件(License 相关错误码 LICENSE_ERROR_*),可据此快速定位。
  • Android 检查要点:<meta-data> 是否在 <application> 内、LicenseKey 与控制台一致、打包包名与申请时填写的 PackageName 一致。
  • iOS 检查要点:AlivcLicenseKey 与控制台一致、BundleId 与申请时填写一致、证书已随包进入 main bundle。
  • 更多排查见:License 相关常见问题

常见问题

Q1:为什么在 HBuilderX 标准基座上运行没有效果 / 报「插件不存在」?
原生插件必须使用自定义调试基座或正式包,请在 HBuilderX 中选择「运行 → 运行到手机或模拟器 → 制作自定义调试基座」完成打包后再运行。

Q2:Android 模拟器无法播放视频?
阿里云播放器 Android SDK 不支持模拟器,请使用真机调试。

Q3:iOS 播放 HTTP 地址报网络错误?
manifest.json → App 原生配置 → iOS Info.plist 配置 中添加 NSAllowsArbitraryLoads: true,或将视频地址改为 HTTPS。

Q4:切换播放源(换 URL)不生效?
需先调用 stop(),再通过 setUrl() 设置新地址并 prepare()setAutoPlay(true) 可在换源后自动起播):

this.$refs.player.stop()
this.$refs.player.setUrl('https://new-url.mp4')
this.$refs.player.setAutoPlay(true)  // 可选:换源后自动起播
this.$refs.player.prepare()

Q5:如何监听播放进度?
通过 @timeupdate 事件,e.currentTime 即为当前播放位置(毫秒):

onTimeUpdate(e) {
  console.log('播放进度:', e.currentTime, '/', e.duration)
}

Q6:VidAuth 播放凭证过期怎么处理?
监听 @error 事件,判断错误码为凭证过期后,重新向服务端换取 PlayAuth,再更新 playAuth prop 或调用 prepare()

Q7:PiP 进入后视频停止了怎么办?
检查 AndroidManifest 的主 Activity 是否有 android:supportsPictureInPicture="true"android:configChanges 属性。

Q8:熄屏后音频也停了?
调用 enableKeepPlayingOnScreenOff() 后,播放器会自动申请 WakeLock 保活。如仍不生效,检查是否在播放完成/出错后未重新启用。

Q9:报 LICENSE_ERROR_INVALID 或提示 License 鉴权失败?
License 配置 逐项检查:两端 LicenseKey 是否与控制台一致、打包包名(PackageName/BundleId)是否与申请 License 时填写的一致、证书文件是否已按规划路径放置(Android assets/cert/AliVideoCert.crt、iOS Resources/AliVideoCert.crt)、证书是否已过期。注意:修改 License 配置后必须重新制作自定义基座。


更新日志

完整版本更新记录请查看 changelog.md


版本:v5.1.0 | 基于阿里云 ApsaraVideo Player SDK(Android / iOS)| 最低 HBuilderX:3.99

隐私、权限声明

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

无强制权限;按需使用网络、悬浮窗、存储(截图/下载)、前台服务、WakeLock 等权限,详见 readme.md 集成配置

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

插件本身不采集任何数据;插件集成的阿里云播放器 SDK(AliPlayer)可能采集设备信息用于 License 鉴权,详情参考阿里云隐私政策

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

暂无用户评论。