更新记录

1.0.0(2026-06-20) 下载此版本

首次发布 jz-screen-share

功能特性

  • 提供 H5 屏幕共享流管理能力,定位为“只负责流,不负责通讯”。
  • 支持 PC 端通过 getDisplayMedia 采集屏幕、窗口或浏览器标签页。
  • 支持采集屏幕画面、系统音频,并可尝试合并麦克风音频。
  • 支持输出本地 MediaStream,方便交给外部 WebRTC/通讯插件传输。
  • 支持 PC 与移动端接收远端 MediaStream,并绑定到 videocanvas 播放。
  • 支持发送端暂停、继续、停止、截图、录制结果输出。
  • 支持帧切片与实时帧回调,可用于 Canvas 渲染、画面分析或 DataChannel 自定义传输。
  • 支持远端流静音、音量调节、视频启用/禁用、轨道状态监听和音量监听。
  • 提供 Vue3 组件:ScreenShareSenderScreenShareReceiver
  • 提供 Vue 插件自动注册全局组件。
  • 提供平台能力检测 API:canSend()canReceive()getRole()getPlatformInfo()

使用场景

  • 在线会议屏幕共享。
  • 远程演示、远程协助。
  • 在线课堂课件共享。
  • PC 端采集屏幕后交给 WebRTC 插件传输。
  • 移动端作为观看端接收并播放 PC 屏幕共享。
  • 通过帧切片做自定义画面传输或 Canvas 渲染。

平台说明

  • PC H5:支持发送和接收,具体能力取决于浏览器是否支持 getDisplayMedia
  • 移动端 H5:仅支持接收远端流,不支持发起屏幕采集。
  • App 与小程序:当前版本不支持。

注意事项

  • 屏幕采集需要 HTTPS 环境,localhost 调试除外。
  • 插件不包含信令、房间、SDP/ICE 交换、PeerConnection 管理、重连等通讯逻辑。
  • 使用实时通话能力时,需要业务层或外部插件负责把 MediaStream 从发送端传到接收端。

平台兼容性

uni-app(4.74)

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

jz-screen-share

jz-screen-share 是一个面向 uni-app Vue3 H5 的屏幕共享流管理插件,用来做 PC 端屏幕采集与流输出PC/移动端远端屏幕流接收与播放

插件只负责屏幕流相关能力:采集、预览、录制结果、截图、帧切片、远端流接入、video/canvas 渲染、音量和轨道状态监听。它 不负责信令、房间、RTCPeerConnection、SDP、ICE、DataChannel 等通讯逻辑,这些需要由业务或外部 WebRTC 插件完成。

能拿来干嘛

适合以下场景:

  • 在线会议里的屏幕共享
  • 远程协助、远程演示
  • 在线课堂、直播课件共享
  • PC 屏幕采集后交给 WebRTC 插件传输
  • 接收 WebRTC 远端 MediaStream 并在 PC 或移动端播放
  • 将屏幕画面切成帧,通过 Canvas 或 DataChannel 做自定义传输/渲染
  • 获取屏幕截图、录制 BlobUrl/DataUrl,用于预览或下载

平台支持

能力 说明
PC H5 Chrome / Safari 发送 + 接收 可调用 getDisplayMedia 采集屏幕,可接收远端流
移动端 H5 仅接收 移动端浏览器通常不支持 getDisplayMedia,不能发起屏幕共享
App / 小程序 不支持 当前插件定位为 H5 Web API 能力

屏幕采集需要 HTTPS 环境,localhost 调试除外。

核心设计

PC 发送端:
getDisplayMedia() -> MediaStream -> ScreenShareStreamOutput.getStream()
                                         |
                                         | 交给外部通讯插件传输
                                         v
PC/移动端接收端:
外部通讯插件 ontrack 得到 MediaStream -> ScreenShareStreamInput.attachStream() -> video/canvas 播放

职责边界:

  • 本插件负责:屏幕采集、流输出、流接入、播放渲染、帧切片、音量/轨道状态监听
  • 本插件不负责:登录、房间、信令、WebRTC 连接、SDP/ICE 交换、重连、心跳

安装与引入

将插件放入项目 uni_modules/jz-screen-share 后,在页面中按需引入:

import {
  getScreenShareManager,
  destroyScreenShareManager,
  canSend,
  canReceive,
  getRole,
  ScreenShareStreamOutput,
  ScreenShareStreamInput,
  ScreenShareVolumeMeter,
  LiveFrameRenderer,
  getConstraintsByScenario
} from '@/uni_modules/jz-screen-share/js/index.js'

如果使用 Vue 组件,可在 main.js 中全局注册:

import { createSSRApp } from 'vue'
import App from './App.vue'
import ScreenShareVuePlugin from '@/uni_modules/jz-screen-share/js/vue/index.js'

export function createApp() {
  const app = createSSRApp(App)
  app.use(ScreenShareVuePlugin)
  return { app }
}

基础用法:PC 端开始屏幕采集

import {
  getScreenShareManager,
  destroyScreenShareManager,
  canSend
} from '@/uni_modules/jz-screen-share/js/index.js'

if (!canSend()) {
  console.log('当前设备不能发起屏幕共享,只能接收')
}

const manager = getScreenShareManager()

manager.onStart(() => {
  console.log('屏幕共享已开始')
})

manager.onStop((result) => {
  console.log('屏幕共享已停止', result)
  // result 内可包含 duration、frameCount、blobUrl、dataUrl 等,取决于 returnType
})

manager.onError((error) => {
  console.error('屏幕共享错误', error)
})

await manager.start({
  width: 1920,
  height: 1080,
  frameRate: 30,
  audio: true,
  microphone: true,
  cursor: 'always',
  returnType: ['blobUrl']
})

// 用于本地预览或交给外部 WebRTC 插件
const stream = manager.getStream()

// 截图
const photo = manager.takePhoto({ format: 'jpeg', quality: 0.9 })

// 暂停、继续、停止
manager.pause()
manager.resume()
manager.stop()

// 页面卸载时清理
destroyScreenShareManager()

和 WebRTC 通讯插件配合

发送端:输出本地屏幕流

import {
  getScreenShareManager,
  ScreenShareStreamOutput
} from '@/uni_modules/jz-screen-share/js/index.js'

const manager = getScreenShareManager()
await manager.start({ audio: true, microphone: true })

const output = new ScreenShareStreamOutput()
output.setStream(manager.getStream())

const stream = output.getStream()

// 示例:交给你自己的 WebRTC 连接层
// rtcAdapter.setLocalStream(stream)
// 或 stream.getTracks().forEach(track => peerConnection.addTrack(track, stream))

output.setVideoEnabled(true)
output.setAudioEnabled(true)
console.log(output.getStats())

接收端:接入远端屏幕流

import { ScreenShareStreamInput } from '@/uni_modules/jz-screen-share/js/index.js'

const input = new ScreenShareStreamInput({
  onStream: ({ peerId, stream }) => {
    input.bindToVideo(peerId, document.querySelector('#remoteVideo'))
  }
})

// 示例:外部 WebRTC 层收到远端流后注入
// peerConnection.ontrack = (event) => {
//   input.attachStream('peer-001', event.streams[0])
// }

input.attachStream('peer-001', remoteMediaStream)
input.setMuted('peer-001', false)
input.setVolume('peer-001', 0.8)

// 不需要时移除
input.detachStream('peer-001')
input.dispose()

Vue 组件用法

发送端组件

<template>
  <ScreenShareSender
    ref="senderRef"
    :width="1920"
    :height="1080"
    :frame-rate="30"
    :audio="true"
    :show-preview="true"
    @stream-ready="onStreamReady"
    @error="onError"
  />
</template>

<script setup>
function onStreamReady({ stream, streamOutput, hasAudio, hasVideo }) {
  // 将 stream 交给外部通讯插件传输
  // rtcAdapter.setLocalStream(stream)
  console.log({ hasAudio, hasVideo })
}

function onError(error) {
  console.error(error)
}
</script>

接收端组件

<template>
  <ScreenShareReceiver
    ref="receiverRef"
    render-mode="video"
    :show-controls="true"
    @audio-volume="onAudioVolume"
  />
</template>

<script setup>
import { ref } from 'vue'

const receiverRef = ref(null)

function onRemoteStream(peerId, stream) {
  receiverRef.value.attachStream(peerId, stream)
}

function onAudioVolume({ peerId, volume }) {
  console.log(peerId, volume)
}
</script>

帧切片与 Canvas 渲染

开启 enableLiveFrame 后,可以监听实时帧数据,用于 Canvas 渲染、截图分析或通过 DataChannel 自定义传输。

import {
  getScreenShareManager,
  LiveFrameRenderer
} from '@/uni_modules/jz-screen-share/js/index.js'

const manager = getScreenShareManager()
const renderer = new LiveFrameRenderer(document.querySelector('#canvas'))

manager.onVideoFrameRecorded((frameData) => {
  const imageData = new ImageData(
    frameData.frameBuffer,
    frameData.width,
    frameData.height
  )
  canvasContext.putImageData(imageData, 0, 0)
})

manager.onLiveVideoFrameRecorded((liveFrameData) => {
  renderer.renderRawFrame(
    liveFrameData.frameBuffer,
    liveFrameData.width,
    liveFrameData.height
  )
})

await manager.start({
  width: 1280,
  height: 720,
  frameRate: 30,
  frameSize: 3,
  enableLiveFrame: true
})

常用 API

能力检测

canSend()       // 当前端是否可发起屏幕采集
canReceive()    // 当前端是否可接收播放
getRole()       // both | receiver
getPlatformInfo()

屏幕采集管理器

const manager = getScreenShareManager()

manager.start(options)
manager.pause()
manager.resume()
manager.stop()
manager.takePhoto(options)
manager.getStream()
manager.getVideoTracks()
manager.getAudioTracks()
manager.hasVideoTrack()
manager.hasAudioTrack()
manager.getState()
manager.getDuration()
manager.getFrameCount()

manager.onStart(callback)
manager.onPause(callback)
manager.onResume(callback)
manager.onStop(callback)
manager.onError(callback)
manager.onVideoFrameRecorded(callback)
manager.onLiveVideoFrameRecorded(callback)
manager.onStreamChange(callback)

流输出器

const output = new ScreenShareStreamOutput()

output.setStream(stream)
output.getStream()
output.getVideoTracks()
output.getAudioTracks()
output.hasVideoTrack()
output.hasAudioTrack()
output.setVideoEnabled(enabled)
output.setAudioEnabled(enabled)
output.getStats()
output.on(eventName, handler)
output.dispose()

流接入器

const input = new ScreenShareStreamInput()

input.attachStream(peerId, stream)
input.detachStream(peerId)
input.detachAll()
input.bindToVideo(peerId, videoElement)
input.bindToCanvas(peerId, canvasElement)
input.setMuted(peerId, muted)
input.setVolume(peerId, volume)
input.setVideoEnabled(peerId, enabled)
input.getStream(peerId)
input.getAllStreams()
input.getStreamCount()
input.dispose()

示例页面

项目内提供以下示例,可按需查看:

  • /pages/screen-share/basic/index:基础屏幕采集、预览、截图、录制结果
  • /pages/screen-share/frame-demo/index:帧切片与 Canvas 渲染
  • /pages/screen-share/stream-demo/index:流输出与流接入
  • /pages/screen-share/vue-demo/index:Vue 组件用法
  • /pages/screen-share/video-call/index:基于帧切片的数据通道通话示例
  • /pages/screen-share/stream-video-call/index:基于 MediaStream 的屏幕共享通话示例

注意事项

  1. PC 发送端需要浏览器支持 navigator.mediaDevices.getDisplayMedia
  2. 屏幕采集必须运行在 HTTPS 或 localhost
  3. 移动端只能接收远端屏幕共享流,不能调用屏幕采集。
  4. 是否能采集系统音频由浏览器和用户选择的共享源决定。
  5. 插件不会自动建立 WebRTC 连接,需要业务层把 MediaStream 交给通讯模块。
  6. 停止页面或组件卸载时,请调用 stop()dispose()destroyScreenShareManager() 释放资源。

隐私、权限声明

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

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

麦克风数据 屏幕数据

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

许可协议

MIT协议

暂无用户评论。