Skip to content
On this page

Camera 组件

操控本地摄像头/麦克风,提供拍摄和录制功能的控件。

何时使用

在一些特定场景,例如在监考系统中,你可能需要实时监控屏幕前的考生,Camera 组件可能会帮到你。

基础用法

Camera 组件向外暴露openCameracloseCamera方法,分别用来打开摄像头和关闭摄像头。你需要通过组件的模板引用来调用它们。

  • 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组件向外暴露了startRecordpauseRecordresumeRecordstopRecord方法,功能分别为:开始录制、暂停录制、继续录制和结束录制。你可以通过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组件宽度number320
height组件高度number180
background-color组件背景色string#000
audio为媒体流添加音频轨道booleanfalse

事件

名称描述回调函数
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

Released under the MIT License.