更新记录
1.3.2(2026-10-11)
- 整理 README 与 API 文档中的示例和文档引用,改为展示可复制的
uni_modules/lizhao-video-feed/...路径,避免使用本地文件跳转。
1.3.1(2026-10-10)
- 统一 uni-app / uni-app x 的内嵌示例控制,补齐跳转、倍速、静音、状态读取、Tab 活跃、卸载重建与全屏打开;保留 App 原媒体输入及生命周期调用。
- 修复微信内嵌示例重建后的静音状态失步及旧会话事件覆盖,插件首页按平台进入对应功能菜单。
- 修复微信旧
description简介字段兼容、关闭评论面板后的有效主动快照回写,以及空列表搜索和频道动作。 - 修复 iOS 错误手动重试丢失已确认进度,正常结束重播仍从头开始;统一双宿主 iOS 返回按钮和标题位置。此项需匹配当前源码的 iOS 原生包。
- 校正微信能力说明及评论示例文案,保留微信首帧事件、倍率、路径和错误诊断边界。
1.3.0(2026-10-10)
- 新增微信小程序原生视频流,兼容 uni-app Vue2 / Vue3 和 uni-app x,沿用全屏、内嵌、连续滑动、邻项封面、互动评论、分页、短剧选集、试看与业务回写接口。
- 新增与安卓一致的微信功能菜单,以及六种微信倍率、微信本地 MP4 路径和有限断网恢复;微信不提供严格首帧事件,能力与接入边界见平台说明。
- 统一 Android / iOS 右侧头像关注徽标、实心互动图标、间距和单行数量格式,保留自定义图标、文案及宿主确认后的状态回写。
- 修复 iOS 上下拖动时相邻封面固定在后方的问题,当前页与相邻页沿同一轨道首尾连接,并修复关注徽标前景被着色遮盖。
- 完善 iOS 上下邻项封面预取和切页承接,补齐移动页面及视频层裁剪;图片失败保留同身份已显示封面,本地 MP4 可使用静态首帧兜底。
- 修复 iOS 内嵌组件原始属性和嵌套事件丢失,以及播放失败事件缺少结构化错误详情的问题。
- 新增 Android / iOS 播放临时网络故障自动恢复,可配置额外尝试 0 至 3 次,并按 1、2、4 秒退避恢复播放位置、倍率、静音和播放意图。
- 新增结构化重试状态与脱敏失败分类,业务可展示等待、尝试、恢复、耗尽和取消结果,不暴露视频地址、请求头或原生异常原文。
- 新增 uni-app / uni-app x 弱网自动恢复示例、配置说明与 API 参考;默认关闭自动恢复,原有播放行为保持不变。
- 修复 Android uni-app 路由遗漏
maxPlaybackRetries,导致配置在进入原生运行时前丢失的问题。 - 修复 Android uni-app nvue 内嵌组件初始属性被二次 JSON 编码,以及事件重复透传导致状态异常和页面控制失效的问题。
- 修复 iOS 从普通 JavaScript 参数打开视频流时,嵌套互动动作、选集按钮及媒体请求头数组缺少元素映射可能触发闪退的问题。
- 修复 iOS 省略开关时自动播放、活跃状态、循环策略及界面默认值丢失,以及追加分页覆盖原有分页状态的问题;显式 false 保持生效。
- 修复超出安全整数范围的剧集编号和计数进入 iOS 原生界面转换的问题,非法数值统一返回参数错误。
平台兼容性
uni-app(5.24)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| √ | √ | × | × | √ | √ | √ | √ | - |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | × | × | × | × | × | × | × | × | × | × | × |
uni-app x(5.24)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| × | × | √ | √ | - | √ |
其他
| 多语言 | 暗黑模式 | 宽屏模式 | 蒸汽模式 |
|---|---|---|---|
| × | × | × | √ |
lizhao-video-feed · 原生短视频流与短剧播放器
介绍
让你的应用快速拥有沉浸式短视频流与短剧播放体验。
lizhao-video-feed 面向 uni-app / uni-app x 提供原生全屏视频流和页面内播放器。用户可上下滑动切换作品,查看作者与互动信息,打开评论和短剧选集,并使用倍速、清屏、试看与自动连播。
播放、手势和业务面板由原生视图承载,无需在页面中拼装 video 或 swiper。视频、作者、评论、点赞、收藏、分享、解锁和分页数据由接入项目提供;插件通过事件发出请求,并在业务确认后更新界面。
支持 Android 6.0 及以上、iOS 13.0 及以上与微信小程序。微信使用原生视频组件、VideoContext 和 WXS 手势,沿用同一套公开 API 和业务回写。接入后请在目标设备验证全屏、页面内嵌与所用媒体编码;Harmony 当前仍为预览实现。
功能特色
| 特色功能 | 能解决什么问题 | 相关配置 / 事件 |
|---|---|---|
| 原生视频流 | 推荐流、作品详情、全屏浏览 | openVideoFeed、switchTo、change |
| 短剧 | 指定集起播、选集、自动连播、最后一集停止 | mode: 'drama'、episodechange |
| 试看与锁定 | 锁定项展示解锁入口,试看截止暂停 | drama.locked、trialend、action |
| 业务互动 | 作者、关注、赞、评、藏、分享与搜索 | action、updateItem |
| 评论面板 | 首次加载、追加、重试、发送评论请求 | commentsrequest、setComments |
| 分页 | 临近末尾请求后续内容,空页/失败可重试 | loadmore、resolveLoadMore |
| 播放控制 | 暂停、继续、跳转、基础倍率与静音 | play、pause、seek、setRate |
| HLS 点播 | 在同一列表混排 MP4、TS HLS 与 fMP4 HLS | source.mediaType、hls |
| 弱网自动恢复 | 临时断网或超时后进行有限次额外尝试 | maxPlaybackRetries、state.retry |
| 页面嵌入 | 宿主自定义顶部、底部、Tab 与页面布局 | <lizhao-video-feed> |
| 生命周期 | 保留主动暂停,离开 Tab 停播,同组互斥 | setActive、playbackGroup |
| 有界预载 | 当前项与下一项,最多两个原生播放器 | maxPlayerCount、preloadCount |
适合哪些场景
| 场景 | 推荐能力 | 说明 |
|---|---|---|
| 短视频推荐流 | 原生视频流、上下滑动、有界预载 | 适合首页推荐、发现页和作品连续浏览 |
| 短剧与连续剧集 | 选集、自动连播、已看状态 | 从指定剧集起播,展示剧集信息并控制连播边界 |
| 试看与内容解锁 | trialEndMs、locked、action |
插件负责界面和播放门禁,订单与授权由业务服务处理 |
| 社区互动视频 | 点赞、关注、收藏、分享、评论 | 用户操作通过事件交给业务,确认成功后再回写真实状态 |
| 分页内容流 | loadmore、resolveLoadMore |
临近末尾请求下一页,支持空结果、失败和重试 |
| 弱网视频播放 | maxPlaybackRetries、diagnostic |
临时网络失败后有限恢复,并向业务提供脱敏失败分类 |
| 自定义业务页面 | <lizhao-video-feed> 页面内嵌 |
由宿主保留自己的导航栏、底部栏、Tab 和业务区域 |
| 详情页或单条播放 | 单条列表、播放控制、生命周期 | 可从指定作品起播,并与页面显示、隐藏和销毁同步 |
下载与导入
- 在插件市场选择“使用 HBuilderX 导入插件”,导入到自己的 uni-app 或 uni-app x 项目。
- 保留完整的
uni_modules/lizhao-video-feed目录和插件名称。 - 在页面脚本中从插件根目录导入:
import { openVideoFeed, closeVideoFeed, createVideoFeedContext, getVideoFeedCapabilities } from '@/uni_modules/lizhao-video-feed'
请使用包含当前插件版本原生代码与依赖的 Android App、iOS App / IPA 或 Harmony HAP 运行;只更新页面资源无法加入原生播放器和依赖。Android 原生依赖为 Media3 1.9.0;不要手动复制其他版本的 AAR 覆盖它。
| 示例 | uni-app | uni-app x |
|---|---|---|
| App 功能菜单:18 个短视频与短剧场景 | uni_modules/lizhao-video-feed/example/uniapp/index.vue |
uni_modules/lizhao-video-feed/example/uniappx/index.uvue |
| 短视频、短剧、评论与分页 | uni_modules/lizhao-video-feed/example/uniapp/feed.vue |
uni_modules/lizhao-video-feed/example/uniappx/feed.uvue |
| 页面内嵌入 | Android/iOS:uni_modules/lizhao-video-feed/example/uniapp/inline.nvue;Harmony:uni_modules/lizhao-video-feed/example/uniapp/inlineHarmony.vue |
uni_modules/lizhao-video-feed/example/uniappx/inline.uvue |
| 微信菜单:短视频、短剧与互动 | uni_modules/lizhao-video-feed/example/uniapp/weixin.vue |
uni_modules/lizhao-video-feed/example/uniappx/weixin.uvue |
| 微信页面内嵌与播放控制 | uni_modules/lizhao-video-feed/example/uniapp/weixin-inline.vue |
uni_modules/lizhao-video-feed/example/uniappx/weixin-inline.uvue |
示例中的互动、评论、分页与解锁为本地 Mock;视频地址由你提供。示例不会调用抖音接口,不包含抖音素材,也不提供内容或支付服务。
注册示例页面
示例文件不会自动成为应用页面。先把对应宿主的条目合并到项目 pages.json 的 pages 数组,保留项目已有页面;path 不写文件扩展名。uni-app 使用:
{
"pages": [
{ "path": "uni_modules/lizhao-video-feed/example/uniapp/index", "style": { "navigationBarTitleText": "原生播放" } },
// #ifdef APP-PLUS
{ "path": "uni_modules/lizhao-video-feed/example/uniapp/inline", "style": { "navigationBarTitleText": "页面内播放" } },
// #endif
// #ifdef APP-HARMONY
{ "path": "uni_modules/lizhao-video-feed/example/uniapp/inlineHarmony", "style": { "navigationBarTitleText": "页面内播放" } },
// #endif
{ "path": "uni_modules/lizhao-video-feed/example/uniapp/feed", "style": { "navigationBarTitleText": "视频流与短剧" } }
]
}
APP-PLUS 分支对应 Android / iOS 的 nvue 页面,APP-HARMONY 分支对应 Harmony 的 Vue / embed 页面。uni-app x 使用下面的页面清单;插件会自动选择对应宿主的组件实现,无需额外配置 easycom:
{
"pages": [
{ "path": "uni_modules/lizhao-video-feed/example/uniappx/index", "style": { "navigationBarTitleText": "原生播放" } },
{ "path": "uni_modules/lizhao-video-feed/example/uniappx/inline", "style": { "navigationBarTitleText": "页面内播放" } },
{ "path": "uni_modules/lizhao-video-feed/example/uniappx/feed", "style": { "navigationBarTitleText": "视频流与短剧" } }
]
}
使用包含本插件的对应 App 原生包,导航到上述 index 页面,填写 HTTPS MP4 地址后打开示例。微信使用下面的专用入口。
微信小程序接入
将下面配置合并到 pages.json;保留原有页面和 usingComponents。全屏 API 通过插件页面承载,缺少该路由会导致打开失败。uni-app Vue2 / Vue3 使用:
{
"pages": [
{ "path": "uni_modules/lizhao-video-feed/example/uniapp/weixin", "style": { "navigationBarTitleText": "短视频与短剧" } },
{ "path": "uni_modules/lizhao-video-feed/example/uniapp/weixin-inline", "style": { "navigationBarTitleText": "嵌入视频流" } },
{ "path": "uni_modules/lizhao-video-feed/pages/weixin-player/weixin-player", "style": { "navigationStyle": "custom", "disableScroll": true, "backgroundColor": "#000000" } }
],
"globalStyle": {
"usingComponents": {
"lizhao-video-feed-native": "/uni_modules/lizhao-video-feed/wxcomponents/lizhao-video-feed-native/index"
}
}
}
uni-app x 将两个示例路径中的 example/uniapp/ 改为 example/uniappx/,全屏页面与原生组件路径保持相同。两种宿主都只从插件根目录 import,页面继续使用 <lizhao-video-feed>;为内嵌组件设置明确高度。
进入 weixin 先显示与安卓相同的 18 个功能场景,点击“刷短视频”“短剧选集”等按钮再打开播放界面。App 和微信的“页面内嵌”均提供播放、暂停、跳到 2 秒、1.5 倍、切换静音、读取状态、离开/回到 Tab、卸载重建和全屏打开;App 保留原视频地址输入。评论、分页、互动与解锁仍是公开 API 回写的本地 Mock。
在微信后台和宿主开发设置配置合法视频、图片域名;HLS 的主列表、子列表和分片域名都须可访问。使用 wx.downloadFile 获得本地媒体时,还需配置对应下载域名。不要通过关闭域名检查替代正式接入。微信端更新小程序代码即可,不因微信改动重新打 App 自定义基座。
微信仅支持 0.5、0.8、1、1.25、1.5、2 倍;其他倍率返回参数错误。微信没有严格“首帧已经显示”事件,firstFrameEvent=false,不会发送 firstframe;封面在真实 play 和推进的 timeupdate 后收起,业务用 statechange / timeupdate / error 观察播放。ready 与命令成功均不代表媒体首帧。请显式提供 poster,尤其邻项封面和锁定项。
微信本地 MP4 使用宿主已有的 wxfile://、http://tmp/ 或 http://usr/ 路径;这些是微信本地文件标识。App 的 file://、Windows 路径和任意本地绝对路径不能直接用于微信。手机上的键盘、安全区、实际音频、手势和前后台行为仍须在接入项目目标机型验收。
5 分钟跑通:打开短视频流
将 https://example.com/... 替换为自己有权播放的真实 MP4 地址,放入按钮处理函数:
openVideoFeed({
feedId: 'home-feed',
items: [
{ itemId: 'v1', source: { url: 'https://example.com/one.mp4' }, poster: 'https://example.com/one.jpg',
author: { authorId: 'u1', name: '作品作者' }, itemDescription: '第一条作品' },
{ itemId: 'v2', source: { url: 'https://example.com/two.mp4' }, poster: 'https://example.com/two.jpg', title: '第二条作品' }
],
options: { mode: 'video', loop: true, maxPlayerCount: 2, preloadCount: 1 },
onEvent: (event) => {
if (event.type == 'created') {
// 保存 feedId/sessionId;旧页面不能用旧身份控制新会话。
console.log('视频会话已创建')
}
if (event.type == 'firstframe') console.log('真实首帧已显示')
if (event.type == 'error') console.log('播放错误:' + event.error?.errCode)
},
success: (_res) => { console.log('原生界面已就绪') },
fail: (error) => { console.log('打开失败:' + error.errCode) },
complete: (res) => { console.log('打开结算:' + res.ok) }
})
created 表示会话已登记,此时可监听或取消;ready / success 表示原生承载可控制;提供严格首帧能力的平台用 firstframe 判断真实画面出现,微信按上方播放事件说明接入。items: [] 合法,只有空态和 ready,不会伪造首帧。
从基础到进阶:按业务模块使用
以下示例假定已经取得当前会话的 feedId 与 sessionId。业务数据请求应保留事件中的请求身份,结果只回写给仍然有效的当前会话。
模块一:播放控制与页面生命周期
const context = createVideoFeedContext({ feedId: event.feedId, sessionId: event.sessionId })
context.pause({ success: (_res) => { console.log('暂停已确认') } })
context.seek({ positionMs: 3000, fail: (error) => { console.log('跳转失败:' + error.errCode) } })
context.setRate({ rate: 1.25 })
context.play({})
// 页面/Tab 隐藏时暂停;它不会清除用户点下的暂停状态。
context.setActive({ active: false })
context.setActive({ active: true })
// 页面卸载时释放此身份;重复调用不会销毁新会话。
context.destroy({})
- 控制命令必须传对象,可用
{}。除监听、解绑、销毁外,命令要求ready。 seek单位毫秒,成功回调等待原生跳转确认;超过已知时长或试看边界明确失败,不偷偷截断。rate是基础倍率;按住指定侧边的临时倍率结束后恢复基础倍率。Harmony 支持0.5 / 0.75 / 1 / 1.25 / 1.5 / 1.75 / 2七档。- 主动
pause会跨切页保留;前后台恢复、关闭评论面板不会自动取消主动暂停。 - 默认
playbackGroup: 'lizhao-video-feed'。同组只有一个会话能够输出音轨;被其他会话抢占后,显式play或setActive(true)才重新争取播放。预载不播放、不抢组。 - 每条命令
success/fail互斥一次,随后complete一次。回调抛出异常不会阻止其他回调或资源清理。
全屏可用 closeVideoFeed({ feedId, sessionId }) 关闭;嵌入组件使用 context.destroy({}) 或卸载组件。
模块二:列表更新与分页
业务列表中 itemId 必须唯一且稳定。switchTo 按 ID 定位;setItems 原子替换;appendItems 用于宿主主动追加;异步分页结果必须使用 resolveLoadMore。
// 在 openVideoFeed.options 中配置 hasMore: true。
// 放入 onEvent 的 loadmore 分支;items 为服务端返回的新条目。
if (event.type == 'loadmore') {
const context = createVideoFeedContext({ feedId: event.feedId, sessionId: event.sessionId })
context.resolveLoadMore({
requestId: event.requestId!,
listRevision: event.listRevision,
outcome: 'success',
items: nextItems,
hasMore: false,
fail: (error) => { console.log('分页响应未被接受:' + error.errCode) }
})
}
| 返回情况 | outcome | items | hasMore |
|---|---|---|---|
| 有新数据 | success |
非空、无重复 ID | 服务端确认的后续页边界 |
| 空页 | empty |
空数组或省略 | true 时等待用户重试,避免自动空转 |
| 业务失败 | error |
空数组或省略 | 保留请求时的原值 |
requestId + listRevision 必须原样传回。刷新、追加或更新条目会增加版本并作废旧请求;迟到结果返回 9093012,不能解除新请求的加载状态。批次内或与已有列表重号会整批失败,旧列表不变。
context.switchTo({ itemId: 'v2', positionMs: 0 })
context.setItems({ items: newItems, hasMore: true })
context.appendItems({ listRevision: latestState.listRevision, items: moreItems })
context.updateItem({ listRevision: latestState.listRevision, item: completeItem })
updateItem.item 是完整替换快照;未提供的可选字段恢复默认值。纯互动更新不重建当前播放器;当前源 URL、媒体身份或门禁变化会建立新播放代次。不要用 durationHintMs 判断可跳转范围,它只用于列表展示。
模块三:互动与评论
右侧作者、关注、点赞、评论、收藏、分享,以及搜索和剧集入口通过 action 通知宿主。requestedSelected 表示用户期望状态,不表示服务端已保存成功。
if (event.type == 'action' && event.action?.action == 'like') {
// 先调用自己的业务服务。成功后携带完整条目回写。
const context = createVideoFeedContext({ feedId: event.feedId, sessionId: event.sessionId })
context.updateItem({ listRevision: event.listRevision, item: savedItem })
}
评论面板打开后发送 commentsrequest,携带 itemId、requestId、listRevision、requestKind 和 lastCommentId。首次请求替换列表;more 追加;retry 重试上次操作。
context.setComments({
itemId: event.itemId,
listRevision: event.listRevision,
requestId: event.requestId!,
outcome: 'success',
items: [{ commentId: 'c1', author: { authorId: 'u2', name: '观众' }, text: '评论内容' }],
hasMore: false
})
- 异步请求响应必须带
requestId;宿主确认评论提交或点赞后,可省略它主动回写完整评论快照。 commentsubmit只返回文字请求,插件不会擅自发布;commentlike也需要宿主处理。- 当前视频变化、列表版本变化或面板关闭后,旧评论响应不能写入其他视频。
- 点击评论后,白色评论层会从底部平滑上推,视频同步调整到顶部播放区;面板直接铺满屏幕余下空间,不会在底部留下黑色空白。
- 评论面板打开时,点击上方视频区域可直接收起面板;评论列表、输入框和面板按钮仍独立响应,不会误触播放或切页。
ui.commentPlayback: 'shrink'保持原播放意图,pause暂停;两种策略使用同一套上下分区视觉。panelVideoScale继续接受0.4~0.8,用于映射顶部播放区高度,不会再对视频做二次缩放。- 评论标题与输入区固定,评论列表独立滚动;评论滚动、输入和进度拖动不会当作视频翻页。
模块四:短剧、选集与试看
openVideoFeed({
feedId: 'series-feed',
items: [
{ itemId: 'e1', source: { url: 'https://example.com/episode1.mp4' }, poster: 'https://example.com/episode1.jpg',
title: '镜中重逢', durationHintMs: 90000,
drama: { seriesId: 's1', episodeId: 'e1', episodeNumber: 1, totalEpisodes: 6, seriesTitle: '剧集名称',
seriesTags: ['都市逆袭', '高能反转'], seriesDescription: '用于选集顶部展示的作品简介。', watched: true } },
{ itemId: 'e2', source: { url: 'https://example.com/episode2.mp4' }, poster: 'https://example.com/episode2.jpg',
title: '迟到五年的信', durationHintMs: 86000,
drama: { seriesId: 's1', episodeId: 'e2', episodeNumber: 2, locked: true, trialEndMs: 8000 } },
{ itemId: 'e3', poster: 'https://example.com/episode3.jpg', title: '照片里的秘密',
drama: { seriesId: 's1', episodeId: 'e3', episodeNumber: 3, locked: true } }
],
options: { mode: 'drama', initialItemId: 'e1', autoNext: true, loop: false,
ui: { episodeLayout: 'list', episodePlayback: 'shrink', episodeActions: [
{ buttonId: 'favorite-series', label: '收藏短剧' },
{ buttonId: 'unlock-card', label: '解锁短剧卡', emphasized: true }
] } }
})
- 短剧每项必须包含
drama。选集默认列表,可切为grid;标题、标签、简介、时长提示与已看状态由宿主提供。 - 列表模式使用深色作品信息区、选集标签、竖版封面、两行标题和辅助状态行;当前集使用主题强调色,底部最多展示两个
episodeActions。内置示例提供 6 集人物短剧 Mock 数据验证长标题、试看、锁定和业务按钮。 - HTTPS 剧集建议为每一集提供
poster,推荐接近 3:4 的竖版图且单图不超过 2MiB。Android 本地 MP4 未传poster时可使用有界首帧兜底;iOS 与 Harmony 应显式传封面,保证三端首屏一致。 locked: true且无正数trialEndMs时不请求源,可省略source,只显示解锁入口。- 正数
trialEndMs表示本集可看的前缀区间,达到边界发送trialend并暂停;拖动或seek不能越过它。锁定媒体不进行相邻预载。 - 用户请求解锁发送
action.action: 'unlock'。宿主完成授权后,通过updateItem传回完整条目、locked: false、trialEndMs: 0和有效源。本插件不校验订单、不提供支付,也不能代替服务端媒体鉴权。 autoNext在自然结束后切下一条;最后一条保留结束状态。loop与autoNext不能同时为 true。- 观看历史由宿主持久化
itemId + positionMs,重新打开时传initialItemId + initialPositionMs。完整示例包含本地恢复流程。
模块五:界面、手势与清屏
options: {
ui: {
title: '推荐', showBack: true, showSearch: true,
theme: { backgroundColor: '#000000', accentColor: '#FF375F', fontSize: 14, iconSize: 28 },
actions: [{ action: 'share', visible: true, label: '转发' }],
longPressRateRegion: 'right-edge', longPressRate: 2,
commentPlayback: 'shrink', episodePlayback: 'pause', panelVideoScale: 0.65
}
}
Android / iOS 默认右侧栏使用同一布局:圆形头像下沿叠加关注徽标,点赞、评论、收藏和分享使用实心图标与单行数量。数量不足一万时显示整数,一万及以上截断一位小数并显示“万”,一亿及以上显示“亿”;数量为零时显示动作名。作者和关注保留独立点击事件,已关注徽标可继续请求取消关注。非空 actions.label 保留自定义文字,visible、icon、activeIcon 及主题色继续生效。省略 theme.iconSize 时主动作图标为 36,头像为 50、关注为 24;显式尺寸仍按 20 至 48 覆盖。
单击视频切换播放意图,双击发送点赞请求,中央长按打开倍率/清屏菜单。可选左侧或右侧 20% 区域临时倍速;控件区域不触发长按倍率。松开、取消、切项、打开面板和进入后台都会恢复基础倍率。
Android 上下拖动时,当前视频与目标上一条或下一条封面使用同一位移轨道连续跟手;手势不等待当前视频首帧,列表和封面就绪后即可拖动。未达到切换条件时一起回弹,切换成功后新页面在原位接管,并在宿主确认切换后准备目标视频,不会先露出整块黑色区域再出现视频。回弹中再次按下可从当前位置继续拖动。翻页手势识别后不再触发同一次触摸的单击、双击或长按操作。
iOS 使用相同的首尾衔接方式,并在当前页配置时提前准备上下邻项封面。已缓存的封面在开始拖动时直接显示,切页成功后承接为新页封面,真实首帧出现后再隐藏;图片加载失败不会清空同一作品已显示的封面。封面预取独立于 preloadCount,保留原有视频预加载配置,目标播放切换仍在手势成功提交后执行。建议为远程视频提供可访问的 poster;授权本地 MP4 无封面时可后台提取静态首帧,远程无封面时保留占位,不为拖动预览额外下载视频。
右侧点赞、评论、收藏、分享等互动区,作品信息区和中央播放按钮均支持从原位置开始上下拖动:短按仍执行原按钮动作,明确纵向拖动后取消该次点击并转交整页分页。顶部返回/搜索和底部播放/进度控制保持独立,不会被分页手势接管。
侧栏在短屏或较矮的内嵌区域中显示不全时,从侧栏拖动会先滚动该栏,便于访问下方入口;在视频其他区域仍可上下翻页。侧栏完整显示时保留从互动区发起翻页的行为。Android / iOS 使用相同规则,显式关闭分页手势时侧栏仍可滚动。
- 相邻封面在列表绑定时开始预取,不等待当前视频的
firstframe;优先使用条目的poster。HTTPS 视频建议始终提供 HTTPSposter,以保证首次打开和弱网快速滑动时已有可显示封面;插件不会为了取封面重复下载远程视频。 - Android 本地绝对路径或
file://MP4 未传poster时,会在后台提取首帧并缩放到最大边约 1024;封面缓存最多 4 项,提帧最多 1 个运行任务和 3 个等待任务,不增加播放器数量。 - Android 8.1 及以上可直接按目标尺寸提取;Android 8.0 及以下只为最大边不超过 1024 的本地视频兜底。更大的旧系统本地视频请显式提供
poster。 - 首条、末条越界拖动没有真实相邻项,因此只回弹当前页,不伪造循环封面。
maxPlayerCount: 2的上限保持不变。
context.setClearScreen({ clearScreen: true }) 隐藏作品信息和业务互动,仍保留退出、暂停/继续与退出清屏入口。context.setPanel({ panel: 'comments' }) 可主动控制面板,每个会话最多一个。
默认自动处理安全区;Android 全屏顶栏在状态栏安全区后保留 20dp 视觉间距。宿主自己布局状态栏或底部导航时,可设 safeAreaMode: 'manual',提供 topInset / bottomInset。插件不绘制宿主底部 TabBar。
模块六:页面内嵌入
<lizhao-video-feed
style="width: 100%; height: 500px"
feed-id="page-feed"
:initial-items="items"
:initial-options="options"
@event="onFeedEvent"
/>
组件只有三个初始化属性和一个事件出口:
| 属性 / 事件 | 类型 | 说明 |
|---|---|---|
feedId |
string | 非空且未占用的业务实例标识 |
initialItems |
VideoFeedItem[] | 初始列表,可为空 |
initialOptions |
VideoFeedOptions | 初始配置,默认使用各字段缺省值 |
event |
e.detail = VideoFeedEvent | 与全屏完全相同的会话事件 |
挂载后修改初始化属性会报告 9093002,不会隐式重建。取得 created 的身份后使用 createVideoFeedContext 更新列表和播放;组件卸载自动释放。
uni-app Android / iOS 在 nvue 页面使用兼容模式组件;普通 Vue 页面请使用全屏 API。Harmony 的 uni-app Vue 页面使用同名组件,内部通过 embed 绑定 ArkUI 原生视图。inlineView: true 表示当前平台提供上述承载,不表示 Android/iOS 普通 Vue 页面能够使用 nvue 组件。
uni-app x 的 App 平台使用标准 native-view 组件;微信在 Vue / uvue 页面使用插件内部原生微信组件。插件会根据宿主和平台选择对应实现,业务页面继续统一使用 <lizhao-video-feed>。
为组件设置明确高度或占满有界父容器。宿主页面/Tab 隐藏时仍需调用 setActive(false);仅改变 CSS 可见性不能代替业务显隐通知。
模块七:播放 HLS 点播内容
短视频或短剧使用 m3u8 分段资源时,在 Android / iOS / 微信传入 HLS 地址;列表中可以同时放入 MP4 和 HLS 条目:
import { openVideoFeed } from '@/uni_modules/lizhao-video-feed'
// 替换为自己有权播放的 HTTPS HLS 点播地址。
openVideoFeed({
feedId: 'hls-feed',
items: [{
itemId: 'episode-1',
source: { url: 'https://example.com/master.m3u8', mediaType: 'hls' }
}],
fail: (error) => { console.log('打开失败', error.errCode) }
})
mediaType 省略或为 auto 时,按地址路径的 .m3u8 后缀识别 HLS,不受查询参数、大小写或 fragment 影响;无后缀的 HLS 地址请显式指定 hls。明确指定 mp4 时不能传入 m3u8 地址。多码率列表交由原生播放器选择,已有进度、倍速、试看、选集和内嵌用法相同。
示例页的“HLS 混合播放”可体验 HLS 与 MP4 连续切换。播放失败后可通过播放按钮或 context.play({}) 发起手动重试,是否开始播放仍以首帧和状态事件为准;示例流由外部服务提供,访问失败会正常显示错误。
模块八:临时网络故障自动恢复
用户处于移动网络、隧道或短暂断网环境时,可以给 Android / iOS / 微信会话设置有限次数的额外播放尝试。下面的示例最多额外尝试两次,并只读取公开的重试状态和脱敏失败分类:
openVideoFeed({
feedId: 'retry-feed',
items: [{ itemId: 'v1', source: { url: 'https://example.com/video.mp4' } }],
options: { maxPlaybackRetries: 2 },
onEvent: (event) => {
const retry = event.state.retry
if (event.type == 'statechange' && retry != null) {
console.log('恢复阶段:' + retry.phase + ',已尝试 ' + retry.attempt + '/' + retry.maxAttempts)
}
const diagnostic = event.error?.diagnostic
if (event.type == 'error' && diagnostic != null) {
console.log('失败分类:' + diagnostic.kind + ',已安排恢复:' + diagnostic.retryScheduled)
}
}
})
maxPlaybackRetries 默认 0,旧接入仍保持手动重试;可设为 1、2、3,分别限制本轮最多进行的额外尝试次数,等待依次为 1 秒、2 秒、4 秒。Android / iOS 对连接失败、断连、DNS、超时,以及可确认的 HTTP 408 / 500 / 502 / 503 / 504 安排恢复。微信只在真实视频错误且官方网络结果明确为断网时安排恢复;联网状态下无法可靠识别的错误保持 unknown,不猜测 HTTP 状态或解码器错误码,不自动重试。
state.retry 的阶段为 waiting / attempting / recovered / exhausted / cancelled;error.diagnostic 只包含固定分类和有界数值,不包含媒体地址、请求头、异常原文或响应正文。暂停、切项、换源、进入后台、打开暂停型面板或销毁会取消正在等待或执行的尝试,恢复前台不会让已取消的周期自行复活。
先检查 getVideoFeedCapabilities().playbackRetry。Android / iOS / 微信返回 true;Harmony 填写正数会明确返回 9093006,Web 和其他小程序仍按不支持平台处理。示例页的“弱网自动恢复”入口会开启三次额外尝试,并直接展示插件发出的阶段和脱敏原因。
API 速查
| API / 方法 | 用途 |
|---|---|
getVideoFeedCapabilities() |
同步查询当前平台、媒体路由、弱网恢复、倍率和资源上限 |
openVideoFeed(options) |
打开唯一全屏实例,先 created、后 ready |
closeVideoFeed({ feedId, sessionId }) |
按固定身份关闭全屏 |
createVideoFeedContext({ feedId, sessionId }) |
取得固定身份句柄,不创建播放器 |
play / pause / seek / setRate / setMuted |
控制当前项 |
switchTo / setItems / appendItems / updateItem |
切换、替换、追加或回写条目 |
resolveLoadMore / setComments |
结算宿主数据请求 |
setPanel / setClearScreen |
控制原生界面 |
setActive / getState / destroy |
显隐、快照与生命周期 |
on / off |
按 listenerId 注册/解绑持续监听 |
uni_modules/lizhao-video-feed/docs/API.md 覆盖完整参数、返回值、回调和逐字段参考,共 47 个公开类型。getState 通过结果的 state 返回独立快照;修改快照不影响原生实例。
常用配置默认值
| 配置 | 默认值 | 范围 / 说明 |
|---|---|---|
mode |
video |
video / drama |
autoplay / active |
true | 播放意图 / 宿主是否活跃 |
muted / rate |
false / 1 | 静音 / 基础倍率 |
objectFit |
cover |
cover / contain |
loop |
video=true;drama=false | 与 autoNext 互斥 |
autoNext |
video=false;drama=true | 自然结束时下一项 |
maxPlayerCount |
2 | 1 或 2;包含当前与预载 |
preloadCount |
maxPlayerCount-1 | 0 或 1,不得超过剩余预算 |
maxPlaybackRetries |
0 | 0~3;Android / iOS / 微信播放失败后的额外尝试上限,微信仅恢复已确认的断网错误 |
hasMore / loadMoreThreshold |
false / 2 | 后续页边界 / 距末尾触发范围 |
requestTimeoutMs |
30000 | 1000~120000;分页和评论请求 |
commandTimeoutMs |
15000 | 1000~120000;命令等待上限 |
ui.episodeLayout |
list |
list / grid |
ui.longPressRateRegion |
none |
none / left-edge / right-edge |
ui.panelVideoScale |
0.65 | 0.4~0.8 |
平台与承载方式
支持 Android 6.0 及以上与 iOS 13.0 及以上;发布前请在自己的目标机型确认全屏播放、页面内嵌与所用媒体编码。Harmony 当前为预览实现。Android 使用 Media3,iOS 使用 AVPlayer,Harmony 使用 AVPlayer 与 XComponent。
| 宿主 | Android | iOS | Harmony(预览) | 微信小程序 |
|---|---|---|---|---|
| uni-app 普通 Vue 页面 | 全屏 API | 全屏 API | 全屏 API;内嵌使用 embed 承载 | 全屏 API、原生微信组件 |
| uni-app nvue 页面 | 全屏 API、原生组件 | 全屏 API、原生组件 | 使用 Vue / embed 方案 | 使用 Vue 示例 |
| uni-app x uvue 页面 | 全屏 API、native-view 组件 | 全屏 API、native-view 组件 | 全屏 API、native-view 组件 | 全屏 API、原生微信组件 |
- 目标最低环境:HBuilderX 5.24、Android 6.0、iOS 13、Harmony API 12;使用最低版本前请先在目标系统试运行。具体媒体编码以系统解码能力为准。
- 当前媒体范围为 HTTPS MP4,以及宿主已有访问权的本地 MP4。App 使用
file://或绝对路径,微信使用上方微信文件标识。本插件不自动申请相册或文件目录权限。 - Android / iOS / 微信另支持非加密 HTTPS HLS 点播,主列表、子列表和分片须可通过 HTTPS 访问;TS / fMP4 的实际编码须由目标设备支持。Harmony 的 HLS 能力仍未开放。
- Android / iOS / 微信支持最多三次有限播放恢复,微信只对官方已确认的断网错误自动尝试;Harmony 不开放该能力,正数
maxPlaybackRetries返回9093006。 - HTTP 明文地址、自定义媒体请求头和本地 HLS 返回
9093006,不会静默丢弃请求头。直播、DRM / 加密授权、无限自动重连和离线缓存不在当前支持范围。 - 使用 HLS 或弱网恢复前,请确认 App 原生包已包含当前插件代码和依赖;旧原生包不能仅靠更新页面资源获得新增能力。
- Web 和其他小程序未提供播放器实现,全屏 API 返回
9093001。微信使用专用页面和原生微信组件注册,不使用 App 的 native-view 或 nvue 承载。 getVideoFeedCapabilities()查询当前平台的实现声明,不检测已安装基座版本或当前页面类型;原生实现存在不代表任意视频格式都能解码。
错误码
错误主题固定为 lizhao-video-feed,错误不包含媒体地址、请求头或原生异常正文。
| 错误码 | 含义 | 处理建议 |
|---|---|---|
| 9093001 | 平台不支持 | 使用 App 平台,先查能力 |
| 9093002 | 参数非法 | 检查类型、唯一 ID、枚举、范围及组件初始属性 |
| 9093003 | 标识或全屏占用 | 等原实例 close,或使用不同内嵌 feedId |
| 9093004 | 会话过期 | 使用本次 created / success 提供的身份 |
| 9093005 | 尚未 ready | 等 ready 后调用控制命令 |
| 9093006 | 媒体、请求头或播放恢复能力不支持 | 使用支持的 MP4 / HLS 路由,或关闭当前平台未开放的配置 |
| 9093007 | 原生承载不可用 | 检查匹配基座和宿主页面 |
| 9093008 | 播放失败 | 检查资源可达性与系统解码支持 |
| 9093009 | 跳转失败 | 根据真实时长重试或更换媒体 |
| 9093010 | 条目不存在 | 使用当前列表中的 itemId |
| 9093011 | 试看或锁定拦截 | 通过宿主业务授权后完整回写 |
| 9093012 | 请求 / 列表版本过期 | 丢弃旧响应,按最新事件重新请求 |
| 9093013 | 取消 | 页面关闭或切代次后停止旧流程 |
| 9093014 | 超时 | 检查原生环境或业务请求;命令超时会释放会话 |
| 9093015 | 分页业务失败 | 显示可重试状态 |
| 9093016 | 当前能力未开放 | 按当前能力和平台范围接入 |
常见问题
打开成功为什么仍没有画面? success 只表示原生承载 ready。支持严格首帧的平台监听 firstframe / error;微信监听真实播放状态和推进的 timeupdate / error,不会提供严格首帧事件;空列表没有首帧。
刷到下一条时旧视频会继续响吗? 切项先暂停旧项,旧代次回调被隔离;预载始终静音且不播放。同组会话也互斥。页面或 Tab 隐藏时请正确调用 setActive(false)。
为什么点赞后数字不立即增加? 插件只发送业务请求。你的服务保存成功后调用 updateItem 回写完整快照,失败时原状态保留。
评论或选集会导致上滑误切页吗? 面板、输入、滚动列表、按钮和进度控件有独立手势区域。面板打开时不执行视频翻页。
怎么处理网络慢、空页或分页失败? 媒体播放可在 Android / iOS / 微信设置有限的 maxPlaybackRetries,并观察 state.retry 与 error.diagnostic;微信仅对官方网络结果确认的断网错误自动恢复。分页仍由业务在对应事件中完成请求,原样回传请求 ID 和列表版本;空页或业务失败不会自动无限循环。
可以防止收费视频被下载吗? 本插件只提供播放门禁与界面流程。源访问控制、过期签名、订单权限和 DRM 由服务端及相应媒体方案负责,不能把客户端 locked 字段当成内容授权凭据。
何时需要更新 App 原生包? 页面样式、业务 JS、普通资源或文档通常只需更新页面资源;UTS 原生逻辑、Kotlin / Swift / ETS、依赖、Manifest 与平台配置变化必须使用包含这些变更的 App 原生包。
联系方式
信-微:l-z-1-8-7-1512-5421(-去掉,不这样写会被和谐)
作者系列 UTS 插件
以下为已确认公开市场页的作者系列 UTS 插件,当前插件也列在首行;它们可按业务需要组合使用,lizhao-video-feed 不强制依赖其中任何一个。
| 插件 | 能力方向 | 插件市场 |
|---|---|---|
lizhao-video-feed |
原生短视频流、短剧选集、评论互动与页面内嵌 | 当前插件 |
lizhao-nfc-pro |
NFC 标签读写、NDEF、IsoDep 与诊断 | 查看插件 |
lizhao-hce-card |
NFC 虚拟卡、HCE、APDU 与 NDEF 标签模拟 | 查看插件 |
lizhao-float-window |
悬浮窗、画中画、权限与诊断 | 查看插件 |
lizhao-device-id |
设备标识、隐私策略与诊断 | 查看插件 |
lizhao-scan-pro |
原生扫码、连续扫码、相册识别 | 查看插件 |
lizhao-choose-file |
原生文件选择、上传、进度与取消 | 查看插件 |
lizhao-bg-audio |
背景音频播放、队列、倍速与事件 | 查看插件 |
lizhao-smart-tts |
系统 TTS、云端合成、听书方案 | 查看插件 |
lizhao-share-plus |
系统分享、远程文件下载后分享 | 查看插件 |
lizhao-sqlite-pro |
原生 SQLite、迁移、备份与诊断 | 查看插件 |
lizhao-icon-pro |
SVG 图标组件、多主题与缓存 | 查看插件 |
lizhao-cast-screen |
DLNA 投屏、AirPlay 路由入口 | 查看插件 |
lizhao-call-kit |
电话、短信、通讯录原生能力 | 查看插件 |
lizhao-app-keepalive |
应用保活、唤醒、自愈与报告 | 查看插件 |
lizhao-doc-corrector |
文档扫描、矫正、增强与识别 | 查看插件 |
lizhao-emu-detect |
模拟器环境检测、风险评分与证据 | 查看插件 |
lizhao-gallery-pro |
相册媒体分页、筛选、缩略图与导出 | 查看插件 |
lizhao-video-thumb |
视频封面、批量取帧与 Base64 返回 | 查看插件 |
lizhao-ble |
BLE 扫描、连接、读写、通知与自动重连 | 查看插件 |
lizhao-sse-pro |
SSE、Line、JSONL 与 Raw 流式请求 | 查看插件 |
lizhao-pdf-pro |
PDF 阅读、签批、真实写回与页面处理 | 查看插件 |
lizhao-serial-port |
路径串口、USB 串口、多会话收发与诊断 | 查看插件 |
lizhao-wechat-kit |
微信登录、分享、支付、小程序与客服 | 查看插件 |
lizhao-video-editor |
视频裁剪、压缩、取帧与 FFmpeg/FFprobe | 查看插件 |
lizhao-vpn-pro |
企业 VPN、IKEv2、安全接入与脱敏诊断 | 查看插件 |
lizhao-camera-pro |
原生相机、拍照录像、水印与媒体保存 | 查看插件 |
lizhao-tcp-pro |
TCP 客户端、服务端、多连接与诊断 | 查看插件 |
lizhao-notify-pro |
本地通知、点击动作、进度与定时提醒 | 查看插件 |
lizhao-usb-storage |
U 盘与移动硬盘浏览、读写、复制与任务管理 | 查看插件 |
lizhao-health |
健康数据授权、查询、统计、写入与删除 | 查看插件 |

收藏人数:
购买源码授权版(
试用
赞赏(0)
下载 6486
赞赏 5
下载 12675942
赞赏 1956
赞赏
京公网安备:11010802035340号