admin 发表于 2024-11-29 17:53:14

Vue3+TS接入萤石云实现视频切换播放

主要就是两个文件,一个index.vue,一个index.ts,效果图如下:



index.vue代码如下:
<template>
      <div class="layout-padding bg data">
                <div class="data-content">
                        <div class="data_left">
                              <div class="left_tree">
                                        <ul class="parent_ul">
                                                <li class="parent zhedie">
                                                      <ul class="child">
                                                                <li v-for="(video, index) in videoData" :key="index" :class="{ selected: deviceSelect === index }" @click="playClick(video, index)">
                                                                        {{ video.channelName }}
                                                                </li>
                                                      </ul>
                                                </li>
                                        </ul>
                              </div>
                        </div>
                        <div class="data_right">
                              <div class="right_video videobox" id="play">
                                        <div class="video-monitor-device-container" style="height: 100%">
                                                <div class="multiple-player-window" style="height: 100%">
                                                      <div class="player-window-item" style="height: 100%">
                                                                <div id="video-box1"></div>
                                                      </div>
                                                </div>
                                        </div>
                              </div>
                        </div>
                </div>
      </div>
</template>

<script lang="ts" setup>
import { getDeviceList, getPlayVideo } from './video';
import EZUIKit from 'ezuikit-js';

interface IPlayer {
      play: Function;
      stop: Function;
      getOSDTime: Function;
      capturePicture: Function;
      openSound: Function;
      closeSound: Function;
      startSave: Function;
      stopSave: Function;
      startTalk: Function;
      stopTalk: Function;
      fullScreen: Function;
      destroy: Function;
}

let player: IPlayer;

const videoData = ref();
const deviceSelect = ref(0);
const chanel = ref(0);

onMounted(() => {
      getDeviceData();
});

const getDeviceData = async () => {
      videoData.value = await getDeviceList();
      if (videoData.value.length > 0) {
                chanel.value = videoData.value;
                await initPlay(videoData.value);
      }
};

const playClick = (device: any, index: number) => {
      deviceSelect.value = index;
      initPlay(device);
};

const initPlay = async (chanel: any) => {
      const res = await getPlayVideo(chanel);
      if (res.url) {
                if (player) {
                        destroy();
                }
                const element = document.getElementById('video-box1');
                const parentElement = element.parentNode;
                const parentWidth = parentElement.offsetWidth;
                const parentHeight = parentElement.offsetHeight;

                player = new EZUIKit.EZUIKitPlayer({
                        id: 'video-box1',
                        accessToken: res.token,
                        url: res.url,
                        // simple: 极简版; pcLive: pc直播; pcRec: pc回放; mobileLive: 移动端直播; mobileRec: 移动端回放;security: 安防版; voice: 语音版;
                        template: 'pcLive',
                        plugin: ['talk'],
                        width: parentWidth,
                        height: parentHeight,
                });
                window.player = player;
      }
};

const destroy = () => {
      const destroyPromise = player.stop();
      destroyPromise.then((data: any) => {
                console.log('promise 获取 数据', data);
      });
      const videoBox = document.getElementById('video-box1');
      videoBox.innerHTML = '';
      player = null!;
};
</script>

<style>
@import url(./video.scss);
@import url(../eemp.scss);
@import url(../map.scss);
</style>
index.ts代码如下:

import axios from 'axios';
import { Session } from '/@/utils/storage';

const ysUrl: string = "https://open.ys7.com/api/lapp";
let token: string = "";
let appKey: string = "你的key";
let appSecret: string = "你的secret";
const orgId = Session.getOrgId();

export const isOrg = (orgName: string) => {
    const tenantName = Session.getTenantName();
    return tenantName && tenantName.includes(orgName);
};

interface Camera {
    channelName: string;
    channelNo: number;
    deviceSerial: string;
}

export const getDeviceList = async () => {

    let videoToken = localStorage.getItem(orgId + '_videoToken');

    const accessToken = new FormData();
    accessToken.append('accessToken', videoToken || '');
    if (videoToken === null || videoToken === undefined) {
      getYsToken();
    } else {
      try {
            const res = await axios.post(ysUrl + '/device/list', accessToken);
            if (res.data.code === "10002") {
                localStorage.clear();
                getYsToken();
                await getDeviceList();
            } else {
                if (!isOrg("测试站点")) {
                  return await getCamera(res.data.data);;
                } else {
                  return await getCameraList(res.data.data);
                }
            }
      } catch (error) {
            return null;
      }
    }
}

export const getCameraList = async (devices: any[]) => {
    let videoToken = localStorage.getItem(orgId + '_videoToken') as string;
    if (!Array.isArray(devices)) {
      return [];
    }

    const cameraPromises = devices.map(async (device) => {
      const formData = new FormData();
      formData.append('accessToken', videoToken);
      formData.append('deviceSerial', device.deviceSerial);

      try {
            const res = await axios.post(ysUrl + '/device/camera/list', formData);
            const camerasData = res.data.data;

            return camerasData
                .filter((camera: any) => camera.status !== -1)
                .map((camera: any) => {
                  return {
                        channelName: camera.channelName,
                        channelNo: camera.channelNo,
                        deviceSerial: camera.deviceSerial,
                  };
                });
      } catch (error) {
            return [];
      }
    });

    const results = await Promise.all(cameraPromises);
    return results.flat();
}

export const getCamera = async (device: any) => {
    const formData = new FormData();
    let videoToken = localStorage.getItem(orgId + '_videoToken') as string;
    formData.append('accessToken', videoToken);
    formData.append('deviceSerial', device.deviceSerial);

    try {
      const res = await axios.post(ysUrl + '/device/camera/list', formData);
      const camerasData = res.data.data;

      const filteredCameraList: Camera[] = camerasData
            .filter((camera: any) => camera.status !== -1)
            .map((camera: any) => {
                return {
                  channelName: camera.channelName,
                  channelNo: camera.channelNo,
                  deviceSerial: camera.deviceSerial,
                };
            });
      return filteredCameraList;
    } catch (error) {
      return [];
    }
}

export const getPlayVideo = async (Camera: any) => {
    const formData = new FormData();
    let videoToken = localStorage.getItem(orgId + '_videoToken') as string;
    formData.append('accessToken', videoToken);
    formData.append('deviceSerial', Camera.deviceSerial);
    formData.append('channelNo', Camera.channelNo);

    try {
      const res = await axios.post(ysUrl + '/v2/live/address/get', formData);
      const playData = res.data.data;
      playData.token = videoToken;
      return playData;
    } catch (error) {
      console.error(error);
      return [];
    }
}

export const getYsToken = async () => {

    const formData = new FormData();
    formData.append('appKey', appKey);
    formData.append('appSecret', appSecret);

    let storedToken = localStorage.getItem(orgId + '_videoToken');
    if (storedToken === undefined) {
      token = storedToken;
    } else {
      await axios.post(ysUrl + '/token/get', formData)
            .then((res) => {
                token = res.data.data.accessToken;
                localStorage.setItem(orgId + '_videoToken', token);
            })
            .catch((error) => {
                console.error(error);
            });
    }
};
样式这里就不分享,主要是个简单的例子,基本的效果已经实现了
页: [1]
查看完整版本: Vue3+TS接入萤石云实现视频切换播放