更新记录

1.3.2(2026-10-15)

新增更详细的错误日志

1.3.1(2026-09-23)

1.新增倍速切换回调事件speed-change; 2.优化播放器的部分功能

1.3.0(2026-09-22)

1.新增弹幕功能 2.新增直播属性,如果是直播,请将isLive设置为true,播放器将自动对于直播进行优化策略 3.新增自定义播放器背景色属性 4.优化直播artc超低延迟 5.新增其他功能,详情见文档

查看更多

平台兼容性

uni-app(4.61)

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

uni-app x(4.61)

Chrome Safari Android iOS 鸿蒙 微信小程序
- - 5.0 12 - -

axiang-aliplaye

基于阿里云播放器 SDK(AliPlayer)封装的 uni-app UTS 原生组件,支持 Android 和 iOS。适用于 nvue 页面,提供完整的视频播放能力。

✨ 核心特性

  • 📺 多格式支持 — 支持 MP4, RTMP, ARTC, FLV, M3U8, RTS, DASH, MKV, AVI等多种视频及直播流媒体
  • 🎬 完整播放控制 — 播放、暂停、停止、跳转、倍速、循环
  • 📱 全屏支持 — 自动横竖屏适配,流畅的全屏切换体验
  • 🪟 画中画悬浮窗 — 支持退出应用时无缝进入桌面画中画及 iOS 后台播放
  • 🎯 手势操作 — 左右滑动调进度、上下滑动调音量、双击播放/暂停
  • 💬 高性能弹幕系统 — 原生多轨防重叠弹幕渲染,支持动态追加与自动清理,支持全屏横竖屏重排
  • ⚡ 初始播放位置 — 直接从指定位置起播,避免先加载再跳转
  • 🎨 灵活 UI 控制 — 各控制元素独立显隐,支持完全自定义覆盖层
  • 📊 实时进度回调 — 500ms 粒度进度上报,轻松实现续播
  • 🖼️ 首帧事件 — firstFrame 事件精准通知首帧渲染完成,方便页面侧控制封面

使用前提

  • 仅 App 端原生组件场景使用,页面建议使用 nvue
  • 修改 utssdk/app-android 或 utssdk/app-ios 后,需重新制作自定义基座
  • iOS / Android 均依赖原生 SDK,云打包或自定义基座配置需保持完整

License 授权配置

阿里云播放器 SDK 需要有效的 License 才能正常工作(否则可能会导致起播失败、黑屏等)。请按如下步骤配置您的 License:

🤖 Android 端配置

  1. 放置证书文件: 将您获取到的 .crt 证书文件重命名为 license.crt,并放置在插件的如下目录中(如果没有对应的文件夹请手动创建): uni_modules/axiang-aliplaye/utssdk/app-android/assets/cert/license.crt
  2. 配置 License Key: 打开配置文件:uni_modules/axiang-aliplaye/utssdk/app-android/AndroidManifest.xml。 找到 <application> 标签下的 meta-data,将其中的 value 替换为您真实的 License Key:
    <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/license.crt" />

🍎 iOS 端配置

  1. 放置证书文件: 将您获取到的 .crt 证书文件重命名为 license.crt,并放置在插件的如下目录中(如果没有对应的文件夹请手动创建): uni_modules/axiang-aliplaye/utssdk/app-ios/Resources/cert/license.crt
  2. 配置 License Key: 打开配置文件:uni_modules/axiang-aliplaye/utssdk/app-ios/info.plist。 找到对应的 <string> 标签,替换为您真实的 License Key:
    <key>AlivcLicenseKey</key>
    <string>您的 LicenseKey</string>
    <key>AlivcLicenseFile</key>
    <string>cert/license.crt</string>

[!WARNING] 修改配置或替换证书后,必须重新提交云打包或重新制作自定义基座才能生效!


快速开始

<template>
  <view class="page">
    <!-- 播放器 -->
    <view style="position: relative;">
      <axiang-aliplaye
        ref="player"
        class="player-view"
        :videoUrl="videoUrl"
        :autoplay="true"
        :loop="false"
        :initialPosition="lastPosition"
        @firstFrame="showPoster = false"
        @progress-update="handleProgressUpdate"
        @playbackComplete="handleComplete" />

      <!-- 页面侧封面图(首帧渲染后自动隐藏) -->
      <image v-if="showPoster" :src="posterUrl"
        style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
        mode="aspectFill" />
    </view>
  </view>
</template>

<script>
  export default {
    data() {
      return {
        videoUrl: 'https://example.com/video.mp4',
        posterUrl: 'https://example.com/cover.jpg',
        showPoster: true,
        lastPosition: 0,
        currentPosition: 0,
        duration: 0
      }
    },
    onLoad() {
      this.lastPosition = uni.getStorageSync('lastPosition') || 0
    },
    methods: {
      handleProgressUpdate(e) {
        const detail = e?.detail?.detail || e?.detail
        if (detail) {
          this.currentPosition = detail.position / 1000
          this.duration = detail.duration / 1000
        }
      },
      handleComplete() {
        uni.setStorageSync('lastPosition', 0)
      }
    },
    onUnload() {
      if (this.currentPosition > 0 && this.currentPosition < this.duration) {
        uni.setStorageSync('lastPosition', this.currentPosition)
      }
    }
  }
</script>

<style>
  .player-view {
    width: 750rpx;
    height: 422rpx;
  }
</style>

Props

属性 类型 默认值 说明
videoUrl String '' 视频播放地址
videourl String '' 小写兼容属性,与 videoUrl 功能相同
autoplay Boolean true 是否自动播放
loop Boolean false 是否循环播放
isLive Boolean false 是否为直播流。设为 true 时,底层播放器会关闭本地缓存(防卡顿)并应用纯直播优化策略
initialPosition Number 0 初始播放位置(秒),用于续播场景
control String '' 播放控制指令:play / pause / stop
seekToSeconds Number -1 跳转到指定秒数
seektoseconds Number -1 小写兼容属性
showPlayButton Boolean true 是否显示播放/暂停按钮
showProgressBar Boolean true 是否显示进度条
showProgressText Boolean true 是否显示时间文本(当前时间/总时间)
showSpeedButton Boolean true 是否显示倍速按钮
showFullscreenButton Boolean true 是否显示全屏按钮
showControlBar Boolean true 是否显示整个底部控制栏
enableDoubleTap Boolean true 是否开启双击播放/暂停
enableSwipe Boolean true 是否开启左右滑动调节进度
enableVolumeSwipe Boolean true 是否开启上下滑动调节音量
enableAutoPiP Boolean false 是否允许退回桌面时自动进入悬浮框画中画
loadingText String "加载中..." 自定义加载中文案
completeText String "视频播放完成" 自定义播放完成文案
errorText String "视频播放失败,请稍后重试" 自定义错误提示文案
objectFit String 'contain' 视频画面缩放模式,可选:contain(等比缩放留黑边)、cover(等比填充裁剪)、fill(拉伸填满)
enableDanmu Boolean true 是否开启弹幕显示(开启时自动接收并显示,关闭时立刻清空当前屏幕弹幕)
danmakuPayload String '[]' 最新弹幕 JSON 数据,支持单项、数组或包含 messages/items/list 列表的对象
bgColor String "#000000" 播放器底层视频背景色(十六进制),常用于竖屏视频的黑边颜色自定义
useExternalFullscreen Boolean false 是否使用外部全屏模式(开启后点击全屏按钮只抛出 fullscreen-request 事件,由外层业务进行全屏旋转)
externalFullscreenActive Boolean false 配合 useExternalFullscreen,由外部控制当前是否已处于全屏状态

initialPosition — 初始播放位置

支持设置初始播放位置,用于视频续播场景。

优势:

  • 播放器直接从指定位置起播,不会先从头加载再跳转
  • 启动速度提升 50-60%,节省流量
  • 无闪烁,用户体验好

注意:单位是秒,仅在首次加载时生效,后续通过 seekTo() 跳转。


Events

事件名 说明 参数
firstFrame 首帧渲染完成 无
progress-update 播放进度更新(每 500ms) detail.position、detail.duration(毫秒,字符串)
landscape-update 视频横竖屏信息更新 detail.value('true' 或 'false')
playbackComplete 播放完成 无
error 播放错误 无
loopingStart 循环播放重新开始 无
singleTap 单击播放器区域 无
doubleTap 双击播放器区域 无
fullscreen-request 请求进入/退出外部全屏(需开启 useExternalFullscreen) detail.entering (布尔), detail.isLandscape ('true' / 'false')
speed-change 播放倍速切换 detail.rate(倍数值,字符串,如 '1.5')

firstFrame — 首帧渲染完成事件

当播放器渲染出第一帧画面时触发。推荐用于控制封面图的隐藏时机。

封面图建议在页面侧实现(而非插件内部),这样可以自由控制封面的样式、动画和交互:

<view style="position: relative;">
  <axiang-aliplaye ref="player" :videoUrl="url" @firstFrame="showPoster = false" />
  <image v-if="showPoster" :src="coverUrl"
    style="position: absolute; top: 0; left: 0; width: 100%; height: 100%;"
    mode="aspectFill" />
</view>

如果需要切换视频时重新显示封面,在切换前将 showPoster 设为 true 即可:

switchVideo(newUrl) {
  this.showPoster = true       // 先显示封面
  this.videoUrl = newUrl       // 切换视频,首帧渲染后 showPoster 自动变为 false
}

进度事件参数说明

iOS 兼容模式下事件参数使用双层 detail 结构,页面侧需兼容读取:

handleProgressUpdate(e) {
  const detail = e?.detail?.detail || e?.detail
  if (!detail) return
  this.currentPosition = detail.position / 1000  // 转换为秒
  this.duration = detail.duration / 1000
}

横竖屏事件参数说明

建议监听 landscape-update 事件缓存结果:

handleLandscapeUpdate(e) {
  const detail = e?.detail?.detail || e?.detail
  if (detail) {
    this.isLandscape = detail.value === 'true'
  }
}

Methods

通过 ref 获取组件实例后调用。

方法 参数 说明
loadSource(url, autoplay) url: string, autoplay: boolean 加载新视频源
play() — 开始播放
pause() — 暂停播放
togglePlayPause() — 切换播放/暂停
stopVideo() — 停止播放
seekTo(seconds) seconds: number 跳转到指定秒数
setStartPosition(seconds) seconds: number 设置起播位置(需配合重新加载)
setSpeed(speed) speed: number 设置播放倍速(范围 0-3)
enterFullScreen() — 进入全屏
exitFullScreen() — 退出全屏
getCurrentPosition() — 当前播放进度(毫秒)
getDuration() — 视频总时长(毫秒)
getIsLandscapeText() — 是否横屏视频,返回 'true' / 'false'
isLandscape() — 同 getIsLandscapeText(),兼容旧方法
enterPiPMode() — 手动触发进入画中画(悬浮窗)模式
pushDanmaku(payload) payload: string 向弹幕轨道追加新的弹幕 JSON 字符串
clearDanmaku() — 立刻清空当前屏幕上的所有弹幕
updateDanmakuMetrics() — 重新计算和下发弹幕轨道尺寸信息(屏幕旋转时建议调用)

使用示例

methods: {
  // 播放控制
  handlePlay() {
    this.$refs.player?.play()
  },
  handlePause() {
    this.$refs.player?.pause()
  },

  // 进度跳转
  handleSeek() {
    this.$refs.player?.seekTo(60)  // 跳转到 60 秒
  },

  // 倍速控制(范围 0-3,超出范围会被忽略)
  handleSetSpeed() {
    this.$refs.player?.setSpeed(1.5)
  },

  // 全屏
  handleFullscreen() {
    this.isFullscreen
      ? this.$refs.player?.exitFullScreen()
      : this.$refs.player?.enterFullScreen()
    this.isFullscreen = !this.isFullscreen
  }
}

旧版方法兼容

旧方法 等价新方法
playVideo() play()
pauseVideo() pause()
seekVideo(seconds) seekTo(seconds)

画中画 (Picture-in-Picture)

组件支持在 Android 12+ 上无缝切换为桌面画中画(悬浮窗)播放,并在 iOS 上支持退至后台时的音频续播(由于深度集成,在 iOS 上表现为激活 UIBackgroundModes: audio 确保音频不中断)。

有两种方式可以控制画中画的开启:

1. 属性自动控制 (推荐)

通过 :enableAutoPiP="true" 绑定。如果在页面中存在多个播放器,可以利用动态属性控制哪个播放器具有悬浮权限:

<axiang-aliplaye 
  ref="player1"
  :enableAutoPiP="currentPlayer === 1"
/>

当系统检测到用户退回桌面时,只有属性为 true 的播放器会自动变成画中画。

2. 手动调用控制

可以在代码里(如点击某个按钮或监听 onHide 生命周期)主动调用:

this.$refs.player?.enterPiPMode()

手势操作

手势 功能 控制属性
左右滑动 调节播放进度(最大 ±3 分钟) enableSwipe
上下滑动 调节播放音量(0-100%) enableVolumeSwipe
双击 播放/暂停切换 enableDoubleTap
单击 显示/隐藏控制栏 —
  • 滑动调进度时,屏幕中央会显示目标时间和进度条提示
  • 滑动调音量时,屏幕中央会显示音量百分比提示
  • 播放中控制栏会在 2.5 秒后自动隐藏,暂停时保持显示

禁用所有手势:

<axiang-aliplaye
  :enableDoubleTap="false"
  :enableSwipe="false"
  :enableVolumeSwipe="false" />

自动初始化

组件在原生视图创建完成后自动加载视频:

页面渲染 → NVLoad 创建原生播放器 → NVLoaded 应用配置并 load(videoUrl)

正常场景下无需在 onReady 中手动调用 loadSource,直接传入 :videoUrl 即可。


平台差异

差异点 iOS Android
原生实现 AxiangAliplayeView.swift AxiangAliplayeFacade.kt
组件入口 utssdk/app-ios/index.vue utssdk/app-android/index.vue
原生视图访问 this.$el this.mNativePlayer
布尔属性初始应用 NVLoaded NVLoad / watch
进度方法返回类型 字符串毫秒值 数字毫秒值
初始播放位置 setStartTime() setStartTime() + 延迟 seek

常见问题

1. 如何实现视频续播?

使用 initialPosition 属性 + progress-update 事件:

data() {
  return {
    videoUrl: 'https://example.com/video.mp4',
    initialPosition: 0
  }
},
onLoad() {
  this.initialPosition = uni.getStorageSync('video_position') || 0
},
methods: {
  handleProgressUpdate(e) {
    const detail = e?.detail?.detail || e?.detail
    if (detail) {
      this.currentPosition = detail.position / 1000
    }
  }
},
onUnload() {
  if (this.currentPosition > 0) {
    uni.setStorageSync('video_position', this.currentPosition)
  }
}

2. 如何实现封面图?

使用 firstFrame 事件控制页面侧封面的显隐(参见 firstFrame 事件说明)。

3. 如何自定义播放器 UI?

通过 props 控制各 UI 元素显隐:

<axiang-aliplaye
  :showPlayButton="false"
  :showProgressBar="true"
  :showProgressText="true"
  :showSpeedButton="false"
  :showFullscreenButton="true"
  :showControlBar="true" />

如需完全自定义控制栏,设置 :showControlBar="false" 后自行叠加 UI 层,通过 ref 调用方法控制播放。

4. iOS 编译报错 NSNumber? 类型问题?

UTS 编译器的类型映射问题,使用 Int64 类型和 as Int64 显式转换解决。

详见: uni_modules/axiang-aliplaye/docs/iOS_UTS_NSNumber_Issue.md


注意事项

  1. ⚠️ 修改原生侧代码后必须重新制作自定义基座
  2. 📱 建议使用 v-if 控制播放器创建和销毁,避免复用状态异常
  3. ⏱️ seekTo 参数单位是秒,进度事件和 getCurrentPosition() / getDuration() 返回单位是毫秒
  4. 💾 建议监听 progress-update 缓存进度值,需要时直接读取
  5. 🍎 iOS 全屏依赖内置的 AxiangAliplayeFullscreenController,确保 iOS 原生文件完整参与打包
  6. 🖼️ 封面图在页面侧实现,监听 firstFrame 事件控制隐藏时机

更新日志

查看 CHANGELOG.md 了解详细版本更新记录。

技术文档

许可证

MIT License

隐私、权限声明

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

无

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

无

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

无