更新记录

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 和业务区域
详情页或单条播放 单条列表、播放控制、生命周期 可从指定作品起播,并与页面显示、隐藏和销毁同步

下载与导入

  1. 在插件市场选择“使用 HBuilderX 导入插件”,导入到自己的 uni-app 或 uni-app x 项目。
  2. 保留完整的 uni_modules/lizhao-video-feed 目录和插件名称。
  3. 在页面脚本中从插件根目录导入:
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 视频建议始终提供 HTTPS poster,以保证首次打开和弱网快速滑动时已有可显示封面;插件不会为了取封面重复下载远程视频。
  • 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 健康数据授权、查询、统计、写入与删除 查看插件

隐私、权限声明

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

播放网络视频需要网络访问;本地媒体须由接入项目提供可访问的路径。

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

视频地址与业务数据由接入项目提供,不向插件作者服务器上传。

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

无