Skip to content
On this page

Camera

Controls to control the local camera/microphone and provide shooting and recording functions.

When to use

In some specific situations, such as in a invigilator system, where you may need to monitor the examinee on the screen in real time, the Camera component may help you.

Basic usage

The Camera component exposes openCamera and closeCamera methods to open and close the camera, respectively. You need to invoke them through the component's template reference.

  • const openCamera: () => Promise<[status: boolean, message: string]>
  • const closeCamera: () => [status: boolean, message: string]

status indicates the status of the operation, true indicates success, false indicates failure, and message indicates the message text of the operation.

<>
<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>

Photo function

The Camera component exposes the takePhoto method. By calling this method, you can take a photo.

  • const openCamera: () => [status: boolean, message: string]

status indicates the status of the operation, true indicates success, false indicates failure, and message indicates the message text of the operation. If status is true, message is the base64 data of the photo.

<>
<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>

Recording function

The Camera component exposes the startRecord, pauseRecord, resumeRecord and stopRecord methods externally, with functions of start recording, pause recording, continue recording and end recording respectively. You can get the current recording status through the Camera component's exposed recorderState property, which has three values: inactive means not recording, recording means recording, and paused means 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

Attribute

namedescriptiontypedefault valuerequired
widthComponent widthnumber320
heightComponent heightnumber180
background-colorComponent background colorstring#000
audioAdd audio tracks to the media streambooleanfalse

Event

namedescriptioncallback function
start-recordTriggered when recording starts(): void
pause-recordTriggered when recording is paused(): void
resume-recordTriggered when recording continues(): void
stop-recordTriggered when recording ends(): void
error-recordTriggered when recording errors occur(): void
progress-recordTrigger during recording (about 100ms trigger once)(event: BlobEvent): void

Function provision

namedescriptiontype
openCameraStart the camera() => [status: boolean, message: string]
closeCameraTurn off the camera() => [status: boolean, message: string]
takePhotoTake pictures() => [status: boolean, message: string]
startRecordStart recording() => [status: boolean, message: string]
pauseRecordPause recording() => [status: boolean, message: string]
resumeRecordContinue recording() => [status: boolean, message: string]
stopRecordStop recording() => [status: boolean, message: string/Blob]
recorderStateCurrent recording statusinactive/recording/paused

Released under the MIT License.