巴林闲侠
2 years ago
20 changed files with 601 additions and 251 deletions
@ -1,244 +0,0 @@ |
|||
import React, { useState, useEffect, useRef } from "react"; |
|||
import { connect } from "react-redux"; |
|||
import moment from 'moment' |
|||
import { Button, Modal, Col, Row, Space } from "@douyinfe/semi-ui"; |
|||
import TextScroll from './textScroll' |
|||
import './videoPlay.less'; |
|||
|
|||
const VideoPlay = ({ height, width }) => { |
|||
const [jessibuca, setjessibuca] = useState(null) |
|||
const [playUrl, setPlayUrl] = useState('http://flv.bdplay.nodemedia.cn/live/bbb.flv') |
|||
const [isPlaying, setIsPlaying] = useState(false) |
|||
const [operationState, setoperationState] = useState() |
|||
|
|||
const changeSelectState = (key) => { |
|||
const nextOperationState = JSON.parse(JSON.stringify(operationState)) |
|||
for (let k in nextOperationState) { |
|||
if (k == key) { |
|||
nextOperationState[k].select = !nextOperationState[k].select |
|||
} else if (key !== 'fullScreen') { |
|||
nextOperationState[k].select = false |
|||
} |
|||
} |
|||
return nextOperationState |
|||
} |
|||
|
|||
const operation = [{ |
|||
key: 'control', |
|||
click: () => { |
|||
let nextOperationState = changeSelectState('control') |
|||
setoperationState(nextOperationState) |
|||
} |
|||
}, { |
|||
key: 'talk', |
|||
click: () => { |
|||
let nextOperationState = changeSelectState('talk') |
|||
setoperationState(nextOperationState) |
|||
} |
|||
}, { |
|||
key: 'fullScreen', |
|||
click: () => { |
|||
let nextOperationState = changeSelectState('fullScreen') |
|||
setoperationState(nextOperationState) |
|||
} |
|||
}, { |
|||
key: 'histroy', |
|||
click: () => { |
|||
|
|||
} |
|||
},] |
|||
useEffect(() => { |
|||
create() |
|||
let nextOperationState = {} |
|||
for (let p of operation) { |
|||
nextOperationState[p.key] = { |
|||
select: false |
|||
} |
|||
} |
|||
setoperationState(nextOperationState) |
|||
}, []) |
|||
|
|||
const create = () => { |
|||
let $container = document.getElementById('container'); |
|||
const jessibuca = new window.Jessibuca({ |
|||
container: $container, |
|||
videoBuffer: 0.2, // 缓存时长 |
|||
isResize: false, |
|||
text: "", |
|||
loadingText: "加载中", |
|||
debug: true, |
|||
showBandwidth: true, // 显示网速 |
|||
operateBtns: { |
|||
fullscreen: true, |
|||
screenshot: true, |
|||
play: true, |
|||
audio: true, |
|||
}, |
|||
forceNoOffscreen: false, |
|||
isNotMute: false, |
|||
}); |
|||
setjessibuca(jessibuca) |
|||
} |
|||
|
|||
useEffect(() => { |
|||
play() |
|||
}, [jessibuca]) |
|||
|
|||
const play = () => { |
|||
if (jessibuca && playUrl) { |
|||
jessibuca.play(playUrl); |
|||
setIsPlaying(true) |
|||
} |
|||
} |
|||
|
|||
const pause = () => { |
|||
if (jessibuca) { |
|||
jessibuca.pause(); |
|||
setIsPlaying(false) |
|||
} |
|||
} |
|||
|
|||
const butStyle = { |
|||
border: '1px solid #fff', display: 'inline-block', color: '#fff', padding: '0 10px', |
|||
display: 'flex', alignItems: 'center', height: '64%', marginLeft: 12 |
|||
} |
|||
|
|||
return ( |
|||
<> |
|||
<div style={{ height: height || '100%', width: width || '100%' }}> |
|||
|
|||
<div style={{ position: 'relative', display: 'flex' }}> |
|||
{/* 顶部信息 */} |
|||
<div style={{ |
|||
height: 42, lineHeight: '42px', background: '#00000026', |
|||
position: 'absolute', width: '100%', zIndex: 99, |
|||
color: '#fff' |
|||
}}> |
|||
<Row > |
|||
<Col span={9} style={{ |
|||
backgroundImage: 'url(/assets/images/background/videoPlayBg.png)', |
|||
backgroundSize: '100% 100%', |
|||
backgroundRepeat: 'no-repeat', |
|||
textAlign: 'center' |
|||
}}>123</Col> |
|||
<Col span={15} style={{}}> |
|||
<div style={{ paddingRight: 12 }}> |
|||
<TextScroll content={['asdadasdasdasdasdasd', '123123']} duration={6} /> |
|||
</div> |
|||
</Col> |
|||
</Row> |
|||
</div> |
|||
{/* 视频内容 */} |
|||
<div id="container" style={{ height: height || '100%', width: width || '100%' }}></div> |
|||
{/* 云控 对讲 对应操作内容 */} |
|||
{ |
|||
operationState ? |
|||
operationState.control.select ? |
|||
<div style={{ |
|||
position: 'absolute', top: 'calc(50% - 105px)', left: 'calc(50% - 125px)', |
|||
width: 210, height: 250, backgroundColor: '#00000014', borderRadius: 68 |
|||
}}> |
|||
<div style={{ |
|||
height: 148, width: 148, borderRadius: '100%', backgroundColor: '#2F53EA72', margin: '12px auto 18px', |
|||
position: 'relative', |
|||
}}> |
|||
{ |
|||
[{ |
|||
style: { top: 12, left: (148 - 24) / 2, } |
|||
}, { |
|||
style: { right: 12, top: (148 - 24) / 2, } |
|||
}, { |
|||
style: { bottom: 12, left: (148 - 24) / 2, } |
|||
}, { |
|||
style: { left: 12, top: (148 - 24) / 2, } |
|||
}].map((s, i) => { |
|||
return ( |
|||
<img |
|||
src="/assets/images/background/up.png" |
|||
style={Object.assign({ |
|||
height: 24, width: 24, display: 'inline-block', transform: `rotate(${i * 90}deg)`, |
|||
position: 'absolute' |
|||
}, s.style)} |
|||
/> |
|||
) |
|||
}) |
|||
} |
|||
<div style={{ |
|||
height: 32, width: 32, border: '2px solid #ffffff24', borderRadius: '100%', |
|||
position: 'absolute', top: (148 - 34) / 2, left: (148 - 34) / 2 |
|||
}} /> |
|||
</div> |
|||
{ |
|||
[ |
|||
[{ n: '+' }, { n: '焦距' }, { n: '-' }], |
|||
[{ n: '+' }, { n: '缩放' }, { n: '-' }] |
|||
].map(s => { |
|||
return ( |
|||
<div style={{ |
|||
width: 110, height: 22, margin: '0 auto 6px', display: 'flex', alignContent: 'center', justifyContent: 'space-around', |
|||
backgroundColor: '#2F53EA72', color: '#fff' |
|||
}}> |
|||
{ |
|||
s.map((m, mi) => { |
|||
return ( |
|||
<div style={{ textAlign: 'center', display: 'inline-block', cursor: mi != 1 ? 'pointer' : 'auto' }}>{m.n}</div> |
|||
) |
|||
}) |
|||
} |
|||
</div> |
|||
) |
|||
}) |
|||
} |
|||
</div> : |
|||
operationState.talk.select ? |
|||
<div style={{ |
|||
position: 'absolute', top: 'calc(50% - 88px)', left: 'calc(50% - 156px)', |
|||
width: 312, height: 176, backgroundColor: '#000000A5', |
|||
}}> |
|||
<img src="/assets/images/background/talking.png" style={{ display: 'block', margin: '12px auto' }} /> |
|||
<div style={{ |
|||
height: 32, width: 88, textAlign: 'center', margin: 'auto', color: '#fff', backgroundColor: '#1859C1', |
|||
lineHeight: '32px' |
|||
}}>开始讲话</div> |
|||
</div> : |
|||
'' : '' |
|||
} |
|||
{/* 下方操作 */} |
|||
<div style={{ |
|||
height: 42, lineHeight: '42px', background: 'linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.8) 100%)', padding: '0 12px', |
|||
display: 'flex', justifyContent: 'space-between', |
|||
position: 'absolute', bottom: 0, width: '100%', zIndex: 99 |
|||
}}> |
|||
<div style={{ display: 'flex', alignItems: 'center' }}> |
|||
{ |
|||
operationState ? |
|||
operation.map(p => { |
|||
return <img |
|||
src={`/assets/images/background/video-icon-${p.key}-${operationState[p.key].select ? 'select' : 'unselect'}.png`} |
|||
height={26} |
|||
style={{ marginRight: 24 }} |
|||
onClick={p.click} |
|||
/> |
|||
}) : '' |
|||
} |
|||
</div> |
|||
<div style={{ display: 'flex', alignItems: 'center' }}> |
|||
<div style={butStyle}>标清</div> |
|||
<div style={butStyle}>高清</div> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
|
|||
</div> |
|||
</> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps (state) { |
|||
const { auth } = state; |
|||
return { |
|||
user: auth.user, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(VideoPlay); |
@ -0,0 +1,83 @@ |
|||
import React, { useState, useEffect, useRef } from "react"; |
|||
import { connect } from "react-redux"; |
|||
import moment from 'moment' |
|||
import VideoOperationCloudControl from './videoOperationCloudControl' |
|||
import VideoOperationTalk from './VideoOperationTalk' |
|||
import VideoOperationSpeed from './videoOperationSpeed' |
|||
import VideoOperationVoice from './VideoOperationVoice' |
|||
import { IconPause, IconPlay } from '@douyinfe/semi-icons'; |
|||
import './videoPlay.less'; |
|||
|
|||
const VideoOperation = ({ operationState, operation, voiceDisY, setVoiceDisY }) => { |
|||
|
|||
const butStyle = { |
|||
border: '1px solid #fff', display: 'inline-block', color: '#fff', padding: '0 10px', |
|||
display: 'flex', alignItems: 'center', height: '64%', marginLeft: 12, cursor: 'pointer', |
|||
position: 'relative' |
|||
} |
|||
|
|||
return ( |
|||
<> |
|||
{ |
|||
operationState ? |
|||
operationState.control.select ? |
|||
<VideoOperationCloudControl /> : |
|||
operationState.talk.select ? |
|||
<VideoOperationTalk /> : |
|||
'' : '' |
|||
} |
|||
{/* 下方操作 */} |
|||
<div style={{ |
|||
height: 42, lineHeight: '42px', background: 'linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.8) 100%)', padding: '0 12px', |
|||
display: 'flex', justifyContent: 'space-between', |
|||
position: 'absolute', bottom: 0, width: '100%', zIndex: 99, color: '#fff' |
|||
}}> |
|||
{ |
|||
operationState ? |
|||
operationState.histroy.select ? |
|||
<> |
|||
<div style={{ display: 'flex', alignItems: 'center' }}> |
|||
<IconPause style={{ cursor: 'pointer' }} /> |
|||
{/* <IconPlay style={{ cursor: 'pointer' }} /> */} |
|||
<span style={{ marginLeft: 12 }}>{moment().format('YYYY-MM-DD HH:mm:ss')}/{moment().format('YYYY-MM-DD HH:mm:ss')}</span> |
|||
</div> |
|||
<div style={{ display: 'flex', alignItems: 'center' }}> |
|||
<VideoOperationVoice voiceDisY={voiceDisY} setVoiceDisY={setVoiceDisY} /> |
|||
<VideoOperationSpeed butStyle={butStyle} /> |
|||
<div style={butStyle}>时间设置</div> |
|||
</div> |
|||
</> |
|||
: |
|||
<> |
|||
<div style={{ display: 'flex', alignItems: 'center' }}> |
|||
{ |
|||
operationState ? |
|||
operation.map(p => { |
|||
return <img |
|||
src={`/assets/images/background/video-icon-${p.key}-${operationState[p.key].select ? 'select' : 'unselect'}.png`} |
|||
height={26} |
|||
style={{ marginRight: 24, cursor: 'pointer' }} |
|||
onClick={p.click} |
|||
/> |
|||
}) : '' |
|||
} |
|||
</div> |
|||
<div style={{ display: 'flex', alignItems: 'center' }}> |
|||
<div style={butStyle}>标清</div> |
|||
<div style={butStyle}>高清</div> |
|||
</div> |
|||
</> : '' |
|||
} |
|||
</div> |
|||
</> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps (state) { |
|||
const { auth } = state; |
|||
return { |
|||
user: auth.user, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(VideoOperation); |
@ -0,0 +1,74 @@ |
|||
import React, { useState, useEffect, useRef } from "react"; |
|||
import { connect } from "react-redux"; |
|||
import './videoPlay.less'; |
|||
|
|||
const VideoOperationCloudControl = ({ }) => { |
|||
|
|||
return ( |
|||
<div style={{ |
|||
position: 'absolute', top: 'calc(50% - 105px)', left: 'calc(50% - 125px)', |
|||
width: 210, height: 250, backgroundColor: '#00000014', borderRadius: 68 |
|||
}}> |
|||
<div style={{ |
|||
height: 148, width: 148, borderRadius: '100%', backgroundColor: '#2F53EA72', margin: '12px auto 18px', |
|||
position: 'relative', |
|||
}}> |
|||
{ |
|||
[{ |
|||
style: { top: 12, left: (148 - 24) / 2, } |
|||
}, { |
|||
style: { right: 12, top: (148 - 24) / 2, } |
|||
}, { |
|||
style: { bottom: 12, left: (148 - 24) / 2, } |
|||
}, { |
|||
style: { left: 12, top: (148 - 24) / 2, } |
|||
}].map((s, i) => { |
|||
return ( |
|||
<img |
|||
src="/assets/images/background/up.png" |
|||
style={Object.assign({ |
|||
height: 24, width: 24, display: 'inline-block', transform: `rotate(${i * 90}deg)`, |
|||
position: 'absolute' |
|||
}, s.style)} |
|||
/> |
|||
) |
|||
}) |
|||
} |
|||
<div style={{ |
|||
height: 32, width: 32, border: '2px solid #ffffff24', borderRadius: '100%', |
|||
position: 'absolute', top: (148 - 34) / 2, left: (148 - 34) / 2 |
|||
}} /> |
|||
</div> |
|||
{ |
|||
[ |
|||
[{ n: '+' }, { n: '焦距' }, { n: '-' }], |
|||
[{ n: '+' }, { n: '缩放' }, { n: '-' }] |
|||
].map(s => { |
|||
return ( |
|||
<div style={{ |
|||
width: 110, height: 22, margin: '0 auto 6px', display: 'flex', alignContent: 'center', justifyContent: 'space-around', |
|||
backgroundColor: '#2F53EA72', color: '#fff' |
|||
}}> |
|||
{ |
|||
s.map((m, mi) => { |
|||
return ( |
|||
<div style={{ textAlign: 'center', display: 'inline-block', cursor: mi != 1 ? 'pointer' : 'auto' }}>{m.n}</div> |
|||
) |
|||
}) |
|||
} |
|||
</div> |
|||
) |
|||
}) |
|||
} |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps (state) { |
|||
const { auth } = state; |
|||
return { |
|||
user: auth.user, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(VideoOperationCloudControl); |
@ -0,0 +1,33 @@ |
|||
import React, { useState, useEffect, useRef } from "react"; |
|||
import { connect } from "react-redux"; |
|||
import './videoPlay.less'; |
|||
|
|||
const VideoOperationSpeed = ({ butStyle }) => { |
|||
|
|||
return ( |
|||
<div style={butStyle} className="video_speed_but"> |
|||
<div className="video_speed_options" style={{ |
|||
position: 'absolute', top: -24 * 3 - 24, backgroundColor: '#00000099', width: 60, |
|||
left: -6, padding: '8px 0' |
|||
}}> |
|||
{ |
|||
[1, 2, 3].map((s) => { |
|||
return ( |
|||
<div className="video_speed_option" style={{ textAlign: 'center', height: 24, lineHeight: '24px' }}>{s}.0 x</div> |
|||
) |
|||
}) |
|||
} |
|||
</div> |
|||
倍速 |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps (state) { |
|||
const { auth } = state; |
|||
return { |
|||
user: auth.user, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(VideoOperationSpeed); |
@ -0,0 +1,33 @@ |
|||
import React, { useState, useEffect, useRef } from "react"; |
|||
import { connect } from "react-redux"; |
|||
import './videoPlay.less'; |
|||
|
|||
const VideoOperationTalk = ({ butStyle }) => { |
|||
|
|||
return ( |
|||
<div style={butStyle} className="video_speed_but"> |
|||
<div className="video_speed_options" style={{ |
|||
position: 'absolute', top: -24 * 3 - 24, backgroundColor: '#00000099', width: 60, |
|||
left: -6, padding: '8px 0' |
|||
}}> |
|||
{ |
|||
[1, 2, 3].map((s) => { |
|||
return ( |
|||
<div className="video_speed_option" style={{ textAlign: 'center', height: 24, lineHeight: '24px' }}>{s}.0 x</div> |
|||
) |
|||
}) |
|||
} |
|||
</div> |
|||
倍速 |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps (state) { |
|||
const { auth } = state; |
|||
return { |
|||
user: auth.user, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(VideoOperationTalk); |
@ -0,0 +1,74 @@ |
|||
import React, { useState, useEffect, useRef } from "react"; |
|||
import { connect } from "react-redux"; |
|||
import { IconVolume2, } from '@douyinfe/semi-icons'; |
|||
import './videoPlay.less'; |
|||
|
|||
const VideoOperationVoice = ({ voiceDisY, setVoiceDisY }) => { |
|||
|
|||
return ( |
|||
<div className="video_voice_but" style={{ display: 'flex', alignItems: 'center', position: 'relative', height: '100%', }}> |
|||
<div className="video_voice_options"> |
|||
<div style={{ |
|||
position: 'absolute', top: -100 - 32 - 16, backgroundColor: '#00000099', width: 32, |
|||
left: -9, padding: '4px 0 12px', |
|||
display: 'flex', justifyContent: 'center', flexDirection: 'column', alignItems: 'center', |
|||
}}> |
|||
<span style={{ height: 32, lineHeight: '32px', }}>{Math.abs(voiceDisY)}</span> |
|||
<div style={{ |
|||
width: 2, height: 100, backgroundColor: '#ffffffa0', position: 'relative', |
|||
}} onMouseDown={(ev) => { console.log('object'); }}> |
|||
<div |
|||
style={{ |
|||
height: 12, width: 12, borderRadius: '100%', backgroundColor: '#fff', |
|||
position: 'relative', left: -5, cursor: 'pointer', |
|||
bottom: -94 |
|||
}} |
|||
id='voice_point' |
|||
onMouseDown={(ev) => { |
|||
ev.stopPropagation(); |
|||
ev.preventDefault(); |
|||
|
|||
let oevent = ev; |
|||
let distanceY = oevent.clientY |
|||
let prev = Date.now(); |
|||
const point = document.getElementById('voice_point') |
|||
document.onmousemove = function (ev) { |
|||
ev.stopPropagation(); |
|||
ev.preventDefault(); |
|||
// 节流 |
|||
let now = Date.now(); |
|||
if (now - prev >= 0) { |
|||
let oevent = ev; |
|||
let y = voiceDisY + oevent.clientY - distanceY |
|||
if (y < -100) { |
|||
y = -100 |
|||
} else if (y > 0) { |
|||
y = 0 |
|||
} |
|||
setVoiceDisY(y) |
|||
point.style.bottom = -94 - y + 'px'; |
|||
prev = Date.now(); |
|||
} |
|||
}; |
|||
document.onmouseup = function () { |
|||
document.onmousemove = null; |
|||
document.onmouseup = null; |
|||
}; |
|||
}} |
|||
/> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
<IconVolume2 style={{ cursor: 'pointer' }} /> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps (state) { |
|||
const { auth } = state; |
|||
return { |
|||
user: auth.user, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(VideoOperationVoice); |
@ -0,0 +1,140 @@ |
|||
import React, { useState, useEffect, useRef } from "react"; |
|||
import { connect } from "react-redux"; |
|||
import screenfull from 'screenfull'; |
|||
import VideoHeader from './voiceHeader' |
|||
import VideoOperation from './videoOperation' |
|||
import './videoPlay.less'; |
|||
|
|||
const VideoPlay = ({ height, width }) => { |
|||
const [jessibuca, setjessibuca] = useState(null) |
|||
const [playUrl, setPlayUrl] = useState('http://flv.bdplay.nodemedia.cn/live/bbb.flv') |
|||
const [isPlaying, setIsPlaying] = useState(false) |
|||
const [operationState, setoperationState] = useState() |
|||
const [voiceDisY, setVoiceDisY] = useState(0) |
|||
|
|||
const changeSelectState = (key) => { |
|||
const nextOperationState = JSON.parse(JSON.stringify(operationState)) |
|||
for (let k in nextOperationState) { |
|||
if (k == key) { |
|||
nextOperationState[k].select = !nextOperationState[k].select |
|||
} else if (k !== 'fullScreen') { |
|||
nextOperationState[k].select = false |
|||
} |
|||
} |
|||
return nextOperationState |
|||
} |
|||
|
|||
const operation = [{ |
|||
key: 'control', |
|||
click: () => { |
|||
let nextOperationState = changeSelectState('control') |
|||
setoperationState(nextOperationState) |
|||
} |
|||
}, { |
|||
key: 'talk', |
|||
click: () => { |
|||
let nextOperationState = changeSelectState('talk') |
|||
setoperationState(nextOperationState) |
|||
} |
|||
}, { |
|||
key: 'fullScreen', |
|||
click: () => { |
|||
let nextOperationState = changeSelectState('fullScreen') |
|||
setoperationState(nextOperationState) |
|||
let player = document.getElementById('vcmp_videoplay') |
|||
if (screenfull.isEnabled) { |
|||
screenfull.toggle(player); |
|||
} |
|||
} |
|||
}, { |
|||
key: 'histroy', |
|||
click: () => { |
|||
let nextOperationState = changeSelectState('histroy') |
|||
setoperationState(nextOperationState) |
|||
} |
|||
},] |
|||
useEffect(() => { |
|||
create() |
|||
let nextOperationState = {} |
|||
for (let p of operation) { |
|||
nextOperationState[p.key] = { |
|||
select: false |
|||
} |
|||
} |
|||
setoperationState(nextOperationState) |
|||
}, []) |
|||
|
|||
const create = () => { |
|||
let $container = document.getElementById('container'); |
|||
const jessibuca = new window.Jessibuca({ |
|||
container: $container, |
|||
videoBuffer: 0.2, // 缓存时长 |
|||
isResize: false, |
|||
text: "", |
|||
loadingText: "加载中", |
|||
debug: true, |
|||
showBandwidth: true, // 显示网速 |
|||
operateBtns: { |
|||
fullscreen: true, |
|||
screenshot: true, |
|||
play: true, |
|||
audio: true, |
|||
}, |
|||
forceNoOffscreen: false, |
|||
isNotMute: false, |
|||
}); |
|||
setjessibuca(jessibuca) |
|||
play() |
|||
} |
|||
|
|||
useEffect(() => { |
|||
play() |
|||
}, [jessibuca]) |
|||
|
|||
const play = () => { |
|||
if (jessibuca && playUrl) { |
|||
jessibuca.play(playUrl); |
|||
setIsPlaying(true) |
|||
} |
|||
} |
|||
|
|||
const pause = () => { |
|||
if (jessibuca) { |
|||
jessibuca.pause(); |
|||
setIsPlaying(false) |
|||
} |
|||
} |
|||
|
|||
return ( |
|||
<> |
|||
<div style={{ height: height || '100%', width: width || '100%' }}> |
|||
<div id="vcmp_videoplay" style={{ position: 'relative', display: 'flex', height: '100%', width: '100%' }}> |
|||
{/* 顶部信息 */} |
|||
<VideoHeader operationState={operationState} changeSelectState={changeSelectState} setoperationState={setoperationState} /> |
|||
{/* 视频内容 */} |
|||
<div id="container" |
|||
style={{ |
|||
height: '100%', width: '100%' |
|||
}}> |
|||
|
|||
</div> |
|||
{/* 云控 对讲 对应操作内容 */} |
|||
<VideoOperation |
|||
operationState={operationState} operation={operation} |
|||
voiceDisY={voiceDisY} setVoiceDisY={setVoiceDisY} |
|||
/> |
|||
</div> |
|||
|
|||
</div> |
|||
</> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps (state) { |
|||
const { auth } = state; |
|||
return { |
|||
user: auth.user, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(VideoPlay); |
@ -0,0 +1,23 @@ |
|||
.video_speed_but:hover { |
|||
.video_speed_options { |
|||
display: block; |
|||
} |
|||
} |
|||
|
|||
.video_speed_options { |
|||
display: none; |
|||
} |
|||
|
|||
.video_speed_option:hover { |
|||
color: #A3B5FF; |
|||
} |
|||
|
|||
.video_voice_but:hover { |
|||
.video_voice_options { |
|||
display: block; |
|||
} |
|||
} |
|||
|
|||
.video_voice_options { |
|||
display: none; |
|||
} |
@ -0,0 +1,53 @@ |
|||
import React, { useState, useEffect, useRef } from "react"; |
|||
import { connect } from "react-redux"; |
|||
import moment from 'moment' |
|||
import { Col, Row, } from "@douyinfe/semi-ui"; |
|||
import { IconReply } from '@douyinfe/semi-icons'; |
|||
import TextScroll from '../textScroll' |
|||
import './videoPlay.less'; |
|||
|
|||
const VideoHeader = ({ operationState, changeSelectState, setoperationState }) => { |
|||
|
|||
return ( |
|||
<div style={{ |
|||
height: 42, lineHeight: '42px', background: '#00000026', |
|||
position: 'absolute', width: '100%', zIndex: 99, |
|||
color: '#fff' |
|||
}}> |
|||
<Row> |
|||
<Col span={9} style={{ |
|||
backgroundImage: 'url(/assets/images/background/videoPlayBg.png)', |
|||
backgroundSize: '100% 100%', |
|||
backgroundRepeat: 'no-repeat', |
|||
// textAlign: 'center', |
|||
padding: '0 12px' |
|||
}}> |
|||
{ |
|||
operationState && operationState.histroy.select ? |
|||
<> |
|||
<IconReply style={{ marginRight: 12, cursor: 'pointer' }} onClick={() => { |
|||
let nextOperationState = changeSelectState('histroy') |
|||
setoperationState(nextOperationState) |
|||
}} /> |
|||
</> : '' |
|||
} |
|||
{moment().format('YYYY-MM-DD HH:mm:ss')} xxxxxxx |
|||
</Col> |
|||
<Col span={15} style={{}}> |
|||
<div style={{ paddingRight: 12 }}> |
|||
<TextScroll content={['asdadasdasdasdasdasd', '123123']} duration={6} /> |
|||
</div> |
|||
</Col> |
|||
</Row> |
|||
</div> |
|||
) |
|||
} |
|||
|
|||
function mapStateToProps (state) { |
|||
const { auth } = state; |
|||
return { |
|||
user: auth.user, |
|||
}; |
|||
} |
|||
|
|||
export default connect(mapStateToProps)(VideoHeader); |
Loading…
Reference in new issue