---
title: 消息视频
summary: 门锁相册、告警、日志中加密消息视频的获取、播放与下载方案，使用 ipc-player 异层组件及 getMediaUrl API。
---

## 消息视频

门锁的相册列表、告警列表、日志列表中会有需要预览视频的功能，由于安全考虑，涂鸦提供的数据是经过加密处理的，需要使用 `ipc-player` 组件才能正常播放视频。

### 视频封面图

视频的封面图，即为记录中对应的返回的图片，展示此图片请根据 [消息图片处理方案](/cn/miniapp/solution-ai/ability/doorlock-solution/media/photo) 进入处理。

### 获取视频地址

记录中返回的视频地址是不能直接用于播放的，需要先获取实际的地址

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

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

### 播放视频

使用 `ipc-player` 异层组件播放

```jsx
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);
}

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

    // 创建播放器的消息实例，用于播放
    ctx.current?.createMessageDevice({
        devId,
        success: () => {
            // 开启声音
            if (ctx.current) {
                ctx.current.setMessageVideoMute({
                mute: 0,
                });
                ctx.current.setRotateZ(rotateInfo.videoAngle);
                // 在创建实例后进行监听
                ipc.onPlayMessageVideoFinish(handlePlayMessageVideoFinish);
            }
        },
        fail: err => {
            ToastInstance.fail(Strings.getLang('initPlayerFailed'));
            console.warn('err createMessageDevice', err);
        },
    });

    // 创建媒体实例，用于下载
    ipc.createMediaDevice({
        deviceId: devId,
    });
}, []);

// 播放
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'));
        },
    });
}, [])
// 下载
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>
```

### 注意事项

- 由于 ipc-player 是异层组件，所以消息视频需要在单独的一个页面实现。
