简体中文
Camera 组件
操控本地摄像头/麦克风,提供拍摄和录制功能的控件。
何时使用
在一些特定场景,例如在监考系统中,你可能需要实时监控屏幕前的考生,Camera 组件可能会帮到你。
基础用法
Camera
组件向外暴露openCamera
和closeCamera
方法,分别用来打开摄像头和关闭摄像头。你需要通过组件的模板引用来调用它们。
const openCamera: () => Promise<[status: boolean, message: string]>
const closeCamera: () => [status: boolean, message: string]
status 代表本次操作的状态,true 表示成功,false 表示失败,message 为本次操作的信息文本。
<>
<template>
<div>
<div class="container">
<kl-camera ref="cameraRef"></kl-camera>
</div>
<div class="btns">
<kl-button @click="handleOpenCamera">开启摄像头</kl-button>
<kl-button @click="handleCloseCamera">关闭摄像头</kl-button>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { KlCamera, KlMessage } from 'kunlun-design'
const cameraRef = ref<InstanceType<typeof KlCamera> | null>(null)
const handleOpenCamera = async () => {
const [status, message] = await cameraRef.value.openCamera()
status ? KlMessage.success(message) : KlMessage.error(message)
}
const handleCloseCamera = () => {
const [status, message] = cameraRef.value.closeCamera()
status ? KlMessage.success(message) : KlMessage.error(message)
}
</script>
<style lang="scss" scoped>
.container {
display: inline-block;
padding: 12px;
background-color: #67c23a;
border-radius: 10px;
}
.btns {
margin-top: 15px;
}
</style>
拍照功能
Camera
组件向外暴露takePhoto
方法,通过调用此方法,你可以实现拍照功能。
const openCamera: () => [status: boolean, message: string]
status 代表本次操作的状态,true 表示成功,false 表示失败,message 为本次操作的信息文本。若 status 为 true,则 message 为照片的 base64 数据。
<>
<template>
<div>
<div class="container">
<kl-camera ref="cameraRef"></kl-camera>
</div>
<div class="container">
<img v-if="imgSrc !== ''" :src="imgSrc" />
<div v-else class="filler">
<KlMediaImageLine />
</div>
</div>
<div class="btns">
<kl-button @click="handleOpenCamera">打开摄像头</kl-button>
<kl-button @click="handleCloseCamera">关闭摄像头</kl-button>
<kl-button @click="handleTakePhoto">拍一张照片</kl-button>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { KlCamera, KlMessage } from 'kunlun-design'
const cameraRef = ref<InstanceType<typeof KlCamera> | null>(null)
const imgSrc = ref('')
const handleOpenCamera = async () => {
const [status, message] = await cameraRef.value.openCamera()
status ? KlMessage.success(message) : KlMessage.error(message)
}
const handleCloseCamera = () => {
const [status, message] = cameraRef.value.closeCamera()
status ? KlMessage.success(message) : KlMessage.error(message)
}
const handleTakePhoto = () => {
const [status, message] = cameraRef.value.takePhoto()
status ? (imgSrc.value = message) : KlMessage.error(message)
}
</script>
<style lang="scss" scoped>
.container {
display: inline-block;
padding: 12px;
background-color: #67c23a;
border-radius: 10px;
margin-bottom: 10px;
.filler {
display: flex;
align-items: center;
justify-content: center;
font-size: 100px;
color: #999;
width: 320px;
height: 180px;
background-color: #f0f9eb;
}
}
.btns {
margin-top: 15px;
}
</style>
录制功能
Camera
组件向外暴露了startRecord
、pauseRecord
、resumeRecord
和stopRecord
方法,功能分别为:开始录制、暂停录制、继续录制和结束录制。你可以通过Camera
组件暴露的recorderState
属性拿到当前的录制状态,recorderState
属性有三个取值,inactive
代表未录制,recording
代表正在录制,paused
代表暂停状态。
const startRecord: () => [status: boolean, message: string]
const pauseRecord: () => [status: boolean, message: string]
const resumeRecord: () => [status: boolean, message: string]
const stopRecord: () => [status: boolean, message: string | Blob]
REC
<>
<template>
<div>
<div class="container">
<kl-camera ref="cameraRef" audio></kl-camera>
<div :class="['rec', cameraRef?.recorderState]">REC</div>
</div>
<div class="container">
<video ref="videoRef" style="width: 320px; height: 180px"></video>
</div>
<div class="btns">
<kl-button @click="handleOpenCamera">开启摄像头</kl-button>
<kl-button @click="handleCloseCamera">关闭摄像头</kl-button>
</div>
<div class="btns">
<kl-button @click="handleRecordStart">开始录制</kl-button>
<kl-button @click="handleRecordPause">暂停录制</kl-button>
<kl-button @click="handleRecordResume">继续录制</kl-button>
<kl-button @click="handleRecordStop">结束录制</kl-button>
<kl-button @click="showRecord">查看录像</kl-button>
</div>
</div>
</template>
<script lang="ts" setup>
import { ref } from 'vue'
import { KlCamera, KlMessage } from 'kunlun-design'
const cameraRef = ref<InstanceType<typeof KlCamera> | null>(null)
const videoRef = ref<HTMLVideoElement | null>(null)
let blob: Blob
// 开启摄像头
const handleOpenCamera = async () => {
const [status, message] = await cameraRef.value.openCamera()
status ? KlMessage.success(message) : KlMessage.error(message)
}
// 关闭摄像头
const handleCloseCamera = () => {
const [status, message] = cameraRef.value.closeCamera()
status ? KlMessage.success(message) : KlMessage.error(message)
}
// 开始录制
const handleRecordStart = () => {
const [status, message] = cameraRef.value.startRecord()
status ? KlMessage.success(message) : KlMessage.error(message)
}
// 暂停录制
const handleRecordPause = () => {
const [status, message] = cameraRef.value.pauseRecord()
status ? KlMessage.success(message) : KlMessage.error(message)
}
// 继续录制
const handleRecordResume = () => {
const [status, message] = cameraRef.value.resumeRecord()
status ? KlMessage.success(message) : KlMessage.error(message)
}
// 结束录制
const handleRecordStop = () => {
const [status, message] = cameraRef.value.stopRecord()
status ? (blob = message) : KlMessage.error(message)
}
// 查看录像
const showRecord = () => {
if (!blob) return
videoRef.value!.src = URL.createObjectURL(blob)
videoRef.value!.play()
}
</script>
<style lang="scss" scoped>
.container {
display: inline-block;
padding: 12px;
background-color: #67c23a;
border-radius: 10px;
margin-bottom: 10px;
position: relative;
.filler {
display: flex;
align-items: center;
justify-content: center;
font-size: 100px;
color: #999;
width: 320px;
height: 180px;
background-color: #f0f9eb;
}
.rec {
position: absolute;
right: 30px;
top: 20px;
color: red;
}
.inactive {
display: none;
}
.paused {
display: block;
}
@keyframes flicker {
0% {
opacity: 1;
}
100% {
opacity: 0.4;
}
}
.recording {
animation: flicker 0.8s linear infinite alternate;
}
}
.btns {
margin-top: 15px;
}
</style>
API
属性
名称 | 描述 | 类型 | 默认值 | 必填 |
---|---|---|---|---|
width | 组件宽度 | number | 320 | 否 |
height | 组件高度 | number | 180 | 否 |
background-color | 组件背景色 | string | #000 | 否 |
audio | 为媒体流添加音频轨道 | boolean | false | 否 |
事件
名称 | 描述 | 回调函数 |
---|---|---|
start-record | 开始录制时触发 | (): void |
pause-record | 暂停录制时触发 | (): void |
resume-record | 继续录制时触发 | (): void |
stop-record | 结束录制时触发 | (): void |
error-record | 录制发生错误时触发 | (): void |
progress-record | 录制时触发(约 100ms 触发一次) | (event: BlobEvent): void |
功能提供
名称 | 描述 | 类型 |
---|---|---|
openCamera | 开启摄像头 | () => [status: boolean, message: string] |
closeCamera | 关闭摄像头 | () => [status: boolean, message: string] |
takePhoto | 拍照 | () => [status: boolean, message: string] |
startRecord | 开始录制 | () => [status: boolean, message: string] |
pauseRecord | 暂停录制 | () => [status: boolean, message: string] |
resumeRecord | 继续录制 | () => [status: boolean, message: string] |
stopRecord | 停止录制 | () => [status: boolean, message: string/Blob] |
recorderState | 当前录制状态 | inactive/recording/paused |