Commit dc553545 authored by 刘梦焕's avatar 刘梦焕

fix: 视频弹窗组件修改

parent 806aa9fc
......@@ -15,10 +15,45 @@ group:
## API
### Column 新增参数
### 主要参数说明
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| ModalInfo | api 参考 Antd Modal 组件 https://ant.design/components/modal-cn#api | | |
| VideoInfo | api 参考视频组件 VmsVideo 的 VideoParam | | - |
| JessibucaObj | api 参考视频组件 VmsVideo 的 JessibucaObj | | - |
| ModalInfo | api 参考 Antd Modal 组件 https://ant.design/components/modal-cn#api | object | {width:1000,title:'视频预览',footer:null} |
| VideoInfo | 传参格式[VideoParams,VideoParams,...],VideoParams 可参考如下详细说明 | array | - |
| JessibucaObj | 传参格式可参考如下详细说明 | object | - |
### VideoParam 参数和 JessibucaObj 参数详细说明
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| VideoParams | 每一个视频的信息,更多 api 可参考视频组件 VmsVideo 的 VideoParam | object | { } |
| | 【fullUrl】 完整 url,接入 flv 或者三方的链接 | string | "" |
| | 【username】 账号 | string | "6c44c8e92d1c4d75a9818756025df550" |
| | 【password】 密码 | string | "78b7dc88f9f4bf19c2b1aabfdd995244" |
| | 【address】 地址 | string | "123638446" |
| | 【protocol】 协议类型 | string | "萤石 EZOPEN" |
| | 【gateway】 是否走网关 | boolean | false |
| | 【pandavmsHost】 pandavms 后端主机地址 eg | string | ws://172.16.19.19:8080/ |
| | 【useFullUrl】 是否为完整 url,是,则取 fullUrl,否,则会用 pandavmsHost 和 id 去拼接 | boolean | false |
| | 【id】 摄像头唯一标识,一串 GUID | string | "" |
| | 【name】 摄像头名称 | string | "" |
| | 【dataRate】 码率,Main 为主码流,Sub 为辅码流,与消耗网络有关,主码流消耗最高,**由于拼接方式不定,改为是字符串传入** | string | 'Sub' |
| JessibucaObj | 更多 api 可参考视频组件 VmsVideo 的 JessibucaObj | object | { } |
| | 【hiddenAutoPause】 是否开启当页面的'visibilityState'变为'hidden'的时候,自动暂停播放。 | boolean | false |
| | 【hasAudio】 是否有音频,如果设置 false,则不对音频数据解码,提升性能 | boolean | true |
| | 【isFlv】 当为 true 的时候:ws 协议不检验是否以.flv 为依据,进行协议解析。 | boolean | false |
| | 【isNotMute】 是否开启声音,默认是关闭声音播放的。 | boolean | false |
| | 【loadingText】 加载过程中文案 | string | "视频加载中" |
| | 【controlAutoHide】 底部控制台是否自动隐藏 | boolean | false |
| | 【recordType】 默认录制的视频格式 | string | mp4 |
| | 【operateBtns】 配置操作按钮,以下为 operateBtns 详细属性 | object | |
| | 【fullscreen】 是否显示全屏按钮 | boolean | true |
| | 【screenshot】 是否显示截图按钮 | boolean | true |
| | 【play】 是否显示播放暂停按钮 | boolean | true |
| | 【audio】 是否显示声音按钮 | boolean | true |
| | 【record】 是否显示录制按钮 | boolean | true |
### 补充
更多参数,方法,事件,可查看 demo 中的传参
/*
* @Author: 634665781 634665781@qq.com
* @Date: 2023-04-11 13:40:18
* @LastEditors: 634665781 634665781@qq.com
* @LastEditTime: 2023-04-17 11:05:27
* @FilePath: \wisdom-components\packages\base-components\TestVideo\src\demos\dmeo1.tsx
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
*/
// @ts-ignore
import React, { useRef, useEffect, useState } from 'react';
import React, { useState } from 'react';
import { Button } from 'antd';
import VideoSliderModal from '../index';
const Demo = () => {
const [showModal, setShowModal] = useState(false);
// 关闭弹窗
const closeModal = () => {
setShowModal(false);
};
// 弹窗参数
const modalInfo = {
title: '视频预览',
title: '视频预览测试',
open: showModal,
onCancel: closeModal,
};
// 视频数据源信息
const videos = [
{
id: '11F102BC-CE03-4E32-AE60-F297934DFE3F', // 398993BB-A795-4237-BE75-B6A7EC9D675
name: '琼海电信小区', // 设备名称
id: '339B3B67-A7AE-45B2-89B7-227619A88A01', // 398993BB-A795-4237-BE75-B6A7EC9D675
name: '琼海电信小区1', // 设备名称
protocol: '萤石云HTTP-FLV', // 萤石EZOPE 萤石HTTP-FLV RTSP GB28181
username: '6c44c8e92d1c4d75a9818756025df550',
password: '78b7dc88f9f4bf19c2b1aabfdd995244',
dataRate: 'Sub', // Main 主码流 Sub 子码流
pandavmsHost: `ws://192.168.8.27:9876/`, // pandavms后端主机地址 eg: ws://172.16.19.19:8080/
pandavmsHost: `ws://192.168.8.30:7000/`, // pandavms后端主机地址 eg: ws://172.16.19.19:8080/
address: '236644034',
},
{
id: '11F102BC-CE03-4E32-AE60-F297934DFE3F', // 398993BB-A795-4237-BE75-B6A7EC9D675
name: '琼海电信小区', // 设备名称
id: '339B3B67-A7AE-45B2-89B7-227619A88A01', // 398993BB-A795-4237-BE75-B6A7EC9D675
name: '琼海电信小区2', // 设备名称
protocol: '萤石云HTTP-FLV', // 萤石EZOPE 萤石HTTP-FLV RTSP GB28181
username: '6c44c8e92d1c4d75a9818756025df550',
password: '78b7dc88f9f4bf19c2b1aabfdd995244',
dataRate: 'Sub', // Main 主码流 Sub 子码流
pandavmsHost: `ws://192.168.8.27:9876/`, // pandavms后端主机地址 eg: ws://172.16.19.19:8080/
pandavmsHost: `ws://192.168.8.30:7000/`, // pandavms后端主机地址 eg: ws://172.16.19.19:8080/
address: '236644034',
},
{
id: '11F102BC-CE03-4E32-AE60-F297934DFE3F', // 398993BB-A795-4237-BE75-B6A7EC9D675
name: '琼海电信小区', // 设备名称
id: '972DF430-2E69-4960-86E2-C1D336B85280', // 398993BB-A795-4237-BE75-B6A7EC9D675
name: '琼海电信小区3', // 设备名称
protocol: '萤石云HTTP-FLV', // 萤石EZOPE 萤石HTTP-FLV RTSP GB28181
username: '6c44c8e92d1c4d75a9818756025df550',
password: '78b7dc88f9f4bf19c2b1aabfdd995244',
dataRate: 'Sub', // Main 主码流 Sub 子码流
pandavmsHost: `ws://192.168.8.27:9876/`, // pandavms后端主机地址 eg: ws://172.16.19.19:8080/
pandavmsHost: `ws://192.168.8.30:7000/`, // pandavms后端主机地址 eg: ws://172.16.19.19:8080/
address: '236644034',
},
];
const JessibucaObj = {};
return (
<>
<Button onClick={() => setShowModal(true)}>打开弹窗</Button>
<VideoSliderModal modalInfo={modalInfo} videoInfos={videos} JessibucaObj={JessibucaObj} />
<VideoSliderModal modalInfo={modalInfo} videoInfos={videos} />
</>
);
};
......
import VmsVideo from '@wisdom-components/VmsVideo';
import { Button, Modal } from 'antd';
import classNames from 'classnames';
import { Modal, Space } from 'antd';
import React, { useState } from 'react';
import SwiperCore, { Autoplay, Lazy, Navigation, Pagination, Virtual } from 'swiper';
import { Swiper, SwiperSlide } from 'swiper/react';
......@@ -12,12 +11,7 @@ SwiperCore.use([Virtual, Navigation, Lazy, Autoplay, Pagination]);
const VideoSliderModal = (props) => {
const { modalInfo, videoInfos, JessibucaObj } = props;
const [swiper, setSwiper] = useState(null);
const handleSwiperRef = (node) => {
if (node) {
setSwiper(node.swiper);
}
};
const [activeIndex, setActiveIndex] = useState(0);
const handleNavigation = (direction) => {
if (swiper) {
......@@ -30,16 +24,18 @@ const VideoSliderModal = (props) => {
};
const handlePaginationClick = (index) => {
setActiveIndex(index);
if (swiper) {
swiper.slideTo(index);
}
};
// 默认配置
const _JessibucaObj = {
operateBtns: {
screenshot: false,
},
loadingText: '演示视频加载中',
loadingText: '视频加载中',
decoder: '/JessibucaVideo/decoder.js',
...JessibucaObj,
};
......@@ -47,29 +43,53 @@ const VideoSliderModal = (props) => {
return (
<Modal
footer={null}
width={800}
width={1000}
title="视频预览"
{...modalInfo}
wrapClassName={styles['video-carousel-modal']}
bodyStyle={{ padding: 0 }}
getContainer={document.body}
destroyOnClose
>
<Swiper onSwiper={handleSwiperRef} navigation pagination={{ clickable: true }}>
{videoInfos.map((videoInfo, index) => (
<Swiper
onSwiper={setSwiper}
slidesPerView={1}
spaceBetween={0}
pagination={{
clickable: true,
}}
loop
lazy
virtual
onActiveIndexChange={(e) => {
setActiveIndex(e.activeIndex);
}}
navigation
>
{videoInfos.map((item, index) => (
<SwiperSlide key={index}>
<VmsVideo VideoInfo={videoInfo} JessibucaObj={_JessibucaObj} />
<div className={styles['swiper-wrap']}>
<div className={styles['swiper-title']}>{item.name}</div>
<div className={styles['swiper-content']}>
<VmsVideo VideoInfo={item} JessibucaObj={_JessibucaObj} />
</div>
</div>
</SwiperSlide>
))}
</Swiper>
{/* <div>
<button onClick={() => handleNavigation('prev')}>Previous</button>
<button onClick={() => handleNavigation('next')}>Next</button>
<div className={styles['swiper-dots-wrap']}>
<Space size={16}>
{videoInfos.map((video, index) => (
<div
className={styles['swiper-dots']}
key={index}
onClick={() => handlePaginationClick(index)}
style={{ background: activeIndex === index ? '#007aff' : '#919090' }}
/>
))}
</Space>
</div>
<div>
{videoInfos.map((video, index) => (
<button key={index} onClick={() => handlePaginationClick(index)}>
{index + 1}
</button>
))}
</div> */}
</Modal>
);
};
......
@root-entry-name: 'default';
@import '~antd/es/style/themes/index.less';
.swiper-container {
height: 100%;
overflow: hidden;
.swiper-button-prev,
.swiper-button-next {
position: absolute;
top: 50%;
width: 50px;
height: 50px;
background-repeat: no-repeat;
background-size: 50% 50%;
transform: translateY(-50%);
cursor: pointer;
&:hover {
background-size: 60% 60%;
}
}
}
.video-carousel-modal {
.@{ant-prefix}-modal-body {
height: 500px;
padding: 0;
}
}
.video-slider-modal-nav {
display: flex;
align-items: center;
justify-content: center;
margin-top: 10px;
:global {
.@{ant-prefix}-btn:empty {
visibility: visible;
.@{ant-prefix}-modal-body {
position: relative;
height: auto;
padding: 0;
}
}
.video-slider-modal-nav-button {
margin-right: 10px;
color: #1890ff;
font-size: 16px;
background-color: transparent;
border: none;
cursor: pointer;
.swiper-wrap {
display: flex;
flex-direction: column;
height: 100%;
.swiper-title {
flex: none;
width: 100%;
height: 40px;
padding-left: 20px;
color: #ffffff;
line-height: 40px;
background: #454545;
}
.swiper-content {
flex: 1;
}
}
.video-slider-modal-nav-dots {
.swiper-dots-wrap {
position: absolute;
bottom: 8px;
left: 0;
z-index: 1;
display: flex;
align-items: center;
}
.video-slider-modal-nav-dot {
width: 8px;
height: 8px;
margin-right: 10px;
background-color: transparent;
border: 2px solid #ddd;
border-radius: 50%;
cursor: pointer;
}
justify-content: center;
width: 100%;
height: 22px;
.video-slider-modal-nav-dot.active {
background-color: #1890ff;
border-color: #1890ff;
.swiper-dots {
width: 8px;
height: 8px;
background: #919090;
border-radius: 50%;
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment