更新记录

1.0.35(2026-09-02)

  • 修复 iOS 面板 2 在多集场景下错误隐藏“选集 / 下一集”和刷新入口的问题,升级后无需修改调用代码。
  • 修复 iOS 分集断点续播等已开启选项可能没有生效的问题,并增强面板参数的兼容性和 JSON 文本稳定性。
  • 优化 Android、iOS 与 HarmonyOS 简约面板的首次进入流程:尚未连接设备时先展示设备搜索页,选择设备并确认媒体成功投屏后再进入原控制页;原控制界面与调用方式保持不变。
  • 本版包含 Android、iOS 与 HarmonyOS 原生面板改动,升级后需要分别重新制作并安装匹配的 Android 自定义基座、iOS IPA/自定义基座和 Harmony HAP。

1.0.34(2026-09-02)

  • 修复 iOS 面板 2 在多集场景下不显示底部“选集 / 下一集”栏的问题;升级后 Android、iOS 与 HarmonyOS 可继续使用同一份 showCastPanel 参数,无需修改调用代码。
  • 进一步修复普通 uni-app 页面传入多集列表时,iOS 面板 2 仍不显示“选集 / 下一集”的问题;本次仍为 1.0.34 修订版,无需修改调用代码。
  • 修复 iOS 多集参数导致整组面板配置失效、退回面板 1 并使用默认主题/标题的问题;本次仍为 1.0.34 修订版,无需修改调用代码。
  • 本版需要重新构建并安装匹配的 iOS IPA/自定义基座;Android 与 HarmonyOS 运行逻辑未因本次修复调整,无需仅为本次升级重新制作 Android 自定义基座或 Harmony HAP。

1.0.33(2026-08-28)

  • 修复 iOS DLNA 读取到历史断点后仍可能从 0 秒开始播放的问题;正断点起播会等待媒体就绪,Seek 后回读确认目标位置,并在 Play 后再次确认未被接收端重置,检测回零时最多补偿一次 Seek,无法确认则明确失败而不再伪报成功。
  • 修复 iOS 云打包中 CastScreenNative.synchronizeVolume 参数标签与错误回调类型不匹配导致的 SwiftCompile 失败;原生入口改为无标签调用,并在 UTS 边界统一使用 NSNumber 错误码,内部错误语义保持不变。
  • 本版修改 iOS 原生 Swift,升级后需要重新构建匹配的 iOS IPA/自定义基座;Android 与 HarmonyOS 原生实现未因本版调整,无需仅为本次修复重打基座或 HAP。
查看更多

平台兼容性

uni-app(5.07)

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

uni-app x(5.07)

Chrome Safari Android iOS 鸿蒙 微信小程序

lizhao-cast-screen

lizhao-cast-screen 是面向 uni-app / uni-app x 的媒体投屏插件。它可以把远程视频、MP3 音频或图片地址发送给同一局域网内的电视、盒子或其他 DLNA 接收设备,并在手机上完成播放控制。

这个插件能解决什么问题

  • 自动搜索同一局域网内可投屏的电视或盒子。
  • 投屏远程视频、MP3 音频和图片。
  • 控制播放、暂停、进度、音量、倍速和停止。
  • 为短剧、课程和连续剧提供选集、上下集、自动连播和断点续播。
  • App 端自带两套投屏面板,不想自己写界面时可以直接使用面板 2。
  • 已有播放器界面时,也可以只使用 API 和事件完成自己的投屏流程。
  • 提供媒体地址检查和诊断信息,帮助排查“搜不到电视”“电视打不开视频”等问题。

适合在线视频、短剧、在线课程、图片相册、会议资料和家庭媒体等场景。

本插件用于“把媒体地址交给电视播放”,不是手机屏幕镜像或录屏推流。媒体地址必须能被电视直接访问;本地临时文件、需要登录或鉴权的私有地址、DRM 加密媒体不能直接投屏。

支持平台

平台 真实投屏 经典面板 面板 2 是否需要自定义基座 说明
App Android 支持 支持 支持 需要 使用 DLNA/UPnP 投屏视频、MP3 和图片。
App iOS 支持 支持 支持 需要 支持 DLNA,并保留系统 AirPlay 路由入口。
App Harmony 支持 支持 支持 需要 使用 DLNA/UPnP 投屏视频、MP3 和图片。
微信小程序 条件支持 不支持 不支持 不需要 基础库具备 UDP/TCP Socket 能力时可搜索和控制设备,投屏界面由项目自己展示。
Web/H5 不支持 不支持 不支持 不需要 API 会明确返回当前平台不支持真实投屏。
支付宝小程序 不支持 不支持 不支持 不需要 API 会明确返回当前平台不支持真实投屏。

Android、iOS 和 Harmony 的界面细节会随系统能力略有差异,但 App 端可以使用同一套公开 API。插件市场的跨端标记只表示对应端可以安装和调用统一入口,是否支持真实投屏应以本表和 getCastCapabilities() 返回结果为准。

先选择接入方式

你的需求 推荐接入方式 需要自己写投屏界面吗
App 端希望最快完成投屏 面板 2,推荐 不需要
App 端希望使用经典面板外观 经典面板 不需要
App 已经有设备弹窗或播放器控制栏 事件 + 投屏 API 需要
微信小程序 自动搜索 + 投屏 API 需要
Web/H5、支付宝小程序 查询能力后显示不支持提示 不需要

如果不想自己写界面,推荐直接使用面板 2。调用时请显式传入 panelStyle: 'minimal'。为了兼容已经上线的项目,未传 panelStyle 时仍会显示经典面板。

下载与导入

  1. 从插件市场将插件导入项目。
  2. 请严格使用下面的插件根目录导入方式,不要在路径后追加其他目录。

各平台运行前提见上方“支持平台”表;App 端的安装包要求也会在文末“注意事项”中再次说明。

uni-app 导入

// 普通 uni-app 页面从插件根目录导入。
import * as CastScreen from '@/uni_modules/lizhao-cast-screen'

uni-app x 导入

// <script setup lang="uts"> 中同样只从插件根目录导入。
import * as CastScreen from '@/uni_modules/lizhao-cast-screen'

下面的业务示例以普通 uni-app JavaScript/TypeScript 写法为主;uni-app x 使用同名 API,强类型写法请参考文末完整 UTS 示例。插件通常只需要初始化一次。

按业务模块使用

除特别说明外,后续模块都假设已经按模块一完成 initCast()

模块一:不写界面,直接投一个视频

适合第一次接入,或项目不想自己开发设备列表和遥控界面。

// 下面是普通 uni-app 写法;uni-app x 可使用同名 API 和参数。
import * as CastScreen from '@/uni_modules/lizhao-cast-screen'

// 初始化成功后直接打开面板 2。
CastScreen.initCast({
  success() {
    CastScreen.showCastPanel({
      useBuiltinUI: true,
      panelStyle: 'minimal',
      theme: 'auto',
      media: {
        url: 'https://media.w3.org/2010/05/video/movie_300.mp4',
        title: '示例视频',
        mediaKind: 'video',
        mimeType: 'video/mp4'
      },
      success() {
        console.log('投屏面板已打开')
      },
      fail(err) {
        console.log('投屏面板打开失败', err)
      }
    })
  },
  fail(err) {
    console.log('投屏插件初始化失败', err)
  }
})

首次打开面板 2 且尚未连接电视时,会先显示设备搜索页。选择设备并确认媒体成功投屏后,再进入播放控制页;如果当前已经连接设备,再次打开时会直接显示控制页。进入播放控制页后,换设备、断开及其他控制逻辑仍保持原有行为,不会重新返回搜索页。

面板 2 会负责搜索设备、连接、投屏、播放、暂停、进度、音量和停止,不需要业务页面重复实现这些界面。

如果需要使用经典面板,将 panelStyle 改为 classic;省略该字段时也会使用经典面板。

模块二:短剧、课程选集与断点续播

适合短剧、课程、连续剧等需要上一集、下一集、选集和继续播放的场景。

// 每集都提供稳定 ID、可访问地址和独立断点键。
const episodes = [
  {
    id: 'episode-1',
    title: '第 1 集',
    url: 'https://media.w3.org/2010/05/video/movie_300.mp4',
    duration: 300,
    resumeKey: 'course-1001-episode-1'
  },
  {
    id: 'episode-2',
    title: '第 2 集',
    url: 'https://media.w3.org/2010/05/sintel/trailer.mp4',
    duration: 52,
    resumeKey: 'course-1001-episode-2'
  }
]

CastScreen.showCastPanel({
  useBuiltinUI: true,
  panelStyle: 'minimal',
  media: {
    url: 'https://media.w3.org/2010/05/video/movie_300.mp4',
    title: '第 1 集',
    mediaKind: 'video',
    mimeType: 'video/mp4',
    duration: 300,
    resumeKey: 'course-1001-episode-1'
  },
  episodes,
  currentEpisodeIndex: 0,
  rememberProgress: true
})

resumeKey 应使用稳定的课程 ID 或剧集 ID,不要使用可能过期或包含鉴权参数的媒体地址。插件会分别记录每一集的投屏进度,切换回来后可以继续播放。希望使用插件保存的断点时可以省略 currentTime;只有需要从页面播放器当前位置接着投时,才传入页面的真实进度。

episodes 至少有两项时,面板 2 会提供“选集”和“下一集”。选择新剧集时,只有接收端真实接受播放后才会更新当前选集;失败时保留原来的播放状态。最后一集播放结束后不会自动回到第一集。

模块三:配置清晰度、倍速和面板外观

适合一个视频提供多个真实清晰度地址,或希望面板颜色与项目风格保持一致的场景。

// 请把示例地址替换为项目自己的真实媒体地址。
CastScreen.showCastPanel({
  useBuiltinUI: true,
  panelStyle: 'minimal',
  media: {
    url: 'https://media.example.com/video-auto.mp4',
    title: '示例课程',
    mediaKind: 'video',
    mimeType: 'video/mp4'
  },
  currentQuality: 'auto',
  qualities: [
    {
      id: 'auto',
      label: '自动',
      url: 'https://media.example.com/video-auto.mp4',
      selected: true
    },
    {
      id: '720p',
      label: '720P',
      url: 'https://media.example.com/video-720p.mp4'
    },
    {
      id: '1080p',
      label: '1080P',
      url: 'https://media.example.com/video-1080p.mp4'
    }
  ],
  playbackRates: [0.5, 1.0, 1.5, 2.0],
  theme: 'auto',
  appearance: {
    progressColor: '#E87B9A',
    progressTrackColor: '#4D4B50',
    episodeSelectedColor: '#E87B9A',
    progressThumbIcon: {
      type: 'tv'
    }
  }
})

每个清晰度都应提供接收设备能够直接访问的真实媒体地址。没有配置 qualities 时,插件不会伪造 720P 或 1080P。

倍速是接收端的真实能力。Android、iOS、Harmony 只有在接收端确认目标倍率后才会更新状态;接收端拒绝时会保留原倍速并返回失败。appearance 只用于面板 2,可以配置进度颜色、选集颜色和进度滑块图标。

点击音量百分比可在静音与最近一次确认的非零音量之间切换。接收端不支持该倍速时会保留原倍率;未配置清晰度资源时不会伪造可切换选项。

模块四:投屏 MP3、图片或带字幕的视频

适合音乐、听书、图片相册以及带字幕或歌词的媒体。

// 示例投屏带歌词描述的 MP3;请将歌词占位地址替换为真实可访问地址。
CastScreen.showCastPanel({
  useBuiltinUI: true,
  panelStyle: 'minimal',
  media: {
    url: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3',
    title: '示例音频',
    mediaKind: 'audio',
    mimeType: 'audio/mpeg',
    textTracks: [
      {
        id: 'lyrics-zh',
        kind: 'lyrics',
        format: 'lrc',
        label: '中文歌词',
        language: 'zh-CN',
        url: 'https://media.example.com/demo.lrc',
        isDefault: true
      }
    ],
    preferredTextTrackId: 'lyrics-zh',
    textTrackFailurePolicy: 'continue-media'
  }
})
媒体 关键配置 说明
视频 mediaKind: 'video'mimeType: 'video/mp4' 支持播放控制和进度同步,实际能力取决于接收设备。
MP3 mediaKind: 'audio'mimeType: 'audio/mpeg' 当前正式支持的音频格式,可携带 LRC 等歌词信息。
图片 mediaKind: 'image'mimeType: 'image/jpeg' 没有时间轴,不支持暂停、恢复、Seek 和倍速。
字幕或歌词 media.textTracks 可声明内嵌轨或 SRT、VTT、ASS、LRC 地址。

外挂字幕和歌词能否真正显示,取决于目标电视或盒子的能力。插件会传递兼容信息,但不会把“媒体开始播放”误报为“字幕已经显示”。面板参数 subtitle 只是面板提示文案,不是媒体字幕。

模块五:使用自己的投屏界面

适合项目已经有设备弹窗、播放器控制栏或统一设计规范,只需要插件提供搜索、连接和投屏能力的场景。

// 自定义界面只负责展示;设备搜索、连接和投屏仍由插件完成。
const media = {
  url: 'https://media.w3.org/2010/05/video/movie_300.mp4',
  title: '示例视频',
  mediaKind: 'video',
  mimeType: 'video/mp4'
}

// 保存同一个函数引用,页面卸载时才能正确移除监听。
const handleDeviceListChange = (event) => {
  console.log('请在业务界面展示这些设备', event.payload)
}

CastScreen.onCastEvent('deviceListChange', handleDeviceListChange)

CastScreen.initCast({
  success() {
    CastScreen.startDiscovery({
      timeoutMs: 12000,
      clearBeforeStart: true,
      fail(err) {
        console.log('搜索设备失败', err)
      }
    })
  }
})

function castToDevice(deviceId) {
  CastScreen.connectDevice({
    deviceId,
    success() {
      CastScreen.startCast({
        media,
        fail(err) {
          console.log('投屏失败', err)
        }
      })
    },
    fail(err) {
      console.log('连接设备失败', err)
    }
  })
}

function leavePage() {
  CastScreen.offCastEvent('deviceListChange', handleDeviceListChange)
}

业务界面应根据成功回调和 connectedstateChangeerror 等事件更新状态,不要在点击按钮后直接显示“投屏成功”。

如需让同一个投屏按钮只触发业务界面,可以调用 showCastPanel({ useBuiltinUI: false })。该调用会派发面板事件,但不会替项目绘制界面。

模块六:控制播放并读取真实状态

适合自定义控制栏,或需要把接收端进度、音量和倍率同步回业务页面的场景。

// 所有控制都应处理失败;部分电视可能不支持其中某个动作。
CastScreen.pauseCast({ fail: (err) => console.log('暂停失败', err) })
CastScreen.resumeCast({ fail: (err) => console.log('恢复失败', err) })
CastScreen.seekCast({ position: 60, fail: (err) => console.log('进度跳转失败', err) })
CastScreen.setCastVolume({ volume: 0.5, fail: (err) => console.log('音量设置失败', err) })
CastScreen.setCastPlaybackRate({ rate: 1.5, fail: (err) => console.log('倍速设置失败', err) })

const state = CastScreen.getCastSessionState()
console.log('接收端状态', state.state, state.currentTime, state.duration)

// volumeKnown 为 false 时,界面应显示“同步中”或“未知”。
console.log('音量是否已确认', state.volumeKnown)

stopCast() 只停止当前媒体,方便继续向同一设备投屏其他内容;需要停止并断开时使用 disconnectDevice({ stopRemote: true })

模块七:微信小程序搜索并投屏

微信小程序没有插件内置面板,需要把发现的设备展示在自己的弹窗或列表中。

// 微信小程序使用同一套公开 API,但需要项目自己展示设备列表。
import * as CastScreen from '@/uni_modules/lizhao-cast-screen'

let selectedDeviceId = ''
const discoveredDevices = []

const handleDeviceFound = (event) => {
  const device = event.payload
  if (device == null || device.id == null) return

  // 把设备加入业务列表,等待用户点击选择,不要自动覆盖选择结果。
  const index = discoveredDevices.findIndex((item) => item.id === device.id)
  if (index >= 0) discoveredDevices[index] = device
  else discoveredDevices.push(device)
  console.log('当前投屏设备列表', discoveredDevices)
}

CastScreen.onCastEvent('deviceFound', handleDeviceFound)

CastScreen.initCast({
  success() {
    CastScreen.startDiscovery({
      timeoutMs: 5000,
      clearBeforeStart: true,
      fail(err) {
        console.log('搜索设备失败', err)
      }
    })
  }
})

function selectDevice(deviceId) {
  // 用户点击设备列表项时保存目标设备 ID。
  selectedDeviceId = String(deviceId)
}

function castSelectedDevice() {
  if (selectedDeviceId.length === 0) {
    console.log('请先选择投屏设备')
    return
  }

  CastScreen.connectDevice({
    deviceId: selectedDeviceId,
    success() {
      CastScreen.startCast({
        media: {
          url: 'https://media.w3.org/2010/05/video/movie_300.mp4',
          title: '示例视频',
          mediaKind: 'video',
          mimeType: 'video/mp4'
        },
        fail(err) {
          console.log('投屏失败', err)
        }
      })
    },
    fail(err) {
      console.log('连接设备失败', err)
    }
  })
}

function leavePage() {
  CastScreen.offCastEvent('deviceFound', handleDeviceFound)
}

手机和电视必须处于同一可互访局域网。实际项目应展示完整设备列表,让用户确认目标设备,不建议自动选择搜索到的第一台设备。

微信小程序的真实投屏能力取决于当前基础库是否提供所需的局域网 Socket API。具体网络排查方法见后文“常见问题”。

模块八:上线前检查媒体地址并收集诊断信息

适合排查手机能播放、电视却打不开媒体,或需要把运行信息提供给技术支持的场景。

// 预检只分析媒体配置,不会代替真实电视访问测试。
const inspection = CastScreen.inspectCastMediaSource({
  media: {
    url: 'https://media.example.com/video.mp4',
    mediaKind: 'video',
    mimeType: 'video/mp4'
  }
})

console.log('是否适合进入投屏流程', inspection.castable)
console.log('风险提示', inspection.riskFlags)
console.log('处理建议', inspection.suggestions)

// 出现问题时导出当前能力、会话和最近事件。
const supportBundle = CastScreen.exportCastSupportBundle({
  includeDevices: true,
  includeRecentEvents: true,
  maxEvents: 20
})

console.log('投屏诊断信息', JSON.stringify(supportBundle))

媒体检查可以提前发现本地路径、疑似鉴权地址、DRM 和格式不明确等常见风险。诊断信息可以帮助区分设备搜索、网络、媒体地址和接收端能力问题,但不能代替真实电视或 AirPlay 接收器验收。

常用 API 与配置

API 用途总览

API 所属模块 用途 平台说明
initCast 初始化 初始化投屏环境,可选择初始化后自动搜索设备。 Android、iOS、Harmony、微信小程序
getCastCapabilities 能力判断 查询当前平台是否支持真实投屏、设备搜索、内置面板和播放控制。 全平台可调用;不支持的平台返回 supported: false
startDiscovery 设备发现 开始搜索同一局域网内的 DLNA 电视或盒子。 Android、iOS、Harmony、微信小程序
stopDiscovery 设备发现 停止当前设备搜索。 全平台可调用
getDiscoveredDevices 设备发现 获取当前已经发现的设备列表。 不支持的平台返回空数组
showCastPanel 面板 打开内置面板,或通知业务展示自己的界面。 内置面板支持 Android、iOS、Harmony
hideCastPanel 面板 关闭当前内置投屏面板。 全平台可调用
connectDevice 设备连接 连接用户选择的电视或盒子。 Android、iOS、Harmony、微信小程序
disconnectDevice 设备连接 断开当前设备,可选择先停止电视端播放。 Android、iOS、Harmony、微信小程序
startCast 媒体投屏 将远程视频、MP3 或图片 URL 投送到当前设备。 Android、iOS、Harmony、微信小程序
pauseCast 播放控制 暂停当前视频或音频。 最终取决于接收设备能力
resumeCast 播放控制 恢复当前视频或音频。 最终取决于接收设备能力
seekCast 播放控制 跳转到指定播放位置。 图片不支持
setCastVolume 播放控制 设置接收端音量,取值范围为 0-1 最终取决于接收设备能力
setCastPlaybackRate 播放控制 设置真实播放倍率。 Android、iOS、Harmony
stopCast 播放控制 停止接收端当前媒体播放。 Android、iOS、Harmony、微信小程序
getCastSessionState 状态查询 获取当前设备、媒体、进度、音量和播放状态。 全平台可调用
getCastDiagnostics 问题排查 获取当前运行环境、设备搜索和会话诊断信息。 全平台可调用
exportCastSupportBundle 问题排查 汇总能力、会话、设备和最近事件。 全平台可调用
inspectCastMediaSource 媒体预检 投屏前检查 URL、媒体类型、鉴权和 DRM 风险。 只做静态检查,不会访问电视
onCastEvent 事件监听 监听设备、连接、播放、进度、音量和错误事件。 全平台可调用
offCastEvent 事件监听 移除指定事件监听。 全平台可调用

通用回调

大部分异步 API 都支持以下回调:

参数 类型 必填 说明 默认值 可选参数
success function 当前操作按平台规则确认成功后触发。
fail function 参数无效、平台不支持、网络失败或接收端拒绝时触发。
complete function 成功或失败后都会触发。

搜索任务启动、网络请求返回或接收端收到命令,不一定代表媒体已经正常播放。业务界面应结合 successconnectedstateChangeerror 等事件更新最终状态。

初始化与设备搜索参数

参数 类型 必填 说明 默认值 可选参数
initCast.options.debug boolean 是否输出精简中文调试日志。 false true / false
initCast.options.autoStartDiscovery boolean 初始化成功后是否立即搜索设备。 false true / false
initCast.options.discoveryTimeoutMs number 自动搜索超时时间,单位毫秒。 按平台使用默认值 大于 0
initCast.options.sessionSyncIntervalMs number 微信小程序同步接收端状态的间隔;传 0 可关闭。 2000 0 / 1000-10000
initCast.options.autoRediscoverOnNetworkChange boolean 微信网络恢复或回到前台后是否自动搜索。 true true / false
startDiscovery.options.timeoutMs number 本轮搜索超时时间,单位毫秒。 App 为 12000,微信为 5000 大于 0
startDiscovery.options.clearBeforeStart boolean 搜索前是否清空上一轮设备列表;跨端项目建议显式传值。 Android/微信为 true,iOS/Harmony 为 false true / false
startDiscovery.options.manualDeviceDescriptionUrl string 已知设备描述地址时用于受限网络排查,正常接入不需要。 http / https

startDiscovery.success 表示搜索任务已经启动,不表示已经找到电视。设备结果应通过 deviceFounddeviceListChange 事件或 getDiscoveredDevices() 获取。

面板参数

参数 类型 必填 说明 默认值 可选参数
showCastPanel.options.useBuiltinUI boolean 是否使用插件内置界面;传 false 时由业务自己绘制。 true true / false
showCastPanel.options.panelStyle CastPanelStyle 内置面板样式;面板 2 使用 minimal classic classic / minimal
showCastPanel.options.theme CastPanelTheme 面板主题。 Android/Harmony 为 dark,iOS 为 auto dark / light / auto
showCastPanel.options.title string 面板顶部标题。 平台默认标题
showCastPanel.options.subtitle string 面板提示文案,不是媒体字幕。 平台默认提示
showCastPanel.options.media CastMediaSource 当前准备投屏或正在控制的媒体。 当前会话媒体
showCastPanel.options.mediaTitle string 面板中展示的媒体主标题。 优先读取 media.title
showCastPanel.options.mediaSubtitle string 剧集、课程或来源说明。 空字符串
showCastPanel.options.currentEpisodeIndex number 当前选集下标,从 0 开始。 0 大于等于 0
showCastPanel.options.episodes Array<CastPanelMediaItem> 选集列表。 []
showCastPanel.options.currentQuality string 当前清晰度 ID 或显示名称。 空字符串
showCastPanel.options.qualities Array<CastPanelQualityItem> 可切换清晰度列表。 []
showCastPanel.options.currentTime number 业务页面当前播放位置,单位秒。 当前会话进度 大于等于 0
showCastPanel.options.duration number 当前媒体总时长,单位秒。 当前媒体或会话时长 大于 0
showCastPanel.options.rememberProgress boolean 是否按照 resumeKey 记忆每个媒体的进度。 true true / false
showCastPanel.options.playbackRates Array<number> 面板 2 中展示的候选倍率。 [0.5, 1.0, 1.5, 2.0] 大于 0
showCastPanel.options.appearance CastPanelAppearance 面板 2 的进度色、选集色和滑块图标。 当前主题默认外观
showCastPanel.options.danmakuSupported boolean 项目是否有自己的电视端弹幕画面层。 false true / false
showCastPanel.options.danmakuEnabled boolean 当前已经确认的弹幕开关状态。 false true / false
showCastPanel.options.onDanmakuToggle function 业务完成真实弹幕切换后提交成功或失败。
showCastPanel.options.showThemeToggle boolean 是否显示主题切换按钮。 true true / false
showCastPanel.options.showEpisodeControls boolean 是否显示选集、上一集和下一集。 true true / false
showCastPanel.options.showQualityControls boolean 是否显示清晰度切换。 true true / false
showCastPanel.options.showRefresh boolean 是否显示刷新设备入口。 true true / false
showCastPanel.options.showCustomAction boolean 是否显示业务自定义入口。 false true / false
showCastPanel.options.customActionText string 自定义入口文案。 平台默认文案

panelStyle: 'minimal' 支持 App Android、iOS 和 Harmony。微信小程序没有内置面板,应使用自己的设备列表和控制界面。

普通 uni-app 对象附带的其他键在 iOS 平台会被忽略。不要依赖未声明字段传递剧集或开关状态;请使用上表公开参数。

普通 DLNA/AirPlay 没有通用弹幕叠加协议,danmakuSupported 默认应保持 false。只有项目拥有配套电视画面层并能真实处理弹幕时,才应开启并处理 onDanmakuToggle

面板 2 外观配置

参数 类型 必填 说明 默认值 可选参数
appearance.progressColor string 已播放进度颜色。 主题默认颜色 #RRGGBB
appearance.progressTrackColor string 未播放进度轨道颜色。 主题默认颜色 #RRGGBB
appearance.episodeSelectedColor string 当前选集的文字、勾选和边框颜色。 主题默认颜色 #RRGGBB
appearance.progressThumbIcon.type string 进度滑块图标类型。 tv tv / circle / image
appearance.progressThumbIcon.dataUri string 自定义 PNG/JPEG Base64 Data URI,解码后最大 256KB。 data:image/...

无效的颜色或图片只会回退对应字段,不影响其他外观配置。

媒体参数 CastMediaSource

参数 类型 必填 说明 默认值 可选参数
url string 接收设备能够直接访问的远程媒体 URL。 http / https
resumeKey string 断点续播使用的稳定业务标识。 空字符串,不保存进度 课程 ID、剧集 ID 等
mediaKind CastMediaKind 媒体类型。 根据 MIME 或 URL 推断 video / audio / image
title string 接收设备和面板显示的媒体标题。
mimeType string 媒体 MIME 类型。 根据媒体类型推断 video/mp4
poster string 封面图片 URL。 http / https
duration number 已知媒体时长,单位秒。 0,表示未知 大于 0
startPosition number 本次投屏的起播位置,单位秒。 0 大于等于 0
headers any 媒体请求头;电视通常无法复用手机登录态。
extras any 业务透传数据。
textTracks Array<CastTextTrack> 字幕、说明字幕或歌词轨。 []
preferredTextTrackId string 优先选择的文本轨 ID。 默认轨或第一个有效轨
textTrackFailurePolicy string 文本轨处理失败后是否继续媒体。 continue-media continue-media / fail-cast

当前正式音频格式为 MP3,建议同时设置 mediaKind: 'audio'mimeType: 'audio/mpeg'。图片应传入正确的 image/* MIME 类型;图片没有时间轴,不支持暂停、恢复、Seek 和倍速。

选集参数 CastPanelMediaItem

参数 类型 必填 说明 默认值 可选参数
id string 选集稳定 ID。 数组下标
resumeKey string 该选集独立的断点续播键。 优先使用 id 稳定业务 ID
title string 选集显示名称。
url string 该集媒体 URL;缺少时只派发业务事件。 http / https
mediaKind CastMediaKind 该集媒体类型。 根据 MIME 或 URL 推断 video / audio / image
mimeType string 该集媒体 MIME 类型。 根据媒体类型推断
poster string 该集封面 URL。 http / https
duration number 该集时长,单位秒。 0,表示未知 大于 0
startPosition number 该集显式起播位置。 0 大于等于 0
episodeIndex number 业务剧集序号,不影响数组下标。 数组下标 大于等于 0
qualityLabel string 当前项的清晰度文案。
extras any 业务透传数据。
textTracks Array<CastTextTrack> 该集对应的文本轨。 []
preferredTextTrackId string 该集优先文本轨 ID。 默认轨或第一个有效轨
textTrackFailurePolicy string 文本轨失败后的媒体处理方式。 continue-media continue-media / fail-cast

多集场景应传入完整 episodes、正确的 currentEpisodeIndex,并确保每一集都有接收设备可访问的 URL。

清晰度参数 CastPanelQualityItem

参数 类型 必填 说明 默认值 可选参数
id string 清晰度稳定 ID。 数组下标 auto / 720p / 1080p
label string 面板显示名称。
url string 该清晰度对应的媒体 URL。 http / https
mediaKind CastMediaKind 媒体类型。 根据 MIME 或 URL 推断 video / audio / image
mimeType string 媒体 MIME 类型。 根据媒体类型推断
bitrate number 码率,单位 bps。 大于 0
selected boolean 是否为当前选中项。 false true / false
extras any 业务透传数据。
textTracks Array<CastTextTrack> 当前清晰度对应的文本轨。 []
preferredTextTrackId string 优先文本轨 ID。 默认轨或第一个有效轨
textTrackFailurePolicy string 文本轨失败后的媒体处理方式。 continue-media continue-media / fail-cast

没有配置真实清晰度 URL 时,插件不会伪造切换成功。

文本轨参数 CastTextTrack

参数 类型 必填 说明 默认值 可选参数
id string 同一媒体内唯一的文本轨 ID。
kind string 文本轨用途。 subtitle / caption / lyrics
format string 文本轨格式;embedded 表示媒体内嵌轨。 embedded / srt / vtt / ass / lrc
url string 外挂字幕或歌词的公开 URL;内嵌轨不需要。 http / https
language string 语言标签,例如 zh-CN
label string 面向用户的轨道名称。
isDefault boolean 未指定优先轨道时是否优先选择。 false true / false

外挂字幕和歌词是否真正显示,取决于接收设备是否支持对应文本轨能力。startCast.success 只表示媒体投屏流程成功,不能作为字幕已经显示的证明。

连接与播放控制参数

参数 类型 必填 说明 默认值 可选参数
connectDevice.options.deviceId string 从设备事件或列表中取得的设备 ID。
disconnectDevice.options.stopRemote boolean 断开前是否先停止接收端播放。 false true / false
startCast.options.deviceId string Android、Harmony 和微信可指定目标设备;跨端流程建议先调用 connectDevice() 当前设备
startCast.options.media CastMediaSource 要投屏的媒体资源。
startCast.options.autoConnect boolean 兼容字段;各 App 端处理不同,跨端项目不要依赖它自动连接。 按平台处理 true / false
seekCast.options.position number 目标播放位置,单位秒。 大于等于 0
setCastVolume.options.volume number 接收端音量。 0-1
setCastPlaybackRate.options.rate number 目标播放倍率。 大于 0

暂停、恢复、Seek、音量和倍速最终取决于接收设备是否实现对应控制能力。接收端拒绝时会触发 fail,不会只修改界面文字来伪造成功。

跨端自定义界面的稳定调用顺序是:先让用户选择设备,调用 connectDevice() 成功后,再调用 startCast()

主要返回值

CastCapabilities

调用 getCastCapabilities() 获取:

字段 类型 说明
supported boolean 当前平台是否支持真实投屏。
platform string 当前运行平台。
adapter string 当前使用的投屏适配方式。
discovery boolean 是否支持搜索设备。
builtinPanel boolean 是否支持插件内置面板。
mediaCast boolean 是否支持真实媒体投屏。
systemRoute boolean 是否支持系统路由入口,例如 iOS AirPlay。
pause / resume / seek / volume boolean 是否具备对应控制入口。
requiresCustomBase boolean 当前平台是否需要包含插件的自定义基座。
reason string 不支持时的说明。

即使能力入口存在,某台电视仍可能不支持暂停、Seek、音量或倍速,应继续处理各 API 的失败回调。

CastDevice

字段 类型 说明
id string 设备唯一 ID,连接设备时使用。
name string 设备显示名称。
type string 设备类型:dlna / airplay / system / unknown
host string 可获取时返回设备 IP。
modelName string 可获取时返回设备型号。
manufacturer string 可获取时返回设备厂商。
connected boolean 当前是否已连接。

CastSessionState

调用 getCastSessionState() 获取:

字段 类型 说明
initialized boolean 是否已经初始化。
discovering boolean 是否正在搜索设备。
state string 当前连接和播放状态。
currentDevice CastDevice | null 当前设备。
currentMedia CastMediaSource | null 当前媒体。
devices Array<CastDevice> 当前设备列表。
currentTime number 当前播放位置,单位秒。
duration number 当前媒体时长,单位秒。
volume number 当前音量,范围 0-1
volumeKnown boolean 音量是否已经从当前设备确认。
playbackRate number 最近一次确认的播放倍率。
lastError CastFail | null 最近一次错误。

volumeKnownfalse 时,应显示“同步中”或“未知”,不要把 volume 当成接收端真实音量。

CastMediaInspection

调用 inspectCastMediaSource() 获取:

字段 类型 说明
castable boolean 根据静态规则判断是否适合进入投屏流程。
emptyUrl boolean URL 是否为空。
httpUrl boolean 是否为 http/https URL。
localFile boolean 是否疑似本地文件、临时文件、Blob 或 Data URL。
drmSuspected boolean 是否疑似 DRM 或加密流。
authSuspected boolean 是否疑似依赖登录态、Cookie 或 Authorization。
lanAddress boolean 是否疑似局域网媒体地址。
likelyVideo / likelyAudio / likelyImage boolean 静态识别出的媒体类型特征。
mediaKind string 当前识别出的媒体类型。
riskFlags Array<string> 风险标记。
suggestions Array<string> 面向业务的处理建议。
message string 检查结果摘要。

该方法不会联网测试电视是否真的能够访问媒体 URL,最终结果仍需在目标设备上确认。

事件

// 使用同一个函数引用注册和移除监听。
const handleCastEvent = (event) => {
  console.log(event.name, event.payload)
}

CastScreen.onCastEvent('*', handleCastEvent)

function leavePage() {
  CastScreen.offCastEvent('*', handleCastEvent)
}
事件 说明
ready 投屏环境初始化完成。
discoveryStart / discoveryStop 设备搜索开始或结束。
deviceFound / deviceLost 发现设备或设备离线。
deviceListChange 当前设备列表发生变化。
panelShow / panelHide 面板或业务面板入口显示、隐藏。
connectStart / connected / disconnected 设备连接状态变化。
castStart 媒体投屏开始。
stateChange 播放、暂停、停止或错误状态变化。
progress 接收端播放进度变化。
volumeChange 接收端音量变化。
customAction 选集、清晰度、主题或业务自定义操作。
error 投屏流程发生错误。

事件名传 * 可以监听全部事件。移除单个监听时,必须向 offCastEvent 传入注册时的同一个回调函数。

错误码

错误码 含义 建议处理
9030001 当前平台或功能不支持。 查询 getCastCapabilities(),按平台显示降级提示。
9030002 参数不合法。 检查必填字段、数值范围和数组内容。
9030003 当前运行环境不可用。 确认 App 使用了包含插件的自定义基座,或微信基础库具备所需 Socket API。
9030004 搜索设备失败。 检查同一 Wi-Fi、本地网络权限、组播能力和路由器隔离设置。
9030005 没有找到可用设备。 确认电视已开启 DLNA/媒体接收功能后重新搜索。
9030006 连接设备失败。 刷新设备列表并重新选择仍在线的设备。
9030007 媒体地址不可投屏。 使用接收设备可直接访问的普通 http/https URL。
9030008 媒体播放失败。 检查媒体编码、MIME、URL、Range 支持和电视兼容性。
9030009 播放控制失败。 当前设备可能不支持暂停、Seek、音量、停止或目标倍率。
9030010 内置面板展示失败。 检查当前平台是否支持内置面板,以及页面是否处于可展示状态。
9030011 当前音频格式不支持。 使用 MP3,并设置 mimeType: 'audio/mpeg'
9030012 文本轨参数不合法。 检查轨道 ID、格式、URL 和优先轨道 ID。
9030013 当前平台或接收端不支持文本轨。 改用硬字幕或支持对应能力的接收设备。
9030014 文本轨选择或发送失败。 检查字幕 URL、语言、格式和接收端支持情况。

常见问题

搜索不到电视

按以下顺序检查:

  1. 确认电视开启的是 DLNA、媒体投屏或媒体接收功能,而不只是 Miracast。
  2. 手机与电视连接同一个可互访 Wi-Fi。
  3. 关闭访客网络、AP 隔离或会阻止局域网设备互访的设置。
  4. App 确认使用了包含当前插件的自定义基座。
  5. iOS 确认已经允许本地网络访问,并完成 Multicast Networking 权限配置。
  6. 微信小程序确认当前基础库具备 UDP/TCP Socket 能力。

手机可以播放,电视却无法播放

媒体是由电视直接下载,不是手机把画面转发给电视。请检查:

  • URL 是否为电视能够直接访问的 http/https 地址。
  • 是否依赖 Cookie、Authorization、Referer、防盗链或短时签名。
  • 是否为 DRM、加密 HLS/DASH 或需要登录的资源。
  • 视频编码和封装是否被电视支持。
  • 远程 MP4 是否支持 HTTP Range;拖动进度通常需要服务端正确返回分段内容。
  • 部分旧电视不支持 HTTPS,可先用普通 HTTP 媒体排除兼容问题。

面板 2 没有显示选集或下一集

请确认:

  • 使用了 panelStyle: 'minimal'
  • showEpisodeControls 没有设置为 false
  • episodes 至少包含两个有效项目。
  • 每一项都有标题和接收设备可访问的 URL。
  • currentEpisodeIndex 是正确的数组下标。
  • App 已制作并安装包含当前插件代码的自定义基座或 IPA。

单集场景不会提供可用的下一集操作,这是正常表现。

倍速切换失败

倍速是电视或系统播放器的真实能力。插件只有在接收端确认目标倍率后才会更新状态。电视拒绝目标倍率时,应保留原倍率并提示当前设备不支持。

微信小程序、Web/H5 和支付宝小程序当前不支持 setCastPlaybackRate

字幕或歌词没有显示

外挂字幕和歌词没有统一适用于所有电视的 DLNA 标准。插件可以发送兼容信息,但最终是否显示取决于接收设备。

如果必须保证显示,优先选择:

  1. 已经烧录在视频画面中的硬字幕。
  2. AirPlay 媒体自身包含的可选字幕轨。
  3. 已验证支持对应外挂字幕格式的电视或盒子。

面板参数 subtitle 只是面板提示文案,不是媒体字幕。

图片为什么不能暂停或拖动进度

图片没有播放时间轴,因此不支持暂停、恢复、Seek、倍速和进度轮询。iOS 图片投屏应选择 DLNA 设备,不应把图片当成 AirPlay 视频播放。

停止播放后为什么设备仍然连接

stopCast() 只停止当前媒体,方便继续向同一设备投屏其他内容。需要同时停止并断开时使用 disconnectDevice({ stopRemote: true })

微信小程序为什么没有内置面板

微信小程序支持局域网 DLNA 搜索和控制,但不提供插件内置原生面板,需要使用自己的弹窗、设备列表和播放控制界面。

微信开发者工具提示 connect fail: invalid address

微信小程序投屏依赖 wx.createUDPSocketwx.createTCPSocket,并受基础库、端口与网络策略限制。开发者工具本地调试时可以临时关闭合法域名校验来排除工具限制;真机仍必须满足局域网互访、端口和媒体地址要求。

Web/H5 或支付宝小程序为什么没有搜索结果

这两个平台当前只保留统一 API 和明确的降级结果,不支持真实 DLNA 搜索、连接或媒体投屏。应先查询能力:

// 不支持的平台使用 reason 显示业务提示。
const capabilities = CastScreen.getCastCapabilities()
if (!capabilities.supported) {
  console.log(capabilities.reason)
}

iOS AirPlay 有声音但没有画面

AirPlay 音频路由成功不等于视频已经进入外部播放。请检查媒体是否包含可播放的视频轨、编码是否被接收器支持,以及电视是否真正进入 AirPlay 视频播放状态。

完整示例

完整示例包含两套内置面板、自定义设备列表、视频/MP3/图片投屏、选集、清晰度、播放控制、诊断和媒体预检。业务页面仍应只从插件根目录导入 API。

注意事项

  • 手机与电视必须处于同一可互访局域网。
  • 插件投送的是媒体 URL,不是手机屏幕镜像,也不提供 Miracast、录屏推流或 DRM 破解能力。
  • 媒体地址必须能由电视直接访问。本地文件、临时文件、Blob、Data URL、Cookie、Authorization 和 DRM 媒体不能直接投屏。
  • App Android、iOS、Harmony 使用真实原生能力时,需要制作并安装包含插件的自定义基座或对应安装包。
  • Android 所需的网络、Wi-Fi 状态和组播权限由插件声明;电视仍需开启 DLNA/媒体接收能力。
  • Harmony 需要网络访问能力;自动搜索仍会受到路由器和系统局域网策略影响。
  • 微信小程序不需要 App 自定义基座,但受微信 Socket、端口和局域网策略限制。
  • success 回调表示当前 API 已按平台规则确认成功,不应仅凭按钮点击更新为“投屏成功”。
  • Seek、音量、倍速、暂停和恢复是否可用,最终取决于电视或盒子的实现。
  • 图片没有时间轴,不支持暂停、恢复、Seek 和倍速。
  • 外挂字幕、歌词和弹幕是三种不同能力,不能互相替代。
  • volumeKnown: false 时不要把 volume 显示成接收端真实音量。
  • 页面卸载时应调用 offCastEvent 释放持续事件监听。
  • resumeKey 应使用课程 ID、剧集 ID 等稳定业务标识,不要使用包含鉴权参数的媒体 URL。
  • 诊断包可能包含当前设备、会话和最近事件。提供给技术支持前,应先检查是否含有业务不希望对外提供的信息。

iOS 本地网络与自动搜索权限

本地网络说明

iOS 使用 DLNA 搜索和控制时,最终 App 的 Info.plist 需要包含本地网络用途说明:

<!-- 用于向用户解释为什么需要访问局域网投屏设备。 -->
<key>NSLocalNetworkUsageDescription</key>
<string>用于发现和连接局域网投屏设备。</string>

如需访问局域网中的普通 HTTP 设备描述或控制地址,应只放开本地网络:

<!-- 仅允许局域网请求,不要全局放开所有非 HTTPS 请求。 -->
<key>NSAppTransportSecurity</key>
<dict>
  <key>NSAllowsLocalNetworking</key>
  <true/>
</dict>

不建议为了投屏功能全局开启 NSAllowsArbitraryLoads。首次访问本地网络时,iOS 会显示系统授权提示;如果用户拒绝,需要在系统设置中重新允许本地网络访问。

申请 Multicast Networking managed capability

DLNA 自动发现使用 SSDP 组播。iOS 正式构建需要 Apple 批准 Multicast Networking managed capability。

  1. 登录 Apple Developer 账号。
  2. 打开 Multicast Networking Entitlement Request
  3. 填写对应 App ID 和使用场景,说明 App 使用 SSDP 在同一局域网发现 DLNA 电视或盒子。
  4. Apple 审批通过后,在对应 App ID 上启用 Multicast Networking 能力。
  5. 重新生成并下载包含该能力的 provisioning profile。
  6. 确认最终签名权限包含 com.apple.developer.networking.multicast
  7. 使用新的 provisioning profile 重新制作 iOS 自定义基座或 IPA。
  8. 安装新构建;如设备仍运行旧签名能力,先卸载旧包再重新测试自动搜索。

签名权限应包含:

<!-- DLNA 自动 SSDP 搜索需要的组播权限。 -->
<key>com.apple.developer.networking.multicast</key>
<true/>

如果打包提示 Provisioning profile doesn't include the Multicast Networking capability,说明当前描述文件尚未包含该能力。应完成 Apple 审批、App ID 开通和 provisioning profile 更新后重新打包;删除该权限会导致 DLNA 自动搜索不可用。

尚未获得审批时,可以使用已知设备描述地址和 manualDeviceDescriptionUrl 调试局域网连接,但不能使用 DLNA 自动搜索。AirPlay 仍通过 iOS 系统路由选择器使用,不需要实现私有 AirPlay 协议。

Apple 参考文档:

作者系列 UTS 插件

以下为已在 DCloud 插件市场上架的作者系列 UTS 插件,可按业务场景组合使用。未列出的插件表示当前未确认公开市场页,后续上架后再补充。

插件 能力方向 插件市场
lizhao-nfc-pro NFC 标签读写、NDEF、IsoDep 与诊断 查看插件
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、安全接入与脱敏诊断 查看插件

隐私、权限声明

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

Android 网络访问、Wi-Fi 状态、Wi-Fi 组播权限;iOS 本地网络、AirPlay 系统路由能力,自动 SSDP 搜索需 Apple Multicast Networking entitlement;Harmony 网络访问权限 ohos.permission.INTERNET

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

投屏设备信息、媒体 URL、播放状态、用户操作事件

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