更新记录

1.0.0(2026-11-13) 下载此版本

支持自定义地址 支持参数调整


平台兼容性

uni-app x(4.62)

Chrome Safari Android iOS 鸿蒙 微信小程序
× × × √ × ×

其他

多语言 暗黑模式 宽屏模式 蒸汽模式
× × × √

跨 App 屏幕共享(RTMP 推流)

一行调用,把整块 iPhone 屏幕(含其它 App、桌面、系统界面)以标准 RTMP 推出去。可对接 SRS / MediaMTX / Nginx-rtmp / 视频号 / 抖音等任何支持 RTMP 的服务。

基于 iOS 官方 ReplayKit 广播上传扩展(Broadcast Upload Extension)实现,是 iOS 上实现「跨 App 全屏录屏」的唯一官方路径。

平台:仅 App-iOS(真机,iOS 15.0+)。Android / H5 / 小程序无等价机制,调用会统一返回不支持。


先体验:零配置,装上就能看效果

不用写代码、不用配证书、不用管 App Group,先确认效果,再决定是否接入。

步骤 做什么
1 用 iPhone 打开体验链接:点此安装体验 App(TestFlight 公开链接,无需提供 UDID)
2 打开「屏幕共享体验」,填入一个你自己的 RTMP 推流地址,例如 rtmp://你的服务器:1935/live/test
3 点「开始屏幕共享」→ 系统弹出「开始直播」面板 → 点一下面板里的按钮
4 切到桌面、微信或任意 App,推流都不会中断;用 VLC 或 RTMP 服务自带的播放页打开同一地址即可看到画面

体验 App 不带授权码,因此画面正中会叠加一行斜排的「未授权」水印,且单次推流最长 60 秒 —— 除这两点外,功能与正式授权完全一致。 换成正式授权:把授权码填进 startScreenCapture 的 license 参数,水印消失、不再限时(详见 第七节 授权说明)。

手边没有 RTMP 服务器?在任意一台电脑上解压运行 MediaMTX(零配置文件,默认监听 1935),推流地址就是 rtmp://<那台电脑的IP>:1935/live/test。

确认效果后再往下看接入步骤即可。


一、功能特性

特性 说明
真正的跨 App 录屏 用户在系统面板确认开始后,切到桌面、微信或任意 App 都会继续录制
后台持续推流 主 App 切后台甚至退出,推流都不中断(推流跑在扩展进程)
标准 RTMP 输出 H.264(VideoToolbox 硬编) + RTMP,服务端零改造
完整的参数控制 分辨率、帧率、码率、H.264 Profile、关键帧间隔均可在 JS 侧下发
状态可订阅 idle / connecting / streaming / stopped / error 全程可回调
纯离线授权 授权码本地校验,不联网、不请求服务器
零第三方依赖 不含任何第三方 SDK,扩展体积小,不引入额外二进制风险
无需 Xcode 广播扩展已随插件提供,只需 HBuilderX 即可打包

二、平台与前置条件

项 要求
宿主 uni-app x(uni-app-x.vapor = true),HBuilderX 4.71 及以上
运行环境 iOS 15.0 及以上,真机(模拟器不支持广播扩展)
开发者账号 付费 Apple Developer 账号。广播扩展需要独立的扩展 App ID 与描述文件,免费个人账号不具备
Bundle ID 规则 扩展 Bundle ID 必须是「主 App Bundle ID + 点号前缀」,例如主 App com.abc.player → 扩展 com.abc.player.rtmp(Apple 硬性要求)

三、安装

在插件市场点击「下载并导入插件」,插件会自动落到工程的 uni_modules/bgyx-screencap/ 目录。

⚠️ 导入后必须重新打包一次才会生效:本插件内含 iOS 原生扩展(BgyxScreenCap.appex),属于原生插件,HBuilderX 的标准基座里不含这段原生代码,直接运行会提示找不到模块。 请在 HBuilderX 中执行「运行 → 运行到手机或模拟器 → 制作自定义基座」(需先在 nativeResources/ios/ 放好描述文件,见第四节),或直接云打包运行正式包。

业务代码中按如下方式引入:

import {
  startScreenCapture,
  stopScreenCapture,
  isScreenCapturing,
  getScreenCaptureState,
  getScreenCaptureLastError,
  onScreenCaptureState
} from '@/uni_modules/bgyx-screencap'

四、快速开始

插件提供两种运行模式,建议先用方式一确认效果,再按方式二上线。

方式一 · 内置参数模式 方式二 · App Group 模式
推流地址来源 扩展自身的 Info.plist,打包时固定 JS 侧运行期下发,随时可改
分辨率/码率等参数 同样写在扩展 plist 中 JS 侧下发
状态回调 不支持 支持
代码停止推流 不支持(从系统控制中心停止) 支持
额外配置 无需 App Group 需配置 App Group
适合场景 快速验证画面 正式上线

方式一:内置参数模式(免 App Group)

第 1 步:创建扩展 App ID 在 Apple Developer 后台创建 App ID,Bundle ID 填 <你的主 App Bundle ID>.rtmp,Capabilities 一个都不用勾。

第 2 步:准备扩展描述文件 为该 App ID 创建一个描述文件(Development / Ad Hoc / App Store 均可,无需 App Groups),下载后放进工程 nativeResources/ios/ 目录。

第 3 步:写配置文件 在工程 nativeResources/ios/ios-extension.json 中写入:

{
  "BgyxScreenCap.appex": {
    "identifier": "com.abc.player.rtmp",
    "profile": "ios-BgyxScreenCap.mobileprovision",
    "plists": {
      "BgyxRtmpUrl": "rtmp://your-server:1935/live/test",
      "CFBundleDisplayName": "屏幕共享",
      "CFBundleShortVersionString": "1.0.0",
      "CFBundleVersion": "1",
      "NSLocalNetworkUsageDescription": "用于把屏幕画面推流到 RTMP 服务器"
    }
  }
}

只要 BgyxRtmpUrl 非空,插件即按内置参数模式运行。 此模式下推流地址在打包时固定,运行期无法修改;换地址需重新打包。

第 4 步:调用

// 地址已内置在扩展 plist 中,rtmp 可留空
startScreenCapture({ rtmp: '' })

返回以 OK 开头时,系统会弹出「开始直播」面板,用户点一下面板中的按钮即开始推流。

方式二:App Group 模式(正式上线)

在方式一的基础上,额外完成以下四步:

(1) 创建 App Group 并绑定 在 Apple Developer 后台创建一个 App Group(例如 group.com.abc.player),并把 主 App 与 扩展 两个 App ID 都加入该 App Group。改过 Capabilities 的 App ID 必须重新生成描述文件。

(2) 扩展配置:nativeResources/ios/ios-extension.json

{
  "BgyxScreenCap.appex": {
    "identifier": "com.abc.player.rtmp",
    "profile": "ios-BgyxScreenCap.mobileprovision",
    "plists": {
      "BgyxAppGroupIdentifier": "group.com.abc.player",
      "CFBundleDisplayName": "屏幕共享",
      "CFBundleShortVersionString": "1.0.0",
      "CFBundleVersion": "1",
      "NSLocalNetworkUsageDescription": "用于把屏幕画面推流到 RTMP 服务器"
    },
    "entitlements": {
      "com.apple.security.application-groups": ["group.com.abc.player"]
    }
  }
}

此模式下不要写 BgyxRtmpUrl,否则会退回内置参数模式,JS 下发的地址将被忽略。

(3) 主 App 声明共享权限:nativeResources/ios/UniApp.entitlements

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>com.apple.security.application-groups</key>
    <array>
        <string>group.com.abc.player</string>
    </array>
</dict>
</plist>

(4) 工程根目录 Info.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>BgyxAppGroupIdentifier</key>
    <string>group.com.abc.player</string>
    <key>BgyxScreenCapExtension</key>
    <string>com.abc.player.rtmp</string>
    <key>NSLocalNetworkUsageDescription</key>
    <string>用于把屏幕画面推流到 RTMP 服务器</string>
</dict>
</plist>
  • BgyxAppGroupIdentifier:不填则使用插件默认值 group.com.bgyx.screencap。
  • BgyxScreenCapExtension:可选,用于给系统选择器预选扩展。
  • NSLocalNetworkUsageDescription:推流地址为局域网 IP 时必需,否则 iOS 不会弹出本地网络授权。

业务代码

onScreenCaptureState((state, message) => {
  console.log('屏幕共享状态', state, message)
})

startScreenCapture({
  rtmp: 'rtmp://your-server:1935/live/room1',
  license: 'BGYX1.xxx.yyy'
})

五、API 说明

5.1 startScreenCapture(options: BgyxScreenCapOptions): string

下发参数并弹出系统「开始直播」面板。

字段 类型 默认值 说明
rtmp string — 推流地址 rtmp://host[:port]/app/streamKey。App Group 模式下必填
license string '' 授权码,纯离线校验。留空 / 无效 / 过期 → 试用模式
width number 0 输出宽度,0 = 按屏幕自动推导(短边 720)
height number 0 输出高度,0 = 自动
fps number 30 帧率
bitrate number 4000000 码率,单位 bps
gop number 0 关键帧间隔(帧),0 = fps × 2
profile string 'baseline' H.264 Profile:baseline / main / high
scaleQuality number 0 0 = 快速缩放;1 = 高质量重采样(小字更锐利)
rateLimitPercent number 150 码率上限倍数(%),0 = 不限制
keyFrameIntervalSeconds number 2 关键帧间隔秒数,0 = 仅按 gop
extension string '' 扩展 Bundle ID,留空则读主 App Info.plist 的 BgyxScreenCapExtension

默认值即兼容性最优组合:baseline Profile + 2 秒关键帧间隔,实测各类播放器与转码服务均可正常播放,不确定时请勿修改。

返回值:以 OK 开头表示参数已下发、系统面板即将弹出;以 FAIL 开头表示失败,冒号后为原因。 注意:返回 OK 仅代表面板已弹出,真正开播需要用户在系统面板中点击一次按钮。

5.2 stopScreenCapture(): string

请求停止推流。扩展会在 1 秒内自行收尾并结束系统录屏。仅 App Group 模式有效。

5.3 isScreenCapturing(): boolean

是否处于 connecting 或 streaming。

5.4 getScreenCaptureState(): string

同步查询当前状态,返回 "state|message" 格式字符串。

5.5 getScreenCaptureLastError(): string

最近一次错误文本;无错误返回空串。

5.6 onScreenCaptureState(cb | null): void

订阅状态变化,回调参数为 (state: string, message: string);传 null 取消订阅。 订阅瞬间会先补发一次当前状态。仅 App Group 模式有效。

5.7 状态取值

state 含义
idle 未开始
connecting 正在连接 RTMP 服务器
streaming 推流中
stopped 已停止
error 出错,原因见 message

六、参数与画质调优

需求 调整方式
播放器播不了 / 转协议失败 使用 profile: 'baseline' + keyFrameIntervalSeconds: 2
画面文字不够清晰 scaleQuality: 1,或提高 bitrate
首帧出画慢 keyFrameIntervalSeconds: 1
流量偏大 降低 bitrate 或 fps,或把输出限制在 720p 以内
画面卡顿掉帧 提高 bitrate,fps 降至 24,scaleQuality: 0

width / height 填 0 时按屏幕短边 720 自动推导,横竖屏自动处理。


七、授权说明

  • 试用模式:未填写授权码、授权码无效或已过期时,画面会叠加居中斜排的水印,且单次推流最长 60 秒,到点自动结束。除水印与时限外,功能与正式授权完全一致。
  • 正式授权:授权码为纯离线校验格式,不联网、不请求任何服务器。授权码绑定宿主主 App 的 Bundle ID 与有效期,换 App 或使用他人授权码均无效。
  • 启用方式:将授权码传入 startScreenCapture 的 license 参数即可。
  • 验证是否生效:画面水印消失且推流超过 60 秒仍在继续,即表示授权已生效。
  • 获取授权码:请通过本插件市场页面下方的「联系作者」入口沟通。

八、常见问题

Q:一定要付费开发者账号吗? 是。广播上传扩展需要独立的扩展 App ID 与描述文件,免费个人账号不具备该能力,这一点由 Apple 的账号体系决定,无法绕过。

Q:调用返回 OK,但服务端没看到流。 OK 只表示系统面板已弹出,需要在面板中点击一次按钮才会真正开始推流。此外请确认流地址可达、端口已放行、app/streamKey 正确;若推流地址是局域网 IP,需要 NSLocalNetworkUsageDescription。

Q:状态一直是 idle,收不到回调。 说明当前运行在内置参数模式(未配置 App Group)。该模式下不支持状态回传,属预期行为。

Q:切到别的 App 就断了? 不会。录制的是系统级屏幕,跨 App 与后台均持续。若中途停止,请先确认是否触发了 60 秒试用时限。

Q:修改了插件代码,真机没有任何变化。 请依次检查:工程中是否存在插件的多份副本(运行时使用的是 uni_modules/ 下那一份);以及 unpackage/dist/build/app-ios/uni_modules/<插件>/utssdk/app-ios/Plugins/ 下是否有缓存的旧 .appex,如有请删除后重新打包。

Q:支持音频轨吗? 当前版本只输出视频轨。

Q:Android / H5 能用吗? 不能。这些平台没有与 iOS 广播上传扩展等价的机制,调用会返回不支持。


九、注意事项

  • 插件依赖 uni_modules 规范,请勿改动插件内部目录结构。
  • 请勿将扩展的 Bundle ID 配置成与主 App 相同或缺少前缀,Apple 会在签名阶段拒绝这种配置。
  • 内置参数模式下推流地址写死在扩展包内,请勿在正式上线时使用。
  • 广播扩展一旦被系统启动,主 App 无法直接终止,这是 iOS 的安全模型限制;stopScreenCapture() 采用标记文件通知扩展自行收尾的方式实现,通常 1 秒内结束。用户也可从系统控制中心直接停止。

隐私、权限声明

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

NSLocalNetworkUsageDescription(推流地址为局域网 IP 时必需,否则系统不弹出本地网络授权)

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

插件不采集任何数据。屏幕画面由 iOS ReplayKit 在本机采集、本机 H.264 硬编码,仅推送到开发者自行填写的 RTMP 服务器地址(插件不内置任何服务器地址);授权码为纯离线本地校验,不联网、不上传任何信息。

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

无

许可协议

MIT协议