更新记录
1.0.0(2026-06-20) 下载此版本
首次发布
核心功能
- 帧切片方案(H5CameraManager):基于 getUserMedia + Canvas + MediaRecorder 的视频采集与实时帧切片
- MediaStream 方案(StreamCameraManager):专注于获取 MediaStream,适用于实时视频通话、WebRTC 推流
- 完全兼容 uni.createCameraContext API(H5 平台)
帧切片功能
onVideoFrameRecorded:实时视频帧切片回调,返回 ImageData 像素数据onLiveVideoFrameRecorded:WebRTC 实时帧回调,使用复用缓冲区降低 GC 压力frameSize参数控制切片频率(每隔 N 帧切片一次)LiveFrameRenderer实时帧渲染器,支持镜像显示与帧缓冲
MediaStream 方案
start()获取 MediaStream,可直接绑定<video>元素播放switchDevice()/switchFacingMode()设备与前后摄像头切换setMuted()/toggleMute()视频静音控制updateConstraints()动态更新视频约束
WebRTC 模块
CameraPublisher视频推流器,支持单个/批量推流与撤销CameraSubscriber视频订阅器,支持多路视频流管理与静音控制CameraVolumeMeter视频状态监听器,检测视频轨活跃状态与帧率
Vue 组件
CameraPreview画面预览组件,支持 stream/frame 两种模式CameraRecorder拍照/录像组件,微信风格交互(单击拍照、长按录像)- Vue 自动挂载插件
vuePlugin,全局注册组件
工具类
VideoUtils:帧处理(灰度、缩放、帧差异、运动检测)、格式转换(ImageData 转 Base64/Blob)VideoConvert:视频格式转换(ArrayBuffer/Base64/DataUrl/Blob/BlobUrl/File 互转)CameraDataSource:视频数据源工具,支持多种返回格式CameraConstraints:视频约束预设(默认/高质量/低延迟/会议/后置摄像头)
事件系统
- 帧切片方案:
onStart/onPause/onResume/onStop/onError - Stream 方案:
on('start')/on('stop')/on('error')/on('mute-change') - WebRTC 模块:
on('publish')/on('stream')/on('state-change')等
平台兼容性
uni-app(4.65)
| Vue2 | Vue3 | Chrome | Safari | app-vue | app-nvue | Android | iOS | 鸿蒙 |
|---|---|---|---|---|---|---|---|---|
| - | √ | √ | √ | √ | × | × | × | × |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | × | × | × |
jz-h5CameraManager H5 相机插件
H5 平台相机插件,完全兼容 uni.createCameraContext API。支持实时帧切片、MediaStream 流式采集、WebRTC 推流/订阅、实时视频通话、Vue 自动挂载组件。
仅支持 H5 平台 | Vue 3 | 需要 HTTPS 环境
目录
功能特性
- 完全兼容
uni.createCameraContextAPI(H5 平台) - 帧切片方案:实时视频帧切片(onVideoFrameRecorded),获取 ImageData 像素数据
- MediaStream 方案:获取 MediaStream,直接绑定
<video>播放,易于集成 WebRTC - WebRTC 推流/订阅:CameraPublisher / CameraSubscriber
- Vue 自动挂载组件:CameraPreview / CameraRecorder,无需手动引入
- 实时帧截图(Canvas / ImageData)
- 视频格式转换(VideoConvert)
- 前后摄像头切换
- 分辨率/帧率配置
- 帧差异检测、运动检测
快速开始
安装
将 jz-h5CameraManager 放入项目的 uni_modules 目录即可。
引入
import jzCamera from '@/uni_modules/jz-h5CameraManager/js/index.js'
注册 Vue 插件(可选,用于自动挂载组件)
// main.js
import jzCamera from '@/uni_modules/jz-h5CameraManager/js/index.js'
const app = createSSRApp(App)
app.use(jzCamera.vuePlugin)
注册后即可在模板中直接使用 <camera-preview> 和 <camera-recorder> 组件,无需手动 import。
两大方案
| 方案 | 入口 | 数据格式 | 适用场景 |
|---|---|---|---|
| 帧切片方案 | getCameraManager() |
ImageData(像素数据) | 视频录制、视频分析、帧截图、WebSocket 实时传输 |
| MediaStream 方案 | getStreamCameraManager() |
MediaStream(视频流) | 实时视频通话、会议、WebRTC 推流/订阅 |
方案一:帧切片方案
适用于需要逐帧处理视频数据的场景,如视频分析、帧截图、运动检测等。
基础使用
import jzCamera from '@/uni_modules/jz-h5CameraManager/js/index.js'
const cameraManager = jzCamera.getCameraManager()
// 开始采集
cameraManager.start({
width: 640,
height: 480,
frameRate: 30,
facingMode: 'user', // 'user' 前置 | 'environment' 后置
frameSize: 1, // 每隔 N 帧切片一次
enableLiveFrame: false, // 是否启用实时帧切片
duration: 60000, // 最大采集时长(ms)
bitRate: 2500000, // 视频码率
returnType: ['blobUrl'] // 停止时返回的数据格式
})
// 监听帧切片
cameraManager.onVideoFrameRecorded((res) => {
console.log('帧序号:', res.frameCount)
console.log('帧尺寸:', res.width, 'x', res.height)
console.log('像素数据:', res.frameBuffer) // Uint8ClampedArray RGBA
})
// 监听停止
cameraManager.onStop((res) => {
console.log('录制完成:', res.blobUrl)
console.log('时长:', res.duration, '秒')
console.log('总帧数:', res.frameCount)
})
// 停止采集
cameraManager.stop()
帧切片频率控制
frameSize 参数控制切片频率:
// 每帧切片(最高频率,30fps 时每秒 30 次)
cameraManager.start({ frameSize: 1 })
// 每 5 帧切片一次(降低处理负担)
cameraManager.start({ frameSize: 5 })
// 每 30 帧切片一次(约每秒 1 次,30fps 时)
cameraManager.start({ frameSize: 30 })
实时帧切片(WebRTC 场景)
启用 enableLiveFrame 后,会额外触发 onLiveVideoFrameRecorded 事件,使用复用缓冲区降低 GC 压力:
cameraManager.start({
width: 640,
height: 480,
enableLiveFrame: true // 启用实时帧
})
cameraManager.onLiveVideoFrameRecorded((res) => {
// 实时帧数据,适用于 WebSocket 传输等场景
// 注意:frameBuffer 是复用缓冲区,应立即消费,不要存储引用
websocket.send(res.frameBuffer)
})
暂停与继续
cameraManager.pause() // 暂停采集
cameraManager.resume() // 继续采集
截图
// 在采集状态下截图
const photo = cameraManager.takePhoto({
width: 640, // 可选,默认使用采集宽度
height: 480, // 可选,默认使用采集高度
format: 'jpeg', // 'jpeg' | 'png' | 'webp'
quality: 0.8 // 0-1
})
console.log('截图 DataUrl:', photo.dataUrl)
切换摄像头
cameraManager.switchCamera()
获取状态信息
cameraManager.getState() // 'idle' | 'recording' | 'paused'
cameraManager.getDuration() // 采集时长(秒)
cameraManager.getFrameCount() // 当前帧数
cameraManager.getActualFrameRate() // 实际帧率
实时帧渲染
使用 LiveFrameRenderer 将帧数据渲染到 Canvas:
import { createLiveFrameRenderer } from '@/uni_modules/jz-h5CameraManager/js/common/LiveFrameRenderer.js'
const renderer = createLiveFrameRenderer({
canvas: document.getElementById('myCanvas'),
mirror: true, // 前置摄像头镜像
maxBufferSize: 3 // 最大缓冲帧数
})
cameraManager.onLiveVideoFrameRecorded((res) => {
renderer.render(res.frameData)
})
// 获取统计信息
console.log('渲染统计:', renderer.getStats())
// { totalFrames, droppedFrames, avgRenderTime, bufferLength, frameRate }
// 停止渲染
renderer.stop()
// 释放资源
renderer.dispose()
onStop 返回数据
cameraManager.onStop((res) => {}) 的 res 包含:
| 字段 | 类型 | 说明 |
|---|---|---|
| mimeType | String | MIME 类型 |
| fileSize | Number | 文件大小(字节) |
| duration | Number | 时长(秒) |
| width | Number | 视频宽度 |
| height | Number | 视频高度 |
| frameCount | Number | 总帧数 |
| blobUrl | String | Blob URL(returnType 包含 'blobUrl' 时) |
| arrayBuffer | ArrayBuffer | ArrayBuffer(returnType 包含 'arrayBuffer' 时) |
| base64 | String | Base64(returnType 包含 'base64' 时) |
| dataUrl | String | Data URL(returnType 包含 'dataUrl' 时) |
| file | File | File 对象(returnType 包含 'file' 时) |
| engine | String | 实现引擎:'h5' |
onVideoFrameRecorded 返回数据
| 字段 | 类型 | 说明 |
|---|---|---|
| frameData | ImageData | ImageData 对象 |
| frameBuffer | Uint8ClampedArray | RGBA 像素数据(width height 4) |
| frameCount | Number | 当前帧序号 |
| width | Number | 帧宽度 |
| height | Number | 帧高度 |
| timestamp | Number | 时间戳(ms) |
| isLastFrame | Boolean | 是否最后一帧 |
方案二:MediaStream 方案
适用于实时视频通话、WebRTC 推流等场景,直接获取 MediaStream 绑定到 <video> 元素。
基础使用
import jzCamera from '@/uni_modules/jz-h5CameraManager/js/index.js'
const streamManager = jzCamera.getStreamCameraManager()
// 启动采集,返回 MediaStream
const stream = await streamManager.start({
width: 640,
height: 480,
frameRate: 30,
facingMode: 'user'
})
// 绑定到 video 元素播放
videoElement.srcObject = stream
videoElement.play()
// 停止采集
streamManager.stop()
设备切换
// 切换前后摄像头
await streamManager.switchFacingMode()
// 切换到指定设备
const devices = streamManager.getDevices()
await streamManager.switchDevice(devices[1].deviceId)
静音控制
// 静音(暂停视频轨)
streamManager.setMuted(true)
// 取消静音
streamManager.setMuted(false)
// 切换静音状态
const muted = streamManager.toggleMute()
// 查询静音状态
streamManager.isMuted() // true/false
更新视频约束
// 动态更新分辨率等约束(会重新采集)
await streamManager.updateConstraints({
width: { ideal: 1280 },
height: { ideal: 720 }
})
状态查询
streamManager.isActive() // 是否在采集
streamManager.getState() // 'idle' | 'starting' | 'active' | 'stopping' | 'error'
streamManager.getStream() // 获取 MediaStream
streamManager.getTrack() // 获取视频轨
streamManager.getDeviceId() // 当前设备 ID
streamManager.getFacingMode() // 当前摄像头方向
streamManager.getActualDimensions() // 实际分辨率 { width, height, frameRate }
streamManager.isSupported() // 环境是否支持
事件监听
// 监听启动事件
streamManager.on('start', (res) => {
console.log('采集启动:', res.dimensions)
})
// 监听停止事件
streamManager.on('stop', () => {
console.log('采集停止')
})
// 监听错误
streamManager.onError((err) => {
console.error('采集错误:', err.errMsg)
})
// 监听静音变化
streamManager.on('mute-change', (res) => {
console.log('静音状态:', res.muted)
})
创建非单例实例
// 创建独立实例(非单例,适用于多路视频场景)
const streamManager2 = jzCamera.createStreamCameraManager({
constraints: { width: { ideal: 1280 }, height: { ideal: 720 } }
})
销毁实例
jzCamera.destroyStreamCameraManager()
Vue 组件
CameraPreview 画面预览组件
提供摄像头画面预览,支持 stream(MediaStream)和 frame(帧切片)两种模式。
基础使用
<template>
<camera-preview
:autoMount="true"
:width="640"
:height="480"
mode="stream"
@ready="onReady"
@photo="onPhoto"
@error="onError"
/>
</template>
<script>
export default {
methods: {
onReady(res) {
console.log('摄像头就绪:', res)
},
onPhoto(res) {
console.log('截图:', res.dataUrl)
},
onError(err) {
console.error('错误:', err.errMsg)
}
}
}
</script>
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| autoMount | Boolean | true | 是否自动启动摄像头 |
| width | Number | 640 | 视频采集宽度(分辨率) |
| height | Number | 480 | 视频采集高度(分辨率) |
| viewWidth | String | '' | 容器显示宽度(rpx/px/auto),不传则自适应父容器 |
| viewHeight | String | '' | 容器显示高度(rpx/px/auto),不传则按视频比例自适应 |
| fitMode | String | 'contain' | 视频填充模式:contain 完整显示 / cover 填充裁剪 |
| frameRate | Number | 30 | 帧率 |
| facingMode | String | 'user' | 摄像头方向:user/environment |
| mirror | Boolean | true | 是否镜像显示(前置摄像头) |
| showControls | Boolean | false | 是否显示控制按钮 |
| showOverlay | Boolean | true | 是否显示遮罩层 |
| mode | String | 'stream' | 使用方案:stream/frame |
| customStyle | Object | {} | 自定义样式 |
Events
| 事件 | 参数 | 说明 |
|---|---|---|
| ready | { stream, width, height } 或 { mode, width, height } |
摄像头就绪 |
| photo | { dataUrl, width, height } |
截图完成 |
| camera-switch | { facingMode } |
摄像头切换 |
| stop | - | 摄像头停止 |
| error | { errMsg } |
错误事件 |
方法(通过 ref 调用)
<camera-preview ref="preview" />
<script>
export default {
methods: {
// 手动启动/停止
this.$refs.preview.startCamera()
this.$refs.preview.stopCamera()
// 切换摄像头
this.$refs.preview.switchCamera()
// 截图
const dataUrl = this.$refs.preview.takePhoto()
// 获取流
const stream = this.$refs.preview.getStream()
// 获取状态
const status = this.$refs.preview.getStatus()
}
}
</script>
CameraRecorder 拍照/录像组件
微信风格的全屏相机界面,单击拍照、长按录像。
基础使用
<template>
<view>
<button @tap="showCamera = true">打开相机</button>
<camera-recorder
v-model:visible="showCamera"
:width="1280"
:height="720"
facingMode="environment"
@photo="onPhoto"
@record-stop="onRecordStop"
@confirm="onConfirm"
@cancel="onCancel"
/>
</view>
</template>
<script>
export default {
data() {
return { showCamera: false }
},
methods: {
onPhoto(capture) {
console.log('拍照:', capture.dataUrl)
},
onRecordStop(capture) {
console.log('录像完成:', capture.dataUrl, '时长:', capture.duration)
},
onConfirm(result) {
console.log('确认:', result.captures)
},
onCancel() {
console.log('取消')
}
}
}
</script>
Props
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| visible | Boolean | false | 是否显示(支持 v-model:visible) |
| width | Number | 1280 | 视频宽度 |
| height | Number | 720 | 视频高度 |
| frameRate | Number | 30 | 帧率 |
| facingMode | String | 'environment' | 摄像头方向 |
| mirror | Boolean | false | 是否镜像显示 |
| maxDuration | Number | 60000 | 最大录制时长(ms) |
| confirmText | String | '完成' | 完成按钮文字 |
Events
| 事件 | 参数 | 说明 |
|---|---|---|
| update:visible | Boolean | 显示状态变化 |
| ready | { stream } |
摄像头就绪 |
| photo | { type, dataUrl, width, height, timestamp } |
拍照完成 |
| record-start | - | 开始录像 |
| record-stop | { type, dataUrl, posterUrl, blob, duration, width, height } |
录像完成 |
| confirm | { captures, lastCapture } |
确认完成 |
| cancel | - | 取消 |
| error | { errMsg } |
错误 |
| camera-switch | { facingMode } |
摄像头切换 |
WebRTC 模块
CameraPublisher 视频推流器
将本地 MediaStream 推送给远端 Peer。
import { CameraPublisher } from '@/uni_modules/jz-h5CameraManager/js/webrtc/index.js'
import jzCamera from '@/uni_modules/jz-h5CameraManager/js/index.js'
// 创建 PeerConnection(需配合 WebRTC 信令库)
const peer = new RTCPeerConnection(config)
// 创建推流器
const publisher = new CameraPublisher({ peer })
// 获取本地视频流
const streamManager = jzCamera.getStreamCameraManager()
const localStream = await streamManager.start()
// 设置并推流
publisher.setStream(localStream)
publisher.publishTo('remote-peer-id')
// 批量推流
publisher.publishToMany(['peer1', 'peer2', 'peer3'])
// 撤销推流
publisher.unpublish('remote-peer-id')
publisher.unpublishAll()
// 监听事件
publisher.on('publish', (res) => {
console.log('推流成功:', res.peerId)
})
// 查询状态
publisher.getTargets() // 推流目标列表
publisher.getTargetCount() // 推流目标数量
publisher.isPublishing(peerId) // 是否正在推流
// 释放资源
publisher.dispose()
CameraSubscriber 视频订阅器
接收远端 Peer 的视频流。
import { CameraSubscriber } from '@/uni_modules/jz-h5CameraManager/js/webrtc/index.js'
const subscriber = new CameraSubscriber({
peer,
onStream: ({ peerId, stream }) => {
// 自动播放远端视频
videoElement.srcObject = stream
videoElement.play()
}
})
// 手动注入视频流
subscriber.attach('remote-peer-id', remoteStream)
// 静音远端
subscriber.setMuted('remote-peer-id', true)
// 移除订阅
subscriber.detach('remote-peer-id')
// 获取视频流
subscriber.getStream('remote-peer-id')
subscriber.getAllStreams()
subscriber.getStreamCount()
// 释放资源
subscriber.dispose()
CameraVolumeMeter 视频状态监听器
监听视频流状态变化(活跃状态、分辨率、帧率)。
import { CameraVolumeMeter } from '@/uni_modules/jz-h5CameraManager/js/webrtc/index.js'
const meter = new CameraVolumeMeter({ interval: 1000 })
// 监听视频状态
meter.attach('local', localStream, (state) => {
console.log('视频状态:', state)
// state: { enabled, readyState, width, height, frameRate }
})
// 监听状态变化事件
meter.on('state-change', ({ key, state }) => {
console.log(`${key} 状态变化:`, state)
})
// 移除监听
meter.detach('local')
// 释放资源
meter.dispose()
工具类
VideoUtils 视频工具
import {
imageDataToBase64,
imageDataToBlob,
imageDataToArrayBuffer,
arrayBufferToImageData,
scaleImageData,
toGrayscale,
rgbaToRgb,
rgbToRgba,
calculateFrameDiff,
detectMotion,
getVideoDimensions,
calculateScaledSize,
calculateFrameRate,
getCameraPosition,
getSupportedMimeType,
imageDataToYUV420
} from '@/uni_modules/jz-h5CameraManager/js/common/VideoUtils.js'
帧格式转换
// ImageData 转 Base64
const base64 = imageDataToBase64(imageData, 'jpeg', 0.8)
// ImageData 转 Blob
const blob = await imageDataToBlob(imageData, 'jpeg', 0.8)
// ImageData 转 ArrayBuffer
const buffer = imageDataToArrayBuffer(imageData)
// ArrayBuffer 转 ImageData
const imageData2 = arrayBufferToImageData(buffer, 640, 480)
// 缩放 ImageData
const smallFrame = scaleImageData(imageData, 0.5) // 缩小一半
// ImageData 转 YUV420(用于 WebRTC)
const yuv = imageDataToYUV420(imageData)
// { yPlane, uPlane, vPlane, width, height }
像素数据处理
// 转灰度图
const gray = toGrayscale(imageData) // Uint8Array
// RGBA 转 RGB(去除 Alpha 通道)
const rgb = rgbaToRgb(imageData.data) // Uint8Array
// RGB 转 RGBA(添加 Alpha 通道)
const rgba = rgbToRgba(rgbData) // Uint8ClampedArray
视频分析
// 计算帧差异(0-1)
const diff = calculateFrameDiff(currentFrame, previousFrame)
// 运动检测
const hasMotion = detectMotion(currentFrame, previousFrame, 0.1) // 阈值 0.1
其他工具
// 获取视频尺寸
const dims = getVideoDimensions(videoElement)
// { width, height, aspectRatio }
// 计算缩放尺寸(保持宽高比)
const size = calculateScaledSize(1920, 1080, 640, 480)
// { width, height }
// 计算帧率
const fps = calculateFrameRate(frameCount, duration)
// 获取支持的 MIME 类型
const mimeType = getSupportedMimeType()
VideoConvert 视频格式转换
import VideoConvert from '@/uni_modules/jz-h5CameraManager/js/common/VideoConvert.js'
// 任意格式互转
const arrayBuffer = await VideoConvert.toArrayBuffer(source)
const base64 = await VideoConvert.toBase64(source)
const dataUrl = await VideoConvert.toDataUrl(source, 'video/webm')
const blob = await VideoConvert.toBlob(source, 'video/webm')
const blobUrl = await VideoConvert.toBlobUrl(source, 'video/webm')
const file = await VideoConvert.toFile(source, 'video.webm', 'video/webm')
// source 可以是 Blob / string(Base64/DataUrl) / ArrayBuffer
CameraDataSource 视频数据源
import { createCameraDataSource, revokeBlobUrl } from '@/uni_modules/jz-h5CameraManager/js/common/CameraDataSource.js'
// 创建数据源(支持多种返回格式)
const dataSource = await createCameraDataSource(blob, mimeType, {
returnType: ['blobUrl', 'arrayBuffer', 'base64', 'dataUrl', 'file']
})
console.log(dataSource.blobUrl)
console.log(dataSource.arrayBuffer.byteLength)
console.log(dataSource.base64.length)
console.log(dataSource.file.name)
// 撤销 BlobUrl
revokeBlobUrl(dataSource.blobUrl)
视频约束预设
import {
DEFAULT_CAMERA_CONSTRAINTS, // 默认:640x480 30fps
HIGH_QUALITY_CONSTRAINTS, // 高质量:1920x1080 60fps
LOW_LATENCY_CONSTRAINTS, // 低延迟:320x240 15fps
MEETING_CONSTRAINTS, // 会议:640x480 24fps
BACK_CAMERA_CONSTRAINTS, // 后置摄像头:640x480 30fps
mergeConstraints, // 合并约束
getConstraintsByScenario // 按场景选择约束
} from '@/uni_modules/jz-h5CameraManager/js/common/CameraConstraints.js'
// 使用预设约束
const stream = await streamManager.start({
constraints: HIGH_QUALITY_CONSTRAINTS
})
// 按场景选择
const constraints = getConstraintsByScenario('meeting')
// 合并自定义约束
const custom = mergeConstraints(DEFAULT_CAMERA_CONSTRAINTS, {
width: { ideal: 1280 },
frameRate: { max: 24 }
})
API 参考
插件入口(js/index.js)
| 方法 | 说明 |
|---|---|
getCameraManager() |
获取帧切片方案管理器(单例) |
getStreamCameraManager() |
获取 MediaStream 方案管理器(单例) |
createStreamCameraManager(options) |
创建 Stream 管理器(非单例) |
destroyStreamCameraManager() |
销毁 Stream 单例 |
getPlatformInfo() |
获取平台信息 |
supportFrameRecorded() |
是否支持帧切片 |
isStreamSupported() |
是否支持 MediaStream |
VideoConvert |
视频格式转换工具 |
帧切片方案(H5CameraManager)
| 方法 | 说明 |
|---|---|
start(options) |
开始视频采集 |
pause() |
暂停采集 |
resume() |
继续采集 |
stop() |
停止采集 |
switchCamera() |
切换摄像头 |
takePhoto(options) |
截取当前帧 |
getState() |
获取当前状态 |
getDuration() |
获取采集时长(秒) |
getFrameCount() |
获取当前帧数 |
getActualFrameRate() |
获取实际帧率 |
getStream() |
获取 MediaStream |
getDevices() |
获取设备列表 |
revokeAllBlobUrls() |
撤销所有 BlobUrl |
| 事件 | 说明 |
|---|---|
onStart(callback) |
采集开始 |
onPause(callback) |
采集暂停 |
onResume(callback) |
采集继续 |
onStop(callback) |
采集停止 |
onError(callback) |
采集错误 |
onVideoFrameRecorded(callback) |
帧切片回调 |
onLiveVideoFrameRecorded(callback) |
实时帧回调 |
start(options) 参数
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| duration | Number | 60000 | 采集时长(ms) |
| width | Number | 640 | 视频宽度 |
| height | Number | 480 | 视频高度 |
| frameRate | Number | 30 | 帧率 |
| facingMode | String | 'user' | 摄像头方向 |
| frameSize | Number | 1 | 帧切片频率(每隔 N 帧) |
| enableLiveFrame | Boolean | false | 是否启用实时帧切片 |
| bitRate | Number | 2500000 | 视频码率 |
| returnType | Array | ['blobUrl'] | 返回数据类型 |
| deviceId | String | null | 指定设备 ID |
| audio | Boolean | true | 是否采集音频 |
MediaStream 方案(StreamCameraManager)
| 方法 | 说明 |
|---|---|
start(options) |
启动采集,返回 Promise\<MediaStream> |
stop() |
停止采集并释放流 |
switchDevice(deviceId) |
切换到指定设备 |
switchFacingMode() |
切换前后摄像头 |
setMuted(muted) |
设置静音 |
toggleMute() |
切换静音状态 |
isMuted() |
是否静音 |
isActive() |
是否在采集 |
getStream() |
获取 MediaStream |
getTrack() |
获取视频轨 |
getDeviceId() |
获取当前设备 ID |
getFacingMode() |
获取摄像头方向 |
getActualDimensions() |
获取实际分辨率 |
getDevices() |
获取设备列表 |
getNextDevice() |
获取下一个设备 |
updateConstraints(constraints) |
更新视频约束 |
isSupported() |
环境是否支持 |
dispose() |
释放资源 |
兼容性
| 平台 | 基础视频 | 帧切片 | WebRTC |
|---|---|---|---|
| H5 | 支持 | 支持 | 支持 |
| App | 不支持 | 不支持 | 不支持 |
| 小程序 | 不支持 | 不支持 | 不支持 |
| 浏览器 | 支持情况 |
|---|---|
| Chrome | 支持 |
| Safari | 支持 |
| Firefox | 支持 |
| Edge | 支持 |
需要 HTTPS 环境(localhost 除外)
常见问题
1. 摄像头无法启动?
- 确认在 HTTPS 环境下运行(localhost 除外)
- 检查浏览器是否授权了摄像头权限
- 确认设备有可用的摄像头
2. 帧切片性能问题?
- 使用
frameSize降低切片频率 - 选择合适的分辨率(视频通话 640x480,分析 320x240)
onLiveVideoFrameRecorded使用复用缓冲区,应立即消费数据
3. 如何选择方案?
- 需要逐帧处理像素数据(视频分析、运动检测)→ 帧切片方案
- 需要直接获取视频流(实时通话、WebRTC 推流)→ MediaStream 方案
- 需要快速搭建相机界面 → CameraRecorder 组件
4. BlobUrl 内存泄漏?
停止采集后,及时调用 revokeAllBlobUrls() 或 revokeBlobUrl() 释放 BlobUrl:
cameraManager.onStop(() => {
// 处理完视频后释放
cameraManager.revokeAllBlobUrls()
})

收藏人数:
下载插件并导入HBuilderX
下载插件ZIP
赞赏(0)
下载 2408
赞赏 0
下载 12289366
赞赏 1922
赞赏
京公网安备:11010802035340号