SDK Examples
本页演示了 Sib Scanne SDK 提供的一些运行时 API 的使用方法。
安装
使用你喜欢的包管理工具
bash
# npm
npm install sib-scanne-sdk
#yarn
yarn add sib-scanne-sdk
#pnpm
pnpm add sib-scanne-sdk
#bun
bun add sib-scanne-sdk
配置选项
handleError 参数 (callback)
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
- | callback: (error: Error) => void | - | sdk 中所有的错误都会通过 handleError 函数抛出 |
createScanner 参数(createOptions)
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
- | createOptions?: ReaderOptions | {} | 扫描器创建时的配置参数 |
start 方法参数(startOption)
属性 | 类型 | 默认值 | 说明 |
---|---|---|---|
video | HTMLVideoElement | - | 必须传入的视频元素,用于展示摄像头画面 |
deviceId | string | - | 可选,指定要使用的摄像头设备 ID(可通过 getDevices 方法获取) |
constraints | MediaTrackConstraints | - | 可选,摄像头约束配置(如分辨率、帧率等) |
readerOptions | ReaderOptions | - | 可选,摄像头约束配置(如分辨率、帧率等) |
扫描器实例方法
方法名 | 类型 | 说明 |
---|---|---|
start | (startOption: StartOption) => Promise<void> | 启动扫描器,传入视频元素及相关配置 |
decodeData | callback: (result: ReadResult[], imageSource?: ImageData | null) => void | 获取解码结果的方法 |
getDevices | () => Promise<MediaDeviceInfo[]> | 获取所有可用摄像头设备列表 |
stop | () => void | 停止解码和 Canvas 绘画 |
destroy | () => void | 销毁扫描器实例,清除元素、流及所有属性 |
在项目中使用
你可以在 Vue
或者React
或者原生html
中使用
Vue
Vue
<template>
<video
muted
autoplay
playsinline
webkit-playsinline
ref="videoElement"
poster="data:image/gif,AAAA"
class="absolute inset-0 w-full h-full object-cover bg-black z-50"
></video>
</template>
<script setup lang="ts">
import { onMounted, useTemplateRef, computed } from 'vue'
import { handleError, createScanner } from 'sib-scanne-sdk'
import type { Position, ReadResult } from 'sib-scanne-sdk'
const videoRef = useTemplateRef<HTMLVideoElement>('videoElement')
const scanner = createScanner() // 创建扫码实例
onMounted(async () => {
try {
const { start, stop, destroy, decodeData, getDevices } = scanner
await start({ video: videoRef.value })
// 获取摄像头列表
const devices: Promise<MediaDeviceInfo[]> = await getDevices()
console.log(
'==>devices',
devices.map(device => ({ label: device.label, deviceId: device.deviceId })),
)
// 解码
decodeData((results: ReadResult[] , imageBitmap: ImageData) => {
if (results && Array.isArray(results) && results.length > 0) {
console.log(results[0].text) // 解码结果
stop() // 停止解码 | 停止媒体流绘制
destroy() // 销毁实例
// ....
}
})
} catch (error) {
console.error(error)
// ...
}
})
// 错误处理
handleError(error => {
console.error(error)
// ....
})
</script>
React
tsx
import { useEffect, useRef } from "react";
import { createScanner, handleError, ReadResult } from "sib-scanne-sdk";
export default function ScannerVideo() {
const videoRef = useRef<HTMLVideoElement>(null);
useEffect(() => {
const scanner = createScanner();
(async () => {
try {
const { start, stop, destroy, decodeData, getDevices } = scanner;
await start({ video: videoRef.current! });
console.log(
"==>devices",
(await getDevices()).map(d => ({ label: d.label, deviceId: d.deviceId }))
);
decodeData((results: ReadResult[]) => {
if (results?.length) {
console.log("扫码结果:", results[0].text);
stop();
destroy();
}
});
} catch (err) {
console.error("scanner error:", err);
}
})();
handleError(err => console.error("scanner handleError:", err));
return () => {
try {
scanner.stop();
scanner.destroy();
} catch {}
};
}, []);
return (
<video
ref={videoRef}
muted
autoPlay
playsInline
poster="data:image/gif,AAAA"
className="absolute inset-0 w-full h-full object-cover bg-black z-50"
/>
);
}
HTML
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<video src="./test.mp4" id="video" controls autoplay></video>
<script src="sib-scanne-sdk.umd.cjs"></script>
<script>
const { createScanner, handleError } = window.SibScanne
handleError((error) => console.error(error)) // 错误监听
const scanner = createScanner(/* options */) // 初始化
window.onload = function () {
; (async () => {
const video = document.getElementById('video')
await scanner.start({ video })
// 解码
scanner.decodeData((results: ReadResult[] , imageBitmap: ImageData) => {
if (results && Array.isArray(results) && results.length > 0) {
console.log(results[0].text) // 解码结果
scanner.stop() // 停止解码 | 停止媒体流绘制
scanner.destroy() // 销毁实例
// ....
}
})
})()
}
</script>
</body>
</html>
常见问题
相机无法启动,扫描不到 Code?
若遇到相机无法启动、无法扫描 Code 的问题,可按以下步骤排查:
1、基础检查
- 浏览器权限设置:查看浏览器地址栏左侧(如锁形图标处),确认相机权限为“允许”;部分系统(如 macOS、Windows)需在系统设置的“隐私与安全性 - 相机”中,允许对应浏览器访问相机。
- HTTPS 连接:现代浏览器仅允许在 HTTPS 协议(公网)或 localhost/127.0.0.1(本地开发)下访问相机,若为本地文件(
file://
协议),需启动本地服务(如 Vite 开发服务器)。 - 浏览器兼容性:推荐使用 Chrome 100+、Edge 100+ 等现代浏览器,旧版或小众浏览器可能对相机 API 支持不足。
2、调试代码
可通过以下代码获取摄像头设备列表,排查设备是否被正确识别:
javascript
// 获取并打印所有媒体设备(含摄像头)
navigator.mediaDevices.enumerateDevices().then(devices => {
// 筛选出摄像头设备
const cameras = devices.filter(device => device.kind === 'videoinput');
console.log('可用摄像头列表:', cameras);
// 若无摄像头设备
if (cameras.length === 0) {
console.error('未检测到任何摄像头设备');
alert('当前设备无可用摄像头,请检查硬件连接');
return;
}
// 打印摄像头详细信息(设备ID、名称等)
cameras.forEach(camera => {
console.log(`设备ID:${camera.deviceId},设备名称:${camera.label || '未知摄像头'}`);
});
}).catch(error => {
console.error('获取设备列表失败:', error);
alert('无法读取摄像头设备信息,请检查浏览器权限');
});
3、补充说明
- 多摄像头场景:若设备有多个摄像头(如手机前后置、PC 外接摄像头),可通过上述代码的
device.label
区分设备,再结合需求指定摄像头(如优先选后置摄像头)。 - iframe 嵌套:若相机功能在 iframe 中,需为 iframe 标签添加
allow="camera"
属性,否则父页面权限无法传递到 iframe。