更新记录

1.1.0(2026-05-25) 下载此版本

CHANGELOG

All notable changes to the ali-player (阿里云播放器SDK) uni-app 原生插件 will be documented in this file.


[1.1.0] - 2026-05-25

新增(Features)

  • PiP 画中画(Picture-in-Picture)

    • Android: Activity.enterPictureInPictureMode() + PiP 状态回调
    • iOS: AVPictureInPictureController + AVPlayerLayer 自动检测
    • JS 接口: enterPip() / exitPip() / isInPipMode()
    • Vue 事件: @pipStateChanged
  • 熄屏/锁屏保活播放

    • Android: PARTIAL_WAKE_LOCK + AudioFocus 管理
    • iOS: AVAudioSession(.playback) + setActive(true)
    • JS 接口: enableKeepPlayingOnScreenOff() / disableKeepPlayingOnScreenOff()
    • Vue 事件: @audioFocusChanged
  • Registry 扩展: 新增 componentRegistry,支持 Module 跨组件调用 PiP/熄屏方法

改进(Changes)

文件 变更
android/.../AliPlayerComponent.java 重写:Lambda 化 + PiP/熄屏实现
android/.../AliPlayerModule.java 新增 5 个 @UniJSMethod
android/.../AliPlayerRegistry.java 重写:新增 componentRegistry
ios/.../AliPlayerComponent.{h,m} 新增 PiP 属性/方法/Delegate
ios/.../AliPlayerModule.m 新增 PiP/熄屏方法 + 修复 stateToName
ios/.../AliPlayerRegistry.{h,m} 新增 components 字典 + componentForId
js/uni.ali-player.js 新增 5 个 JS 方法
components/ali-player/ali-player.vue 新增 pipStateChanged/audioFocusChanged 事件转发
package.json 补全元数据(version/dcloudext/declaration/platforms)
README.md 按插件市场标准全面重写

修复(Fixes)

  • 修复 AliPlayerModule.m 中 stateToName: 方法定义缺失的回归问题
  • 清理 ali-player.vue onInfo 中的进度日志输出

平台配置要求(用户需手动操作)

平台 配置项
Android manifest.json 添加 androidManifest.activities[0].supportsPictureInPicture=true + configChanges
iOS Xcode → Signing & Capabilities → Background Modes → Audio, AirPlay, and Picture in Picture

[1.0.0] - 初始版本

新增

  • 基于 阿里云 ApsaraVideo Player SDK 7.14.0 封装,支持 iOS / Android 双端
  • 三种播放方式: VidAuth / VidSts / URL
  • 核心能力:
    • 点播 / 直播 / 列表播放
    • 播放控制(播放/暂停/停止/Seek/重播)
    • 本地缓存管理
    • 画质切换(清晰度列表 + 切换)
    • 截图功能
    • 音量/亮度/倍速调节
    • 全屏切换
  • Vue 组件化封装 (<ali-player>) + Module 调用方式 (uni.requireNativePlugin)

平台兼容性

uni-app(3.7.7)

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

阿里云播放器 SDK for uni-app

uni-app 版 ApsaraVideo Player SDK
对齐阿里云官方 Android / iOS / Flutter SDK 交付规范,完整封装播放器能力。
仅支持 App 端(Android / iOS),H5/小程序请使用官方 Web 版 SDK。


目录


功能概览

功能类别 支持能力
播放方式 URL 直播/点播、VidAuth(推荐)、VidSts
视频格式 MP4、HLS (M3U8)、FLV、RTMP、RTS 超低延时直播
播放控制 播放/暂停/停止/Seek/重加载/续播
画面控制 缩放模式、旋转、镜像
音频控制 音量、静音
画中画(PiP) Android 8.0+、iOS 15+ 系统级 PiP
熄屏/锁屏播放 Android WakeLock + AudioFocus;iOS AVAudioSession
性能 本地缓存(边播边缓存)、网络自适应码率(HLS ABR)
安全 HLS AES-128 加密、阿里云私有加密
多实例 支持页面内同时创建多个播放器
列表播放 短视频列表预加载(AliListPlayer)
截图 截取当前帧并返回本地文件路径
质量监控 播放日志上报(需阿里云账号)

平台支持

平台 支持 最低版本
Android minSdkVersion 21(Android 5.0)
iOS iOS 12.0+
H5 请使用 Aliplayer Web SDK
微信小程序
HarmonyOS

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


安装方式

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

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

方式二:手动拷贝

uni_modules/ali-player/ 整个目录拷贝到目标项目的 uni_modules/ 下,目录结构如下:

uni_modules/
└── ali-player/
    ├── android/                         # Android 原生插件源码
    │   ├── build.gradle
    │   ├── dcloud_uniplugins.json       # 插件注册声明
    │   └── src/main/java/com/aliyun/player/uniapp/
    │       ├── AliPlayerModule.java     # Module(供 JS 调用)
    │       ├── AliPlayerComponent.java  # Component(播放器渲染视图)
    │       └── AliPlayerRegistry.java   # 多实例注册表
    ├── ios/                             # iOS 原生插件源码
    │   ├── Classes/
    │   │   ├── AliPlayerModule.h/.m     # Module
    │   │   ├── AliPlayerComponent.h/.m  # Component
    │   │   └── AliPlayerRegistry.h/.m   # 多实例注册表
    │   ├── ali-player.podspec
    │   └── dcloud_uniplugins.json
    ├── components/
    │   └── ali-player/
    │       └── ali-player.vue           # Vue 组件(视图层桥接)
    ├── js/
    │   └── uni.ali-player.js            # JS SDK 核心(工厂/实例/常量)
    └── package.json

集成配置

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

Android 配置

1. build.gradle 添加依赖

在项目 android/app/build.gradle 中添加:

repositories {
    // 阿里云 Maven 仓库
    maven { url "https://maven.aliyun.com/nexus/content/repositories/releases" }
}

android {
    defaultConfig {
        minSdkVersion 21
    }
}

dependencies {
    // 完整版(含软解码),体积约 25MB;lite 版约 9MB(仅硬解码)
    implementation 'com.aliyun.sdk.android:AliyunPlayer:7.14.0-full'

    // 可选:RTS 超低延时直播
    // implementation 'com.aliyun.rts.android:RtsSDK:2.x.x'
    // implementation 'com.aliyun.sdk.android:AlivcArtc:7.14.0'
}

2. 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" />

3. 开启 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" />

HBuilderX 3.x 的主 Activity 名称通常为 io.dcloud.PandoraEntry,请以实际生成的 AndroidManifest 为准。


iOS 配置

1. Podfile 添加依赖

target 'HBuilder' do
    pod 'AliPlayerSDK_iOS', '7.14.0'
    # 可选:RTS 超低延时直播
    # pod 'AliPlayerSDK_iOS_ARTC', '7.14.0'
    # pod 'RtsSDK', '2.x.x'
end

执行 pod install

2. Info.plist 配置

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

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

3. Xcode 开启 Background Modes

  1. 在 Xcode 中打开项目 → 选择 Target → Signing & Capabilities
  2. 点击「+ Capability」→ 添加 Background Modes
  3. 勾选 ☑ Audio, AirPlay, and Picture in Picture

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


快速开始

基础播放示例

<template>
  <view class="container">
    <!-- 播放器视图组件(仅 APP 端渲染) -->
    <!-- #ifdef APP-PLUS -->
    <ali-player
      ref="aliPlayer"
      player-id="main-player"
      :width="750"
      :height="422"
      @prepared="onPrepared"
      @info="onInfo"
      @completion="onCompletion"
      @error="onError"
    />
    <!-- #endif -->

    <!-- 控制栏 -->
    <view class="controls">
      <button @tap="togglePlay">{{ isPlaying ? '暂停' : '播放' }}</button>
      <slider
        :value="currentPosition"
        :max="duration"
        @change="onSliderChange"
      />
      <text>{{ formatTime(currentPosition) }} / {{ formatTime(duration) }}</text>
    </view>
  </view>
</template>

<script>
// #ifdef APP-PLUS
import { AliPlayerFactory, SeekMode } from '@/uni_modules/ali-player/js/uni.ali-player.js'
// #endif

export default {
  data() {
    return {
      player: null,
      isPlaying: false,
      currentPosition: 0,
      duration: 0
    }
  },

  onLoad() {
    // #ifdef APP-PLUS
    this.initPlayer()
    // #endif
  },

  onUnload() {
    // 页面销毁时必须释放播放器,否则原生资源会泄漏
    if (this.player) {
      this.player.release()
    }
  },

  methods: {
    async initPlayer() {
      // 1. 创建播放器实例(playerId 需与 <ali-player> 的 player-id 一致)
      this.player = AliPlayerFactory.createAliPlayer('main-player')

      // 2. 可选:配置缓冲参数
      await this.player.setConfig({
        startBufferDuration: 500,
        highBufferDuration:  3000,
        maxBufferDuration:   50000,
        networkTimeout:      15000,
        networkRetryCount:   3
      })

      // 3. 设置自动播放
      await this.player.setAutoPlay(true)

      // 4. 设置播放源(三选一)
      // 方式 A:URL 直接播放
      await this.player.setUrl('https://example.com/video.mp4')

      // 方式 B:VidAuth 播放(推荐生产环境,凭证有效期约 100s)
      // await this.player.setVidAuth({
      //   vid:       'your-video-id',
      //   playAuth:  'your-play-auth-token',
      //   region:    'cn-shanghai'
      // })

      // 方式 C:VidSts 播放
      // await this.player.setVidSts({
      //   vid:             'your-video-id',
      //   region:          'cn-shanghai',
      //   accessKeyId:     'STS_KEY_ID',
      //   accessKeySecret: 'STS_KEY_SECRET',
      //   securityToken:   'STS_TOKEN'
      // })

      // 5. 开始准备
      await this.player.prepare()
    },

    async onPrepared() {
      // 准备完成后获取媒体信息
      const info = await this.player.getMediaInfo()
      this.duration = info.duration
      console.log('时长:', info.duration, '轨道:', info.tracks)
    },

    onInfo(detail) {
      // infoCode === 0:当前播放位置(ms)
      if (detail.infoCode === 0) {
        this.currentPosition = detail.extraValue
      }
    },

    onCompletion() {
      this.isPlaying = false
    },

    onError(detail) {
      uni.showToast({ title: '播放失败: ' + detail.errorMsg, icon: 'none' })
    },

    async togglePlay() {
      if (this.isPlaying) {
        await this.player.pause()
      } else {
        await this.player.play()
      }
      this.isPlaying = !this.isPlaying
    },

    async onSliderChange(e) {
      await this.player.seekTo(e.detail.value, SeekMode.INACCURATE)
    },

    formatTime(ms) {
      const s = Math.floor(ms / 1000)
      const m = Math.floor(s / 60)
      const ss = s % 60
      return `${String(m).padStart(2, '0')}:${String(ss).padStart(2, '0')}`
    }
  }
}
</script>

<style>
.container { flex: 1; background-color: #000; }
.controls  { padding: 20rpx; background-color: #fff; }
</style>

API 参考

AliPlayerFactory(工厂)

import { AliPlayerFactory } from '@/uni_modules/ali-player/js/uni.ali-player.js'

AliPlayerFactory.createAliPlayer([playerId])

创建普通播放器实例。

参数 类型 必填 说明
playerId string 播放器 ID,需与 <ali-player>player-id 属性一致;不传则自动生成 UUID

返回:AliPlayerInstance

AliPlayerFactory.createAliListPlayer([playerId])

创建列表播放器(适合短视频列表场景),拥有预加载、快速切换能力。

返回:AliListPlayerInstance


AliPlayerInstance(播放器实例)

播放源设置

方法 参数 说明
setUrl(url) url: string 设置 URL 播放源(MP4/M3U8/FLV/RTMP 等)
setVidAuth(options) 见下表 VidAuth 鉴权播放(推荐生产环境)
setVidSts(options) 见下表 STS 临时凭证播放

setVidAuth options:

参数 类型 必填 说明
vid string 阿里云点播视频 ID
playAuth string 播放凭证(服务端签发,有效期约 100s)
region string 接入区域,默认 cn-shanghai
definition string 指定清晰度:FD/LD/SD/HD/OD/2K/4K

setVidSts options:

参数 类型 必填 说明
vid string 视频 ID
region string 接入区域
accessKeyId string STS AccessKeyId
accessKeySecret string STS AccessKeySecret
securityToken string STS SecurityToken

播放控制

方法 说明 返回
prepare() 准备播放(设置播放源后调用) Promise
play() 开始 / 恢复播放 Promise
pause() 暂停(调用 play() 恢复) Promise
stop() 停止(需重新 prepare() 才可播放) Promise
seekTo(position, seekMode?) Seek 到指定位置(毫秒) Promise
reload() 重新加载当前播放源 Promise
release() 销毁播放器,释放所有原生资源 Promise

seekTo 参数说明:

参数 类型 说明
position number 目标时间(毫秒)
seekMode SeekMode ACCURATE(精准,较慢)/ INACCURATE(跳至关键帧,较快,默认)

播放参数

方法 参数 说明
setAutoPlay(autoPlay) boolean 是否自动播放(在 prepare() 前调用)
setLoop(loop) boolean 循环播放
setMute(mute) boolean 静音
setVolume(volume) 0.0 ~ 1.0 音量
setRate(rate) 0.5 / 1.0 / 1.5 / 2.0 播放速率
setScalingMode(mode) ScalingMode 缩放模式
setRotateMode(degree) RotateMode 旋转角度
setMirrorMode(mode) MirrorMode 镜像模式

播放器配置

// setConfig —— 需在 prepare() 前调用
await player.setConfig({
  startBufferDuration: 500,     // ms,起播缓冲
  highBufferDuration:  3000,    // ms,高水位缓冲
  maxBufferDuration:   50000,   // ms,最大缓冲
  maxDelayTime:        5000,    // ms,最大延迟(直播场景)
  networkTimeout:      15000,   // ms,网络超时
  networkRetryCount:   3,       // 网络重试次数
  referrer:            'https://example.com',
  httpProxy:           'http://proxy:8080',
  enableSEI:           false,   // 是否启用 SEI
  clearFrameWhenStop:  true,    // 停止后是否清空画面
  disableVideo:        false,   // 纯音频时设为 true
  disableAudio:        false
})

// setCacheConfig —— 边播边缓存(需在 prepare() 前调用)
await player.setCacheConfig({
  enable:       true,
  maxSizeMB:    200,            // 最大缓存总容量(MB)
  maxDurationS: 3600,           // 单文件最大缓存时长(秒)
  dir:          '/path/to/cache'
})

播放状态查询

方法 返回 说明
getCurrentPosition() Promise<number> 当前播放位置(ms)
getDuration() Promise<number> 视频总时长(ms)
getPlayerState() Promise<{state, stateName}> 当前播放器状态
getMediaInfo() Promise<MediaInfo> 媒体信息(prepared 事件后可用)
selectTrack(trackIndex) Promise 切换清晰度轨道;-1 = 自动 ABR
snapshot() Promise 截图(结果通过 snapshot 事件返回)

MediaInfo 结构:

{
  title:    string,       // 视频标题
  duration: number,       // 总时长(ms)
  coverUrl: string,       // 封面地址
  tracks: [{
    trackIndex:   number, // 轨道索引(用于 selectTrack)
    trackType:    string, // 'video' | 'audio'
    trackBitrate: number,
    videoWidth:   number,
    videoHeight:  number,
    definition:   string  // 'FD'|'LD'|'SD'|'HD'|'OD'|'2K'|'4K'
  }]
}

AliListPlayerInstance(列表播放器)

继承 AliPlayerInstance 全部方法,额外提供:

方法 参数 说明
addUrlSource(url, uid) url: string, uid: string 添加 URL 播放源
addVidSource(vid, uid) vid: string, uid: string 添加 VID 播放源
removeSource(uid) uid: string 移除指定播放源
setPreloadCount(count) count: number 设置预加载数量(建议 2~3)
moveTo(uid, stsInfo?) uid: string 切换播放指定 UID 的视频

AliPlayer(全局静态方法)

import { AliPlayer } from '@/uni_modules/ali-player/js/uni.ali-player.js'

日志

方法 参数 说明
setLogLevel(level) 'verbose'|'debug'|'info'|'warn'|'error'|'none' 设置 SDK 日志等级
enableConsoleLog(enable) boolean 开启 / 关闭控制台日志

画中画

方法 参数 说明
enterPip(playerId, videoWidth?, videoHeight?, callback?) 进入画中画(Android 8.0+、iOS 15+)
exitPip(playerId, callback?) 退出画中画
isInPipMode(playerId, callback) callback: (result) => void 查询是否处于画中画,result.inPip: boolean

熄屏/锁屏播放

方法 参数 说明
enableKeepPlayingOnScreenOff(playerId, callback?) 启用熄屏保活(开始播放后调用)
disableKeepPlayingOnScreenOff(playerId, callback?) 释放保活(暂停/完成/出错时调用)

ali-player 组件

<ali-player
  ref="aliPlayer"
  player-id="main-player"
  :width="750"
  :height="422"
  background-color="#000000"
  @prepared="onPrepared"
  @renderingStart="onRenderingStart"
  @stateChanged="onStateChanged"
  @info="onInfo"
  @completion="onCompletion"
  @error="onError"
  @loadingBegin="onLoadingBegin"
  @loadingProgress="onLoadingProgress"
  @loadingEnd="onLoadingEnd"
  @seekComplete="Complete"
  @videoSizeChanged="onVideoSizeChanged"
  @trackChanged="d"
  @snapshot="onSnapshot"
  @pipStateChanged="onPipStateChanged"
  @audioFocusChanged="onAudioFocusChanged"
/>

Props:

属性 类型 默认值 说明
player-id string 'default' 播放器 ID,必须与 AliPlayerFactory.createAliPlayer 传入的 playerId 一致
width number / string 750 宽度(rpx 或带单位字符串)
height number / string 422 高度
background-color string '#000000' 播放器背景色

常量

import {
  PlayerState,
  SeekMode,
  ScalingMode,
  RotateMode,
  MirrorMode,
  InfoCode
} from '@/uni_modules/ali-player/js/uni.ali-player.js'

// 播放器状态
PlayerState.IDLE        // 'idle'        — 空闲
PlayerState.INITIALIZED // 'initialized' — 已初始化
PlayerState.PREPARED    // 'prepared'    — 准备完成
PlayerState.STARTED     // 'started'     — 播放中
PlayerState.PAUSED      // 'paused'      — 已暂停
PlayerState.STOPPED     // 'stopped'     — 已停止
PlayerState.COMPLETION  // 'completion'  — 播放完成
PlayerState.ERROR       // 'error'       — 错误

// Seek 模式
SeekMode.ACCURATE       // 精准 seek(帧级别,较慢)
SeekMode.INACCURATE     // 非精准 seek,跳至最近关键帧(较快,推荐)

// 缩放模式
ScalingMode.SCALE_TO_FILL  // 拉伸填充(会变形)
ScalingMode.ASPECT_FIT     // 等比缩放,留黑边
ScalingMode.ASPECT_FILL    // 等比缩放填满,裁剪超出部分

// 旋转角度
RotateMode.ROTATE_0    // 不旋转
RotateMode.ROTATE_90   // 顺时针 90°
RotateMode.ROTATE_180  // 顺时针 180°
RotateMode.ROTATE_270  // 顺时针 270°

// 镜像模式
MirrorMode.NONE        // 不镜像
MirrorMode.HORIZONTAL  // 水平镜像
MirrorMode.VERTICAL    // 垂直镜像

// info 事件码(detail.infoCode)
InfoCode.CURRENT_POSITION    // 0 — 当前播放位置(extraValue 单位 ms)
InfoCode.BUFFERED_POSITION   // 1 — 缓冲位置
InfoCode.AUTO_PLAY_START     // 2 — 自动播放开始
InfoCode.LOOPING_START       // 3 — 循环播放重头开始
InfoCode.NETWORK_RETRY       // 5 — 网络重试
InfoCode.NETWORK_BANDWIDTH   // 6 — 当前网络带宽(extraValue 单位 bps)

事件参考

事件名 detail 结构 说明
prepared { playerId } 准备完成,此时可调用 getMediaInfo()
renderingStart { playerId } 首帧画面渲染,可在此隐藏封面图
stateChanged { playerId, state, stateName } 播放状态变化(见 PlayerState)
videoSizeChanged { playerId, width, height, rotation } 视频分辨率或旋转角度变化
loadingBegin { playerId } 开始缓冲(转圈)
loadingProgress { playerId, percent, netSpeed } 缓冲进度(0~100,netSpeed 单位 kbps)
loadingEnd { playerId } 缓冲结束
seekComplete { playerId } Seek 完成
info { playerId, infoCode, infoCodeName, extraValue, extraMsg } 播放器信息回调(进度/缓冲/带宽等)
completion { playerId } 点播播放完成
error { playerId, errorCode, errorMsg, errorExtra } 播放错误
trackChanged { playerId, success, trackIndex, trackType } 清晰度切换结果
snapshot { playerId, path } 截图完成,path 为本地文件路径
pipStateChanged { playerId, pipState, message } PiP 状态变化(见下方说明)
audioFocusChanged { playerId, focusChange } Android AudioFocus 变化(见下方说明)

pipState 值说明:

说明
willEnter 即将进入画中画
entered 已进入画中画
willExit 即将退出画中画
exited 已退出画中画,回到 App
restoring 从 PiP 还原到全屏
error 进入 PiP 失败
unsupported 系统不支持 PiP(< Android 8.0 / < iOS 15)

focusChange 值说明(Android):

说明
GAIN 重新获得音频焦点(可继续播放)
LOSS 永久失去焦点(建议停止播放)
LOSS_TRANSIENT 临时失去焦点(建议暂停)
LOSS_TRANSIENT_CAN_DUCK 短暂被抢占(可降低音量继续)

进阶用法

多实例播放

页面内同时渲染多个播放器,各自独立,通过不同的 playerId 区分:

<template>
  <!-- #ifdef APP-PLUS -->
  <ali-player player-id="player-1" :width="375" :height="211" @prepared="() => onReady(1)" />
  <ali-player player-id="player-2" :width="375" :height="211" @prepared="() => onReady(2)" />
  <!-- #endif -->
</template>

<script>
// #ifdef APP-PLUS
import { AliPlayerFactory } from '@/uni_modules/ali-player/js/uni.ali-player.js'
// #endif

export default {
  onLoad() {
    // #ifdef APP-PLUS
    this.player1 = AliPlayerFactory.createAliPlayer('player-1')
    this.player2 = AliPlayerFactory.createAliPlayer('player-2')

    this.player1.setUrl('https://example.com/video1.mp4')
    this.player1.prepare()

    this.player2.setUrl('https://example.com/video2.mp4')
    this.player2.prepare()
    // #endif
  },
  onUnload() {
    this.player1?.release()
    this.player2?.release()
  }
}
</script>

列表/短视频播放

// #ifdef APP-PLUS
import { AliPlayerFactory } from '@/uni_modules/ali-player/js/uni.ali-player.js'

const listPlayer = AliPlayerFactory.createAliListPlayer('list-player')

// 设置预加载(建议 2~3,过多消耗内存)
await listPlayer.setPreloadCount(3)

// 批量添加播放源
const videos = [
  { url: 'https://cdn.example.com/v1.mp4', uid: 'video_001' },
  { url: 'https://cdn.example.com/v2.mp4', uid: 'video_002' },
  { url: 'https://cdn.example.com/v3.mp4', uid: 'video_003' },
]
for (const v of videos) {
  await listPlayer.addUrlSource(v.url, v.uid)
}

// 播放第一个
await listPlayer.moveTo('video_001')

// 滑动到下一个
await listPlayer.moveTo('video_002')
// #endif

直播播放

// RTMP
await player.setUrl('rtmp://live.example.com/live/stream')

// HLS
await player.setUrl('https://live.example.com/live/stream.m3u8')

// FLV
await player.setUrl('https://live.example.com/live/stream.flv')

// RTS 超低延时(需引入 RTS SDK)
await player.setUrl('artc://live.example.com/live/stream')

// 直播推荐配置(低延迟优先)
await player.setConfig({ maxDelayTime: 5000, maxBufferDuration: 5000 })
await player.prepare()

本地缓存下载

// 在 prepare() 前配置,首次播放后相同 URL 自动读本地缓存
const cacheDir = plus.io.convertLocalFileSystemURL('_doc/video_cache/')

await player.setCacheConfig({
  enable:       true,
  maxSizeMB:    500,     // 最大 500 MB
  maxDurationS: 7200,    // 单文件最大 2 小时
  dir:          cacheDir
})

await player.setUrl('https://example.com/video.mp4')
await player.prepare()

画质切换

async function onPrepared() {
  const info  = await player.getMediaInfo()
  const tracks = info.tracks.filter(t => t.trackType === 'video')
  console.log('可选清晰度:', tracks.map(t => t.definition))

  // 切换到 HD
  const hd = tracks.find(t => t.definition === 'HD')
  if (hd) await player.selectTrack(hd.trackIndex)

  // 开启自动码率(ABR)
  // await player.selectTrack(-1)
}

// 切换结果在 trackChanged 事件中返回

截图

<ali-player player-id="main" @snapshot="onSnapshot" />

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

画中画(PiP)

系统要求:Android 8.0+(API 26)/ iOS 15+
必须完成 iOS Background Modes 配置,否则进入后台后 PiP 窗口会消失。

// #ifdef APP-PLUS
import { AliPlayer } from '@/uni_modules/ali-player/js/uni.ali-player.js'

// 进入画中画(视频宽高比 16:9)
AliPlayer.enterPip('main-player', 16, 9, (result) => {
  if (result.code !== 0) {
    console.error('进入 PiP 失败:', result.message)
  }
})

// 退出画中画
AliPlayer.exitPip('main-player')

// 查询是否处于画中画模式
AliPlayer.isInPipMode('main-player', (result) => {
  console.log('当前 PiP 状态:', result.inPip)
})
// #endif

监听 PiP 状态变化:

<ali-player
  player-id="main-player"
  @pipStateChanged="onPipStateChanged"
/>

<script>
methods: {
  onPipStateChanged(detail) {
    const { pipState, message } = detail
    if (pipState === 'entered') {
      // 已进入画中画,可隐藏自定义控制条
    } else if (pipState === 'exited') {
      // 已退出画中画,恢复 UI
    } else if (pipState === 'error' || pipState === 'unsupported') {
      uni.showToast({ title: message || '不支持画中画', icon: 'none' })
    }
  }
}
</script>

熄屏/锁屏播放

Android 需在 AndroidManifest.xml 中声明 WAKE_LOCK 权限(见 集成配置)。
iOS 需在 Info.plist 中加 UIBackgroundModes: audio,并在 Xcode 开启 Background Modes(见 iOS 配置)。

// #ifdef APP-PLUS
import { AliPlayer } from '@/uni_modules/ali-player/js/uni.ali-player.js'

// 开始播放后调用,申请保活锁
// Android: PARTIAL_WAKE_LOCK(CPU 保活,屏幕不亮)+ AudioFocus
// iOS: AVAudioSession category = .playback
AliPlayer.enableKeepPlayingOnScreenOff('main-player')

// 暂停 / 完成 / 出错时释放
AliPlayer.disableKeepPlayingOnScreenOff('main-player')
// #endif

💡 组件内已在 play() 时自动调用 enableKeepPlayingOnScreenOff,在 onCompletion / onError 时自动释放,通常无需手动调用。


License 配置(SDK 7.0.0+)

⚠️ 自 7.0.0 版本起,阿里云播放器 SDK 需要有效的 License 才能使用,否则会提示鉴权失败。

// 在 App.vue 的 onLaunch 中尽早配置
// #ifdef APP-PLUS
const aliModule = uni.requireNativePlugin('AliPlayer-AliPlayerModule')
if (aliModule && aliModule.setLicenseKey) {
  aliModule.setLicenseKey({
    licenseKey:  'YOUR_LICENSE_KEY',
    licenseFile: 'alivc_license'  // 证书文件名(Android,不含扩展名)
  })
}
// #endif

申请 License:阿里云点播播放器 License 申请


常见问题

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

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

Q3:iOS 播放 HTTP 地址报网络错误?
Info.plist 中添加 NSAllowsArbitraryLoads: true,或将视频地址改为 HTTPS。

Q4:切换播放源(换 URL)不生效?
需先 stop(),再重新 setUrl() + prepare()

await player.stop()
await player.setUrl('https://new-url.mp4')
await player.prepare()

Q5:如何监听播放进度?
通过 info 事件,infoCode === 0extraValue 即为当前播放位置(ms):

onInfo(detail) {
  if (detail.infoCode === 0) {
    this.currentPosition = detail.extraValue  // ms
  }
}

Q6:VidAuth 播放凭证过期怎么处理?
监听 error 事件,判断 errorCode 为凭证过期后,重新向服务端换取 PlayAuth,再调用 setVidAuth + prepare()

Q7:多实例内存占用高怎么办?

  • 不可见的播放器及时调用 pause()stop()
  • 页面卸载时必须调用 release() 释放原生资源
  • 列表场景使用 AliListPlayerInstance 配合 setPreloadCount 控制预加载数量(建议 ≤ 3)

Q8:PiP 进入后视频停止了怎么办?

  • iOS:检查是否已在 Xcode 开启 Background Modes → Audio, AirPlay, and Picture in Picture,以及 Info.plist 是否有 UIBackgroundModes: audio
  • Android:检查 AndroidManifest 的主 Activity 是否有 android:supportsPictureInPicture="true"

Q9:熄屏后音频也停了(iOS)?
检查 Info.plist 中是否有 UIBackgroundModes: audio,且 Xcode Background Modes 已勾选 Audio。

Q10:如何在页面隐藏(进后台)时不停止播放(Android)?
调用 enableKeepPlayingOnScreenOff 后,只要不调用 pause(),App 进后台时播放器会继续运行。如需后台通知栏控制,需配合前台 Service 实现,这不在本插件范围内。


更新日志

v1.1.0(2026-05-25)

新增功能:

  • 🆕 画中画(PiP):Android 8.0+ 和 iOS 15+ 系统级 PiP 支持
    • AliPlayer.enterPip() / exitPip() / isInPipMode()
    • 组件新增 @pipStateChanged 事件(willEnter / entered / willExit / exited / restoring / error / unsupported)
  • 🆕 熄屏/锁屏播放:Android WakeLock + AudioFocus;iOS AVAudioSession
    • AliPlayer.enableKeepPlayingOnScreenOff() / disableKeepPlayingOnScreenOff()
    • 组件新增 @audioFocusChanged 事件(Android AudioFocus 变化回调)
  • AliPlayerRegistry 新增 Component 注册表,支持 Module 调用 Component 层方法

优化:

  • VideoPlayer.nvue 自动在 play() 时申请保活锁,在 onCompletion / onError 时释放

v1.0.0(2026-05-20)

  • 🎉 首次发布
  • 支持 URL / VidAuth / VidSts 三种播放源
  • 支持点播、直播、列表播放
  • 支持截图、本地缓存、画质切换、续播
  • 双端完整实现(Android Java + iOS Objective-C)
  • JS 工厂模式(AliPlayerFactory),API 对齐阿里云 Flutter SDK 规范

版本:v1.1.0 | 对应阿里云播放器 SDK:7.14.0 | 最低 HBuilderX:3.0.0

隐私、权限声明

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

INTERNET(网络访问);ACCESS_NETWORK_STATE/ACCESS_WIFI_STATE(网络状态检测);WAKE_LOCK(熄屏保活,可选);READ/WRITE_EXTERNAL_STORAGE(本地缓存,可选,Android 9 及以下);FOREGROUND_SERVICE(后台播放,可选)

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

本插件不采集用户数据。阿里云播放器 SDK 内部可能上报匿名播放质量日志(需阿里云账号开启),请参阅阿里云隐私政策。

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

许可协议

MIT协议

暂无用户评论。