设置向导
This commit is contained in:
parent
130064b8ba
commit
375fb2a022
|
|
@ -1,5 +1,5 @@
|
|||
#基础API 绝对的
|
||||
VITE_BASE_URL_API = 'http://192.168.2.9:6500'
|
||||
VITE_BASE_URL_API = 'http://192.168.2.8:5192'
|
||||
VITE_BASE_URL_DRAW_API = 'http://192.168.2.9:6555'
|
||||
#当前IP 相对的
|
||||
VITE_BASE_CURRENT_API = '.'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#基础API 绝对的
|
||||
VITE_BASE_URL_API = 'http://192.168.2.9:6500'
|
||||
VITE_BASE_URL_API = 'http://192.168.2.8:5192'
|
||||
VITE_BASE_URL_DRAW_API = 'http://192.168.2.9:6555'
|
||||
#当前IP 相对的
|
||||
VITE_BASE_CURRENT_API = '.'
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#基础API 绝对的
|
||||
VITE_BASE_URL_API = 'http://192.168.2.9:6500'
|
||||
VITE_BASE_URL_API = 'http://192.168.2.8:5192'
|
||||
VITE_BASE_URL_DRAW_API = 'http://192.168.2.9:6555'
|
||||
#当前IP 相对的
|
||||
VITE_BASE_CURRENT_API = '.'
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -20,7 +20,9 @@
|
|||
"make:prod": "vite build --mode production & electron-forge make"
|
||||
},
|
||||
"agora_electron": {
|
||||
"prebuilt": true
|
||||
"platform": "win32",
|
||||
"prebuilt": true,
|
||||
"arch": "ia32"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.3.7",
|
||||
|
|
@ -53,7 +55,7 @@
|
|||
"@vitejs/plugin-react": "^1.0.7",
|
||||
"concurrently": "^7.6.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"electron": "^17.4.11",
|
||||
"electron": "^31.1.0",
|
||||
"typescript": "^4.5.4",
|
||||
"vite": "^2.8.0"
|
||||
},
|
||||
|
|
|
|||
125
preload.js
125
preload.js
|
|
@ -7,8 +7,10 @@ const {
|
|||
VideoViewSetupMode,
|
||||
ScreenCaptureSourceType,
|
||||
RenderModeType,
|
||||
ChannelProfileType
|
||||
} = require("agora-electron-sdk");
|
||||
const agoraAonfig = require('./src/utils/package/agoraConfig')
|
||||
const agoraAonfig = require('./src/utils/package/agoraConfig');
|
||||
const { message } = require('antd');
|
||||
const rtcEngine = createAgoraRtcEngine();
|
||||
rtcEngine.initialize({
|
||||
appId: agoraAonfig.appid,
|
||||
|
|
@ -22,28 +24,26 @@ const getDom = () => {
|
|||
const EventHandles = {
|
||||
// 监听本地用户加入频道事件
|
||||
onJoinChannelSuccess: ({ channelId, localUid }, elapsed) => {
|
||||
const dom = document.getElementById('video1')
|
||||
console.log({ channelId, localUid });
|
||||
// 本地用户加入频道后,设置本地视频窗口
|
||||
rtcEngine.setupLocalVideo({
|
||||
renderMode: RenderModeType.RenderModeFit,
|
||||
sourceType: VideoSourceType.VideoSourceScreen,
|
||||
// sourceType: VideoSourceType.VideoSourceCameraPrimary,
|
||||
uid: localUid,
|
||||
view: dom,
|
||||
// view: getDom(),
|
||||
view: getDom(),
|
||||
setupMode: VideoViewSetupMode.VideoViewSetupAdd,
|
||||
});
|
||||
},
|
||||
// 监听远端用户加入频道事件
|
||||
onUserJoined: ({ channelId, localUid }, remoteUid, elapsed) => {
|
||||
console.log('远端用户 ' + remoteUid + ' 已加入');
|
||||
const dom = document.getElementById('video2')
|
||||
// 远端用户加入频道后,设置远端视频窗口
|
||||
rtcEngine.setupRemoteVideo(
|
||||
{
|
||||
renderMode: RenderModeType.RenderModeFit,
|
||||
sourceType: VideoSourceType.VideoSourceRemote,
|
||||
uid: remoteUid,
|
||||
view: dom,
|
||||
view: getDom(),
|
||||
setupMode: VideoViewSetupMode.VideoViewSetupAdd,
|
||||
},
|
||||
{ channelId },
|
||||
|
|
@ -51,24 +51,28 @@ const EventHandles = {
|
|||
|
||||
},
|
||||
// 监听用户离开频道事件
|
||||
onUserOffline: (info, remoteUid, reason) => {
|
||||
console.log('远端用户 ' + remoteUid + ' 已离开频道');
|
||||
onUserOffline: ({ channelId, localUid }, remoteUid, reason) => {
|
||||
// 远端用户离开频道后,关闭远端视频窗口
|
||||
const dom = document.getElementById('video2')
|
||||
rtcEngine.setupRemoteVideo(
|
||||
{
|
||||
renderMode: RenderModeType.RenderModeFit,
|
||||
sourceType: VideoSourceType.VideoSourceRemote,
|
||||
uid: remoteUid,
|
||||
view: dom,
|
||||
view: getDom(),
|
||||
setupMode: VideoViewSetupMode.VideoViewSetupRemove,
|
||||
},
|
||||
);
|
||||
},
|
||||
// 用户音量提示回调。
|
||||
onAudioVolumeIndication: (connection, speakers, speakerNumber, totalVolume) => {
|
||||
const percentage = (totalVolume / 255) * 100
|
||||
if (document.getElementById('recordingDeviceTest')) {
|
||||
document.getElementById('recordingDeviceTest').style.width = `${percentage}%`
|
||||
}
|
||||
}
|
||||
};
|
||||
rtcEngine.registerEventHandler(EventHandles);
|
||||
|
||||
|
||||
contextBridge.exposeInMainWorld(
|
||||
'electron',
|
||||
{
|
||||
|
|
@ -77,7 +81,7 @@ contextBridge.exposeInMainWorld(
|
|||
return rtcEngine.getScreenCaptureSources({ width: 300, height: 300 }, { width: 300, height: 300 }, true);
|
||||
},
|
||||
|
||||
// 设置视频播放
|
||||
// 共享屏幕采集
|
||||
setDesktopCapturerVideo: (targetSource) => {
|
||||
rtcEngine.stopScreenCapture()
|
||||
if (
|
||||
|
|
@ -105,7 +109,10 @@ contextBridge.exposeInMainWorld(
|
|||
);
|
||||
}
|
||||
videoID = `vidoe-${123}-${agoraAonfig.channelId}`;
|
||||
rtcEngine.joinChannel(agoraAonfig.token, agoraAonfig.channelId, 123, {
|
||||
rtcEngine.joinChannelEx(agoraAonfig.token, {
|
||||
channelId: agoraAonfig.channelId,
|
||||
localUid: 123,
|
||||
}, {
|
||||
autoSubscribeAudio: true, //设置是否自动订阅所有音频流
|
||||
autoSubscribeVideo: true, //设置是否自动订阅所有视频流
|
||||
publishMicrophoneTrack: false, //设置是否发布麦克风采集到的音频
|
||||
|
|
@ -114,6 +121,23 @@ contextBridge.exposeInMainWorld(
|
|||
publishScreenTrack: true, //设置是否发布屏幕采集的视频
|
||||
});
|
||||
},
|
||||
// 摄像头采集
|
||||
setCameraCapture: () => {
|
||||
rtcEngine.startCameraCapture(VideoSourceType.VideoSourceCamera, {})
|
||||
videoID = `vidoe-${123}-${agoraAonfig.channelId}`;
|
||||
rtcEngine.joinChannelEx(agoraAonfig.token, {
|
||||
channelId: agoraAonfig.channelId,
|
||||
localUid: 123,
|
||||
}, {
|
||||
channelProfile: ChannelProfileType.ChannelProfileLiveBroadcasting, //设置频道场景为直播场景
|
||||
clientRoleType: ClientRoleType.ClientRoleBroadcaster, //设置用户角色为主播;如果要将用户角色设置为观众,保持默认值即可
|
||||
publishMicrophoneTrack: true, //发布麦克风采集的音频
|
||||
publishCameraTrack: true, //发布摄像头采集的视频
|
||||
autoSubscribeAudio: true, //自动订阅所有音频流
|
||||
autoSubscribeVideo: true, //自动订阅所有视频流
|
||||
publishScreenTrack: false, //设置是否发布屏幕采集的视频
|
||||
});
|
||||
},
|
||||
// 加入频道
|
||||
setJoinChannel: () => {
|
||||
videoID = `vidoe-${234}-${agoraAonfig.channelId}`;
|
||||
|
|
@ -133,18 +157,73 @@ contextBridge.exposeInMainWorld(
|
|||
getVideoId: () => {
|
||||
return videoID;
|
||||
},
|
||||
// 获取摄像头以及音频内容
|
||||
getCameraAndMicrophoneMedia: async () => {
|
||||
try {
|
||||
const stream = await navigator.mediaDevices.getUserMedia({
|
||||
// 获取音频设备列表
|
||||
getAudioMediaList: () => {
|
||||
return {
|
||||
currentDevice: rtcEngine.getAudioDeviceManager().getRecordingDefaultDevice(),
|
||||
currentDevices: rtcEngine.getAudioDeviceManager().enumerateRecordingDevices(),
|
||||
currentVolume: rtcEngine.getAudioDeviceManager().getRecordingDeviceVolume()
|
||||
}
|
||||
},
|
||||
// 设置音频设备音量
|
||||
setRecordingDeviceVolume: (volume) => {
|
||||
rtcEngine.getAudioDeviceManager().setRecordingDeviceVolume(volume)
|
||||
},
|
||||
// 设置音频采集设备
|
||||
setRecordingDevice: (deviceId) => {
|
||||
rtcEngine.getAudioDeviceManager().setRecordingDevice(deviceId)
|
||||
},
|
||||
// 启动音频采集设备测试
|
||||
startRecordingDeviceTest: (indicationInterval) => {
|
||||
rtcEngine.getAudioDeviceManager().startRecordingDeviceTest(indicationInterval)
|
||||
navigator.mediaDevices.getUserMedia({ audio: true })
|
||||
.then((stream) => {
|
||||
let dom = document.getElementById('startAudio');
|
||||
dom.srcObject = stream;
|
||||
dom.play()
|
||||
})
|
||||
.catch((error) => {
|
||||
message.error('无法获取麦克风!');
|
||||
});
|
||||
},
|
||||
// 停止音频设备回路测试
|
||||
stopAudioDeviceLoopbackTest: () => {
|
||||
rtcEngine.getAudioDeviceManager().stopAudioDeviceLoopbackTest()
|
||||
rtcEngine.getAudioDeviceManager().stopRecordingDeviceTest()
|
||||
let video = document.getElementById('startPreview');
|
||||
if (video.srcObject) {
|
||||
const tracks = video.srcObject.getTracks();
|
||||
tracks.forEach((track) => {
|
||||
track.stop();
|
||||
});
|
||||
video.srcObject = null;
|
||||
}
|
||||
let audio = document.getElementById('startAudio');
|
||||
if (audio.srcObject) {
|
||||
const tracks = audio.srcObject.getTracks();
|
||||
tracks.forEach((track) => {
|
||||
track.stop();
|
||||
});
|
||||
audio.srcObject = null;
|
||||
}
|
||||
},
|
||||
// 开启本地视频预览
|
||||
startPreview: async () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
navigator.mediaDevices.getUserMedia({
|
||||
video: true,
|
||||
audio: true,
|
||||
}).then((stream) => {
|
||||
let dom = document.getElementById('startPreview');
|
||||
dom.srcObject = stream;
|
||||
dom.play()
|
||||
resolve(true)
|
||||
}).catch((error) => {
|
||||
message.error('无法获取摄像头!');
|
||||
resolve(true)
|
||||
});
|
||||
stream.getTracks().forEach(track => track.stop());
|
||||
return stream
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
})
|
||||
|
||||
},
|
||||
// 设置窗口大小
|
||||
setMainWindowSize: (config) => {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { request } from '@/utils'
|
||||
export const GetViewSize = (data: any) =>
|
||||
export const GetCheckUser = (userName: string) =>
|
||||
request({
|
||||
url: `/draw/position?X=${data.X}&Y=${data.Y}&Width=${data.Width}&Height=${data.Height}&ImageUrl=${data.ImageUrl}&ImageWidth=${data.ImageWidth}&ImageHeight=${data.ImageHeight}`,
|
||||
url: `/auth/check-user?userName=${userName}`,
|
||||
method: 'get'
|
||||
})
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 745 B |
Binary file not shown.
|
After Width: | Height: | Size: 2.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.7 KiB |
|
|
@ -4,6 +4,8 @@ import { useEffect, useState } from "react";
|
|||
import { useNavigate } from 'react-router-dom';
|
||||
import { Input, Button, Checkbox } from "antd"
|
||||
import { storage } from '@/utils'
|
||||
import { GetCheckUser } from '@/api/Login'
|
||||
|
||||
const Login: React.FC = () => {
|
||||
const navigate = useNavigate();
|
||||
const [accountPasswordStatus, setAccountPasswordStatus] = useState<boolean>(false);
|
||||
|
|
@ -124,6 +126,9 @@ const Login: React.FC = () => {
|
|||
...operation,
|
||||
account: e.target.value
|
||||
})
|
||||
// GetCheckUser(e.target.value).then(res => {
|
||||
// console.log(res);
|
||||
// })
|
||||
}}
|
||||
className={`${styles.loginInputIcon} drag`}
|
||||
style={{ marginBottom: '12px' }}
|
||||
|
|
@ -176,12 +181,12 @@ const Login: React.FC = () => {
|
|||
<span>or</span>
|
||||
<div></div>
|
||||
</div>
|
||||
<div className={`${styles.code} drag`}>
|
||||
{/* <div className={`${styles.code} drag`}>
|
||||
<div>
|
||||
<Input placeholder="输入会议号" className={`${styles.loginInput}`} />
|
||||
</div>
|
||||
<div><img src="/src/assets/icon3.png" alt="" /></div>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -117,7 +117,7 @@
|
|||
.meetingContentSwiperCardVdeio {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background:black url('/src/assets/error.png') no-repeat center/30%;
|
||||
background: black url('/src/assets/error.png') no-repeat center/30%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -128,12 +128,11 @@
|
|||
width: 1378px;
|
||||
margin: 0 auto;
|
||||
height: 0px;
|
||||
display: flex;
|
||||
|
||||
.meetingContentVideoDom {
|
||||
border: 1px red solid;
|
||||
width: 50%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background:black url('/src/assets/error.png') no-repeat center/30%;
|
||||
background: black url('/src/assets/error.png') no-repeat center/30%;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -507,6 +506,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
// 共享屏幕
|
||||
.sharedScreenModal {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
|
@ -514,10 +514,10 @@
|
|||
>div:nth-child(1) {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
max-height: 50vh;
|
||||
overflow-y: auto;
|
||||
align-content: flex-start;
|
||||
padding: 50px 0 0;
|
||||
max-height: 40vh;
|
||||
overflow-y: auto;
|
||||
|
||||
>div {
|
||||
display: flex;
|
||||
|
|
@ -576,4 +576,90 @@
|
|||
justify-content: space-between;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
// 设置向导
|
||||
.stupWizard {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
>div:nth-child(1) {
|
||||
padding: 20px 0 0;
|
||||
overflow-x: hidden;
|
||||
max-height: 60vh;
|
||||
overflow-y: auto;
|
||||
|
||||
>div:nth-child(1) {
|
||||
color: #EEEEEE;
|
||||
font-weight: bold;
|
||||
font-size: 20px;
|
||||
}
|
||||
|
||||
>div:nth-child(2) {
|
||||
>div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 22px;
|
||||
|
||||
>span {
|
||||
flex-shrink: 0;
|
||||
color: #828282;
|
||||
font-size: 18px;
|
||||
width: 130px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
>div:nth-child(3) {
|
||||
margin-top: 34px;
|
||||
|
||||
>span {
|
||||
color: #828282;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
>div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-top: 20px;
|
||||
|
||||
>img {
|
||||
flex-shrink: 0;
|
||||
width: 36px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
>div {
|
||||
flex-grow: 1;
|
||||
height: 40px;
|
||||
position: relative;
|
||||
|
||||
>img {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
>div {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 0%;
|
||||
overflow: hidden;
|
||||
|
||||
>img {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
>div:nth-child(2) {
|
||||
flex-shrink: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-end;
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
|
@ -6,7 +6,7 @@ import { Swiper, SwiperSlide } from 'swiper/react';
|
|||
import 'swiper/css';
|
||||
import 'swiper/css/navigation';
|
||||
import 'swiper/css/pagination';
|
||||
import { Button, Input, Popover, Modal, Checkbox, message } from "antd";
|
||||
import { Button, Input, Popover, Modal, Checkbox, message, Select, Slider } from "antd";
|
||||
import { SearchOutlined } from '@ant-design/icons';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { thumbImageBufferToBase64 } from '@/utils/package/base64'
|
||||
|
|
@ -17,6 +17,7 @@ const Meeting: React.FC = () => {
|
|||
userChatList: false,
|
||||
})
|
||||
const [isSharedScreenModal, setIsSharedScreenModal] = useState(false);
|
||||
const [isStupWizard, setIsStupWizard] = useState(false);
|
||||
const [sharedScreenList, setSharedScreenList] = useState<any>([]);
|
||||
const [sharedScreenItem, setSharedScreenItem] = useState<any>('');
|
||||
const [footerList] = useState([
|
||||
|
|
@ -77,6 +78,13 @@ const Meeting: React.FC = () => {
|
|||
},
|
||||
],
|
||||
])
|
||||
const [audioDeviceManager, setAudioDeviceManager] = useState<any>({
|
||||
currentDevices: [],
|
||||
currentDevice: {},
|
||||
currentVolume: 0,
|
||||
});
|
||||
const [stepsStatus, setStepsStatus] = useState<boolean>(true);
|
||||
const [isVideoLoad, setIsVideoLoad] = useState<boolean>(false);
|
||||
const [list] = useState<number[]>([1, 2, 3, 4, 5, 6, 7])
|
||||
const [open, setOpen] = useState(false)
|
||||
const [videoID, setVideoID] = useState('')
|
||||
|
|
@ -107,7 +115,10 @@ const Meeting: React.FC = () => {
|
|||
window.electron.setJoinChannel()
|
||||
setVideoID(window.electron.getVideoId())
|
||||
break;
|
||||
default:
|
||||
case '设置向导':
|
||||
getAudioMediaList()
|
||||
window.electron.startRecordingDeviceTest(200)
|
||||
setIsStupWizard(true)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -126,6 +137,7 @@ const Meeting: React.FC = () => {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
const getDesktopCapturerVideo = (): void => {
|
||||
window.electron.getDesktopCapturerVideo().then((res: any) => {
|
||||
if (sharedScreenList.length !== res.length) {
|
||||
|
|
@ -141,6 +153,21 @@ const Meeting: React.FC = () => {
|
|||
}
|
||||
})
|
||||
};
|
||||
|
||||
const getAudioMediaList = (): void => {
|
||||
const { currentDevices, currentDevice, currentVolume } = window.electron.getAudioMediaList();
|
||||
setAudioDeviceManager({
|
||||
currentDevices: currentDevices.map((row: any) => {
|
||||
return {
|
||||
value: row.deviceId,
|
||||
label: row.deviceName
|
||||
}
|
||||
}),
|
||||
currentDevice: currentDevice.deviceId,
|
||||
currentVolume,
|
||||
})
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className={styles.meeting}>
|
||||
|
|
@ -183,8 +210,8 @@ const Meeting: React.FC = () => {
|
|||
{list.map((item) =>
|
||||
<SwiperSlide key={item}>
|
||||
<div className={styles.meetingContentSwiperCard}>
|
||||
<video src="" className={styles.meetingContentSwiperCardVdeio} ></video>
|
||||
<div style={{ color: 'white', position: 'absolute', left: 0, top: 0 }}>{item}</div>
|
||||
<div className={styles.meetingContentSwiperCardVdeio}></div>
|
||||
{/* <div style={{ color: 'white', position: 'absolute', left: 0, top: 0 }}>{item}</div> */}
|
||||
{meetingContentUser()}
|
||||
</div>
|
||||
</SwiperSlide>
|
||||
|
|
@ -192,10 +219,8 @@ const Meeting: React.FC = () => {
|
|||
</Swiper>
|
||||
</div>
|
||||
<div className={`${styles.meetingContentVideo} drag`}>
|
||||
<div className={styles.meetingContentVideoDom} id='video1'></div>
|
||||
<div className={styles.meetingContentVideoDom} id='video2'></div>
|
||||
{/* <div className={styles.meetingContentVideoDom} id={videoID}></div> */}
|
||||
{/* {meetingContentUser()} */}
|
||||
<div className={styles.meetingContentVideoDom} id={videoID}></div>
|
||||
{meetingContentUser()}
|
||||
</div>
|
||||
</div>
|
||||
{
|
||||
|
|
@ -332,6 +357,109 @@ const Meeting: React.FC = () => {
|
|||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
<Modal title="设置向导" open={isStupWizard} footer={null} closable={false} centered width={'40vw'}>
|
||||
<div className={styles.stupWizard}>
|
||||
<div>
|
||||
<div>{stepsStatus ? '音频设置向导' : '视频测试'}</div>
|
||||
<div>
|
||||
<div>
|
||||
<span>音频输出设备:</span>
|
||||
<Select
|
||||
options={audioDeviceManager.currentDevices} style={{ flexGrow: 1 }}
|
||||
value={audioDeviceManager.currentDevice} onChange={(e) => {
|
||||
setAudioDeviceManager({
|
||||
...audioDeviceManager,
|
||||
currentDevice: e
|
||||
})
|
||||
window.electron.setRecordingDevice(e);
|
||||
getAudioMediaList()
|
||||
}} />;
|
||||
<audio src="" id='startAudio'></audio>
|
||||
</div>
|
||||
{stepsStatus ? <div>
|
||||
<span>调节声音大小:</span>
|
||||
<Slider min={0} max={255} value={audioDeviceManager.currentVolume} onChange={(e) => {
|
||||
setAudioDeviceManager({
|
||||
...audioDeviceManager,
|
||||
currentVolume: e
|
||||
})
|
||||
window.electron.setRecordingDeviceVolume(e)
|
||||
}} style={{ flexGrow: 1 }} />
|
||||
</div> :
|
||||
<div>
|
||||
<span>视频预览:</span>
|
||||
<video id='startPreview'
|
||||
poster={'/src/assets/error.png'}
|
||||
style={{ width: '226px', height: '136px', backgroundColor: 'black' }}>
|
||||
</video>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
{stepsStatus ? <div>
|
||||
<span>您可以对着麦克风说话,试听表克风的输入质量</span>
|
||||
<div>
|
||||
<img src="/src/assets/icon33.png" alt="" />
|
||||
<div>
|
||||
<img src="/src/assets/icon34.png" alt="" />
|
||||
<div id='recordingDeviceTest'>
|
||||
<img src="/src/assets/icon35.png" alt="" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> : null}
|
||||
</div>
|
||||
<div>
|
||||
{stepsStatus ? <div>
|
||||
<Button type="primary" className='m-ant-btn' onClick={() => {
|
||||
let audio = document.getElementById('startAudio') as any;
|
||||
if (audio.srcObject) {
|
||||
const tracks = audio.srcObject.getTracks();
|
||||
tracks.forEach((track: any) => {
|
||||
track.stop();
|
||||
});
|
||||
audio.srcObject = null;
|
||||
}
|
||||
setStepsStatus(false)
|
||||
window.electron.startPreview().then((res: boolean) => {
|
||||
setIsVideoLoad(res)
|
||||
})
|
||||
}}>下一步</Button>
|
||||
</div> :
|
||||
<div>
|
||||
<Button
|
||||
type="primary"
|
||||
style={{ backgroundColor: '#31353A', marginRight: '14px' }}
|
||||
onClick={() => {
|
||||
if (isVideoLoad) {
|
||||
setIsVideoLoad(false)
|
||||
window.electron.stopAudioDeviceLoopbackTest()
|
||||
setStepsStatus(true)
|
||||
window.electron.startRecordingDeviceTest(200)
|
||||
} else {
|
||||
message.error('视频加载中!')
|
||||
}
|
||||
}}
|
||||
>上一步</Button>
|
||||
<Button
|
||||
type="primary"
|
||||
className='m-ant-btn'
|
||||
onClick={() => {
|
||||
if (isVideoLoad) {
|
||||
window.electron.stopAudioDeviceLoopbackTest()
|
||||
window.electron.setRecordingDeviceVolume(audioDeviceManager.currentVolume)
|
||||
setIsStupWizard(false)
|
||||
setStepsStatus(true)
|
||||
setIsVideoLoad(false)
|
||||
} else {
|
||||
message.error('视频加载中!')
|
||||
}
|
||||
}}
|
||||
>完成
|
||||
</Button>
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
</Modal>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,13 +1,19 @@
|
|||
// electron-env.d.ts
|
||||
export interface IElectronAPI {
|
||||
getDesktopCapturerVideo: () => Promise<void>;
|
||||
setDesktopCapturerVideo: (data: any) => Promise<void>;
|
||||
getCameraAndMicrophoneMedia: () => Promise<void>;
|
||||
setDesktopCapturerVideo: (data: any) => void;
|
||||
setCameraCapture: (data: any) => void;
|
||||
getAudioMediaList: () => { currentDevice: any, currentDevices: any, currentVolume: number };
|
||||
setRecordingDeviceVolume: (volume: number) => void;
|
||||
setRecordingDevice: (deviceId: string) => void;
|
||||
setMainWindowSize: (config: any) => void;
|
||||
getIsMaximized: () => Promise<boolean>;
|
||||
setViewStatus: (status: 'quit' | 'maximize' | 'minimize' | 'unmaximize') => void;
|
||||
setJoinChannel: () => Promise<void>;
|
||||
getVideoId: () => string;
|
||||
startRecordingDeviceTest: (indicationInterval:number) => void;
|
||||
stopAudioDeviceLoopbackTest: () => void;
|
||||
startPreview: () => Promise<boolean>;
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
module.exports = {
|
||||
appid: "dcfc466a6ecb4a1f972630065dfb1e75",
|
||||
token: "007eJxTYNDz89yosT64YN5i3snT6nzY/aVOvs1Tmu3zc9r6qUkXHyxSYEhJTks2MTNLNEtNTjJJNEyzNDcyMzYwMDNNSUsyTDU3FQxuTmsIZGSQn/iShZEBAkF8bgZDc3MjYwMLU2MTMwYGAAHrH7M=",
|
||||
token: "007eJxTYOAzvBU4eaX8g2nNm16Yp0YZ6SzIVbXWteo/H1tr947n0jUFhpTktGQTM7NEs9TkJJNEwzRLcyMzYwMDM9OUtCTDVHPT9MD2tIZARobaiU4MjFAI4nMzGJqbGxkbWJgam5gxMAAA0L4e4A==",
|
||||
channelId: '17723085346',
|
||||
}
|
||||
|
|
@ -1,95 +0,0 @@
|
|||
// import AgoraRTC from "agora-rtc-sdk-ng"
|
||||
|
||||
// let rtcClient = null as any;
|
||||
|
||||
// const options = {
|
||||
// appId: "dcfc466a6ecb4a1f972630065dfb1e75",
|
||||
// channel: '17723085346',
|
||||
// token: "007eJxTYNDlkfJ9fD3lzh2e0KI5Oyy6vdU7phyIXOpV8F36/xPOeS8VGFKS05JNzMwSzVKTk0wSDdMszY3MjA0MzExT0pIMU81Np/g0pTUEMjJExEqyMjJAIIjPzWBobm5kbGBhamxixsAAAC6mH9k=",
|
||||
// uid: 'eaecab',
|
||||
// };
|
||||
|
||||
// rtcClient = AgoraRTC.createClient({ mode: "live", codec: "vp8" });
|
||||
|
||||
// // 以观众身份加入房间
|
||||
// export async function AudienceJoinChannel(channel: any, uid: string | number) {
|
||||
// await SetRule(1)
|
||||
// await rtcClient.join(options.appId, channel, options.token, uid)
|
||||
// }
|
||||
|
||||
// // 加入房间
|
||||
// export async function JoinChannel(channel: any, uid: string | number) {
|
||||
// await rtcClient.join(options.appId, channel, options.token, uid)
|
||||
// }
|
||||
|
||||
// // 设置用户角色 1=观众 2=主播
|
||||
// export async function SetRule(type: number) {
|
||||
// await rtcClient.setClientRole(type == 1 ? "audience" : "host");
|
||||
// }
|
||||
|
||||
// // 接流
|
||||
// export async function ReceiveFLow(flowHandld: any) {
|
||||
// rtcClient.on("user-published", async (user: any, mediaType: any) => {
|
||||
// await rtcClient.subscribe(user, mediaType);
|
||||
// console.log(user,'嘻嘻');
|
||||
|
||||
// flowHandld(user)
|
||||
// });
|
||||
// }
|
||||
|
||||
// // 远端取消推流
|
||||
// export function ChannelFlow(channelHandle: any) {
|
||||
// rtcClient.on("user-unpublished", (user: any) => {
|
||||
// channelHandle(user)
|
||||
// });
|
||||
// }
|
||||
|
||||
// // 离开频道
|
||||
// export function LeaveChannel() {
|
||||
// rtcClient.leave()
|
||||
// }
|
||||
|
||||
// // 发布本地音频轨道
|
||||
// export async function PublishAudio(deviceId: string) {
|
||||
// var audioTrack = await AgoraRTC.createMicrophoneAudioTrack({
|
||||
// AEC: true, // 是否开启回声消除
|
||||
// AGC: true, // 是否开启自动增益
|
||||
// ANS: true, // 是否开启噪声抑制
|
||||
// microphoneId: deviceId // 麦克风的设备 ID
|
||||
// })
|
||||
// await rtcClient.publish(audioTrack)
|
||||
// }
|
||||
|
||||
// // 发布本地视频轨道 硬件设备
|
||||
// export async function PublishVideo(deviceId: string) {
|
||||
// var videoTrack = await AgoraRTC.createCameraVideoTrack({
|
||||
// cameraId: deviceId,
|
||||
// encoderConfig: '1080p_3'
|
||||
// })
|
||||
// await rtcClient.publish(videoTrack)
|
||||
// }
|
||||
|
||||
// // 发布本地视频轨道 屏幕共享
|
||||
// export async function PublishVideoScreen(sharedScreenItem: any) {
|
||||
// var screenTrack = await AgoraRTC.createScreenVideoTrack({
|
||||
// encoderConfig: "1080p_1",
|
||||
// electronScreenSourceId: sharedScreenItem.id,
|
||||
// })
|
||||
// await rtcClient.publish(screenTrack)
|
||||
// }
|
||||
|
||||
// // 获取麦克风设备列表
|
||||
// export async function GetMicrophones() {
|
||||
// return await AgoraRTC.getMicrophones()
|
||||
// }
|
||||
|
||||
// // 获取摄像头设备列表
|
||||
// export async function GetCameras() {
|
||||
// return await AgoraRTC.getCameras()
|
||||
// }
|
||||
|
||||
// // 取消发布所有流
|
||||
// export async function UnpublishAll() {
|
||||
// await rtcClient.unpublish()
|
||||
// }
|
||||
|
||||
|
|
@ -170,3 +170,20 @@
|
|||
max-height: 70vh;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.ant-slider:hover .ant-slider-rail {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.ant-slider .ant-slider-rail {
|
||||
background-color: #D9D9D9;
|
||||
}
|
||||
|
||||
.ant-slider .ant-slider-track {
|
||||
background-color: #3672E9;
|
||||
}
|
||||
|
||||
.ant-slider .ant-slider-handle::after {
|
||||
background-color: #3672E9;
|
||||
box-shadow: 0 0 0 2px #3672E9;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
.ant-input{background-color:#28282C !important;border:1px solid #404145;color:white;box-sizing:border-box}.ant-input::placeholder{color:#E6E6E6}.ant-input-affix-wrapper{background-color:#28282C !important;border:1px solid #404145;box-sizing:border-box}.ant-input-affix-wrapper .ant-input{color:white !important}.ant-input-affix-wrapper .ant-input-password-icon{color:white !important}.m-ant-btn.ant-btn{background-color:#3F51B5;box-shadow:none}.m-ant-btn.ant-btn:hover{background-color:#606fc7 !important}.m-ant-btn.ant-btn:active{background-color:#32408f !important}.m-border-ant-button.ant-btn{border:1px solid #5575F2 !important;color:#5575F2 !important;background-color:#1E1E1F !important}.ant-checkbox-wrapper{color:#848484}.ant-checkbox-wrapper .ant-checkbox .ant-checkbox-inner{background-color:#28282C !important;border:1px solid #404145}.ant-checkbox-wrapper .ant-checkbox .ant-checkbox-inner::after{background-color:#3F51B5 !important}.ant-checkbox-wrapper .ant-checkbox-checked .ant-checkbox-inner{background-color:#3F51B5 !important;border:1px solid #404145}.ant-table{background-color:#1B1E24 !important;border-radius:0px !important}.ant-table .ant-table-header .ant-table-cell{background-color:#1B1E24;color:#808080;box-shadow:none;border-bottom:1px solid transparent}.ant-table .ant-table-header .ant-table-cell::before{visibility:hidden}.ant-table .ant-table-body .ant-table-row{background-color:#16191e;color:white}.ant-table .ant-table-body .ant-table-row .ant-table-cell{border-bottom:1px solid #292F3A}.ant-table .ant-table-body .ant-table-row-selected .ant-table-cell{background-color:#0d0f12 !important;color:white}.ant-table .ant-table-body .ant-table-cell-row-hover{background-color:#0d0f12 !important}.ant-pagination .ant-pagination-prev{margin-right:10px !important}.ant-pagination .ant-pagination-prev,.ant-pagination .ant-pagination-next{width:30px !important;height:30px !important;border-radius:50%;background:#20242C}.ant-pagination .ant-pagination-prev .anticon,.ant-pagination .ant-pagination-next .anticon{color:#808080}.ant-pagination .ant-pagination-item{width:30px !important;height:30px !important;line-height:30px !important;border-radius:50%;background:#20242C !important;margin-right:10px !important}.ant-pagination .ant-pagination-item:hover{background:#5575F2 !important;border:none;box-shadow:0px 0px 10px 0px #66C8FF}.ant-pagination .ant-pagination-item:hover a{color:black !important}.ant-pagination .ant-pagination-item-active{background:#5575F2 !important;border:none;box-shadow:0px 0px 10px 0px #66C8FF}.ant-pagination .ant-pagination-item-active a{color:black !important}.ant-popover:not(.ant-popconfirm) .ant-popover-arrow::before{background-color:#07090B !important}.ant-popover:not(.ant-popconfirm) .ant-popover-content .ant-popover-inner{background-color:#07090B}.ant-modal-mask{background-color:rgba(0,0,0,0.25) !important}.ant-modal .ant-modal-content{background-color:#07090B}.ant-modal .ant-modal-content .ant-modal-header{background-color:#07090B}.ant-modal .ant-modal-content .ant-modal-header .ant-modal-title{text-align:center;color:#EEEEEE;font-weight:bold}.ant-modal .ant-modal-content .ant-modal-body{max-height:70vh;overflow-y:auto}
|
||||
.ant-input{background-color:#28282C !important;border:1px solid #404145;color:white;box-sizing:border-box}.ant-input::placeholder{color:#E6E6E6}.ant-input-affix-wrapper{background-color:#28282C !important;border:1px solid #404145;box-sizing:border-box}.ant-input-affix-wrapper .ant-input{color:white !important}.ant-input-affix-wrapper .ant-input-password-icon{color:white !important}.m-ant-btn.ant-btn{background-color:#3F51B5;box-shadow:none}.m-ant-btn.ant-btn:hover{background-color:#606fc7 !important}.m-ant-btn.ant-btn:active{background-color:#32408f !important}.m-border-ant-button.ant-btn{border:1px solid #5575F2 !important;color:#5575F2 !important;background-color:#1E1E1F !important}.ant-checkbox-wrapper{color:#848484}.ant-checkbox-wrapper .ant-checkbox .ant-checkbox-inner{background-color:#28282C !important;border:1px solid #404145}.ant-checkbox-wrapper .ant-checkbox .ant-checkbox-inner::after{background-color:#3F51B5 !important}.ant-checkbox-wrapper .ant-checkbox-checked .ant-checkbox-inner{background-color:#3F51B5 !important;border:1px solid #404145}.ant-table{background-color:#1B1E24 !important;border-radius:0px !important}.ant-table .ant-table-header .ant-table-cell{background-color:#1B1E24;color:#808080;box-shadow:none;border-bottom:1px solid transparent}.ant-table .ant-table-header .ant-table-cell::before{visibility:hidden}.ant-table .ant-table-body .ant-table-row{background-color:#16191e;color:white}.ant-table .ant-table-body .ant-table-row .ant-table-cell{border-bottom:1px solid #292F3A}.ant-table .ant-table-body .ant-table-row-selected .ant-table-cell{background-color:#0d0f12 !important;color:white}.ant-table .ant-table-body .ant-table-cell-row-hover{background-color:#0d0f12 !important}.ant-pagination .ant-pagination-prev{margin-right:10px !important}.ant-pagination .ant-pagination-prev,.ant-pagination .ant-pagination-next{width:30px !important;height:30px !important;border-radius:50%;background:#20242C}.ant-pagination .ant-pagination-prev .anticon,.ant-pagination .ant-pagination-next .anticon{color:#808080}.ant-pagination .ant-pagination-item{width:30px !important;height:30px !important;line-height:30px !important;border-radius:50%;background:#20242C !important;margin-right:10px !important}.ant-pagination .ant-pagination-item:hover{background:#5575F2 !important;border:none;box-shadow:0px 0px 10px 0px #66C8FF}.ant-pagination .ant-pagination-item:hover a{color:black !important}.ant-pagination .ant-pagination-item-active{background:#5575F2 !important;border:none;box-shadow:0px 0px 10px 0px #66C8FF}.ant-pagination .ant-pagination-item-active a{color:black !important}.ant-popover:not(.ant-popconfirm) .ant-popover-arrow::before{background-color:#07090B !important}.ant-popover:not(.ant-popconfirm) .ant-popover-content .ant-popover-inner{background-color:#07090B}.ant-modal-mask{background-color:rgba(0,0,0,0.25) !important}.ant-modal .ant-modal-content{background-color:#07090B}.ant-modal .ant-modal-content .ant-modal-header{background-color:#07090B}.ant-modal .ant-modal-content .ant-modal-header .ant-modal-title{text-align:center;color:#EEEEEE;font-weight:bold}.ant-modal .ant-modal-content .ant-modal-body{max-height:70vh;overflow-y:auto}.ant-slider:hover .ant-slider-rail{background-color:#fff}.ant-slider .ant-slider-rail{background-color:#D9D9D9}.ant-slider .ant-slider-track{background-color:#3672E9}.ant-slider .ant-slider-handle::after{background-color:#3672E9;box-shadow:0 0 0 2px #3672E9}
|
||||
|
|
|
|||
|
|
@ -205,4 +205,28 @@ $pagination-hover-background-color: #5575F2;
|
|||
overflow-y: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Slider
|
||||
.ant-slider {
|
||||
&:hover {
|
||||
.ant-slider-rail {
|
||||
background-color: lighten(#D9D9D9, 100%);
|
||||
}
|
||||
}
|
||||
|
||||
.ant-slider-rail {
|
||||
background-color: #D9D9D9;
|
||||
}
|
||||
|
||||
.ant-slider-track {
|
||||
background-color: #3672E9;
|
||||
}
|
||||
|
||||
.ant-slider-handle {
|
||||
&::after {
|
||||
background-color: #3672E9;
|
||||
box-shadow: 0 0 0 2px #3672E9;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue