Message Video

The door lock's album list, alarm list, and log list have the capability to preview videos. For security reasons, the data provided by Tuya is encrypted, so the ipc-player component must be used to play videos normally.

Video Cover Image

The video cover image is the corresponding image returned in the record. To display this image, please refer to Message Image Processing Solution for processing.

Get Video Address

The video address returned in the record cannot be used directly for playback. You need to get the actual address first

import { getMediaUrl } from '@ray-js/lock-sdk';

const mediaUrl = await getMediaUrl({
    mediaPath: data.mediaPath,
    mediaBucket: data.mediaBucket,
})

Play Video

Use the ipc-player cross-layer component to play

import React, { useRef } from 'react';
import { IpcPlayer } from '@ray-js/ray';
import { getMediaRotate } from '@ray-js/lock-sdk';


const { videoAngle } = getMediaRotate();
const isInit = useRef(false);
const ctx = useRef(null);

if (!ctx.current) {
    ctx.current = createIpcPlayerContext(devId);
}

// Initialize
const initPlayer = useCallback(() => {
    if (isInit.current) {
        return;
    }
    isInit.current = true;

    // Create message device instance for playback
    ctx.current?.createMessageDevice({
        devId,
        success: () => {
            // Enable sound
            if (ctx.current) {
                ctx.current.setMessageVideoMute({
                mute: 0,
                });
                ctx.current.setRotateZ(rotateInfo.videoAngle);
                // Listen after creating instance
                ipc.onPlayMessageVideoFinish(handlePlayMessageVideoFinish);
            }
        },
        fail: err => {
            ToastInstance.fail(Strings.getLang('initPlayerFailed'));
            console.warn('err createMessageDevice', err);
        },
    });

    // Create media device instance for download
    ipc.createMediaDevice({
        deviceId: devId,
    });
}, []);

// Play
const handlePlay = useCallback(async () => {
    ctx.current.startMessageVideoPlay({
        encryptKey: data.mediaKey,
        path: url,
        startTime: 0,
        success: res => {

        },
        fail: err => {
            console.warn('start fail:', err);
            ToastInstance.fail(Strings.getLang('playMediaFailed'));
        },
    });
}, [])
// Download
const handleDownload = useCallback(() => {
if (ctx.current) {
    ipc.startDownloadMessageVideo({
    deviceId: devId,
    path: mediaUrl,
    encryptKey: data.mediaKey,
    savePath: 2,
    rotateMode: rotateInfo.videoAngle || 0,
    });
}
}, [mediaUrl]);


<IpcPlayer
    type={2}
    deviceId={devId}
    autoplay={false}
    objectFit="contain"
    orientation="vertical"
    rotateZ={videoAngle}
    onCreateViewSuccess={initPlayer}
    className={styles.player}
/>
<View className={styles.tools}>
    <View className={styles.playButton} onClick={handlePlay}>
    <Icon name={Play} size="48rpx" />
    </View>
    <View className={styles.downloadButton} onClick={handleDownload}>
    <Icon name={Download} size="48rpx" />
    </View>
</View>

Notes

  • Since ipc-player is a cross-layer component, message videos need to be implemented on a separate page.