From 1da838f568338ed126caa617d5b8e3aba69e5952 Mon Sep 17 00:00:00 2001
From: yj <1336058017@qq.com>
Date: Fri, 27 Sep 2024 15:36:50 +0800
Subject: [PATCH 1/4] =?UTF-8?q?=E5=BD=95=E5=88=B6=E8=A7=86=E9=A2=91?=
=?UTF-8?q?=E4=BB=A3=E7=A0=81=E5=9B=9E=E6=98=BE?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
main.js | 56 ---------------------------
src/page/Meeting/index.tsx | 79 ++++++++++++--------------------------
2 files changed, 25 insertions(+), 110 deletions(-)
diff --git a/main.js b/main.js
index 5a92cf7..4609203 100644
--- a/main.js
+++ b/main.js
@@ -12,7 +12,6 @@ const {
} = require('electron');
const path = require('node:path')
const fs = require('fs');
-const https = require('https');
const Registry = require('winreg');
const { autoUpdater, CancellationToken } = require('electron-updater');
const cancellationToken = new CancellationToken()
@@ -300,24 +299,6 @@ app.on('ready', () => {
})
});
});
- // 监听渲染进程请求应用数据目录
- ipcMain.handle('get-user-data-path', () => {
- return app.getPath('userData');
- });
- // 用户数据目录路径
- const userDataPath = app.getPath('userData'); // 全局变量
- console.log('User Data Path:', userDataPath);
- // 检查并下载 ffmpeg
- checkAndDownloadFFmpeg(userDataPath)
- .then(() => {
- console.log('FFmpeg is ready for use.');
- // 在这里执行任何依赖于 ffmpeg 的操作
- })
- .catch(error => {
- console.error('Failed to ensure ffmpeg is available:', error);
- app.quit();
- });
-
}
});
// 检测更新,在你想要检查更新的时候执行,renderer事件触发后的操作自行编写
@@ -386,40 +367,3 @@ function cancleDownloadUpdate() {
function quitAndInstall() {
autoUpdater.quitAndInstall();
}
-
-// 下载文件
-function downloadFile(url, dest) {
- return new Promise((resolve, reject) => {
- const file = fs.createWriteStream(dest);
- https.get(url, function (response) {
- response.pipe(file);
- file.on('finish', function () {
- file.close(resolve);
- });
- }).on('error', function (err) {
- fs.unlink(dest, () => reject(err));
- });
- });
-}
-
-// 检查并下载ffmpeg
-function checkAndDownloadFFmpeg(appPath) {
- const ffmpegPath = path.join(appPath, 'ffmpeg.exe');
- return new Promise((resolve, reject) => {
- if (!fs.existsSync(ffmpegPath)) {
- console.log(`ffmpeg.exe not found at ${ffmpegPath}, downloading...`);
- downloadFile('https://meeting-api.23544.com/meeting/update/ffmpeg.exe', ffmpegPath)
- .then(() => {
- console.log('ffmpeg.exe downloaded successfully.');
- resolve();
- })
- .catch(error => {
- console.error('Error downloading ffmpeg.exe:', error);
- reject(error);
- });
- } else {
- console.log(`ffmpeg.exe found at ${ffmpegPath}.`);
- resolve();
- }
- });
-}
\ No newline at end of file
diff --git a/src/page/Meeting/index.tsx b/src/page/Meeting/index.tsx
index dd3dfe0..4af1721 100644
--- a/src/page/Meeting/index.tsx
+++ b/src/page/Meeting/index.tsx
@@ -21,8 +21,7 @@ import StupWizard from '@/components/StupWizard';
import EquipmentManagement from '@/components/EquipmentManagement';
import UserVideo from '@/components/UserVideo';
import { role } from '@/config/role';
-const { ipcRenderer } = require('electron');
-import * as path from 'path';
+import { fixWebmDuration } from "webm-duration-fix-buffer";
const { confirm } = Modal;
const { exec } = require('child_process');
const fs = require('fs').promises;
@@ -563,60 +562,32 @@ const Meeting: React.FC = () => {
useEffect(() => {
if (recorder) {
recorder.start();
- recorder.ondataavailable = (event: any) => {
- const blob = new Blob([event.data], {
- type: 'video/webm',
- });
+ recorder.ondataavailable = async (event: any) => {
+ const blob = await fixWebmDuration(event.data);
const reader = new FileReader() as any;
reader.onload = async () => {
- try {
- const userDataPath = await ipcRenderer.invoke('get-user-data-path');
- // 获取当前日期并格式化
- const date = new Date();
- const year = date.getFullYear();
- const month = date.getMonth() + 1; // JavaScript月份从0开始
- const day = date.getDate();
- const hours = date.getHours();
- const minutes = date.getMinutes();
- const formattedDate = `${year}年${month}月${day}日${hours}时${minutes}分`;
- const setting = await JSON.parse(storage.getItem('setting') as string)
- const buffer = Buffer.from(reader.result);
- const mp4Path = `${setting.recordingFilesPath}会议录制_${state.roomName}_${state.channelId}_${formattedDate}_beforehanlder.mp4`;
- await fs.writeFile(mp4Path, buffer);
- // 获取应用程序安装路径
- const ffmpegPath = path.join(userDataPath, "ffmpeg.exe");
- const inputFilePath = mp4Path; // 输入文件路径
- const outputFilePath = mp4Path.replace('_beforehanlder', ''); // 输出文件路径
- const command = `${ffmpegPath} -i "${inputFilePath}" -vcodec copy -acodec copy "${outputFilePath}"`;
- exec(command, (error: any, _stdout: any, _stderr: any) => {
- if (error) {
- return;
+ const setting = await JSON.parse(storage.getItem('setting') as string)
+ const buffer = Buffer.from(reader.result);
+ await fs.writeFile(`${setting.recordingFilesPath}会议录制_${state.roomName}_${state.channelId}_${+new Date()}.webm`, buffer, {});
+ confirm({
+ title: '提示',
+ icon: ,
+ content: `录制成功!文件已保存至:${setting.recordingFilesPath}`,
+ centered: true,
+ okText: '打开文件夹',
+ cancelText: '关闭',
+ async onOk() {
+ await fs.access(setting.recordingFilesPath, fs.constants.F_OK);
+ if (process.platform === 'win32') {
+ exec(`explorer "${setting.recordingFilesPath}"`);
+ } else if (process.platform === 'darwin') {
+ exec(`open "${setting.recordingFilesPath}"`);
}
- // 删除输入文件
- fs.unlink(inputFilePath);
- confirm({
- title: '提示',
- icon: ,
- content: `录制成功!文件已保存至:${setting.recordingFilesPath}`,
- centered: true,
- okText: '打开文件夹',
- cancelText: '关闭',
- async onOk() {
- await fs.access(setting.recordingFilesPath, fs.constants.F_OK);
- if (process.platform === 'win32') {
- exec(`explorer "${setting.recordingFilesPath}"`);
- } else if (process.platform === 'darwin') {
- exec(`open "${setting.recordingFilesPath}"`);
- }
- },
- onCancel() {
- }
- })
- });
- } catch (err) {
-
- }
- }
+ },
+ onCancel() {
+ }
+ })
+ };
reader.readAsArrayBuffer(blob);
}
};
@@ -748,7 +719,7 @@ const Meeting: React.FC = () => {
setCurrentEffective(0)
break;
default:
- setCurrentEffective(storage.getItem('reconnect') =='true'? 4 : 0)
+ setCurrentEffective(storage.getItem('reconnect') === 'true' ? 4 : 0)
break;
}
}
From 72a42c8836a32d6f64c48515184007f3a757b7eb Mon Sep 17 00:00:00 2001
From: yj <1336058017@qq.com>
Date: Fri, 27 Sep 2024 15:57:57 +0800
Subject: [PATCH 2/4] =?UTF-8?q?=E6=96=87=E4=BB=B6=E5=90=8D=E4=BC=98?=
=?UTF-8?q?=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/page/Meeting/index.tsx | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/src/page/Meeting/index.tsx b/src/page/Meeting/index.tsx
index 5316514..efff682 100644
--- a/src/page/Meeting/index.tsx
+++ b/src/page/Meeting/index.tsx
@@ -568,7 +568,8 @@ const Meeting: React.FC = () => {
reader.onload = async () => {
const setting = await JSON.parse(storage.getItem('setting') as string)
const buffer = Buffer.from(reader.result);
- await fs.writeFile(`${setting.recordingFilesPath}会议录制_${state.roomName}_${state.channelId}_${+new Date()}.webm`, buffer, {});
+ const mp4Path = `${setting.recordingFilesPath}会议录制_${state.roomName}_${state.channelId}_${dayjs().format('YYYY年MM月DD日HH时mm分')}.webm`;
+ await fs.writeFile(mp4Path, buffer, {});
confirm({
title: '提示',
icon: ,
From 932d8e82856082a58321bcfab683bded45be4070 Mon Sep 17 00:00:00 2001
From: yj <1336058017@qq.com>
Date: Fri, 27 Sep 2024 16:11:07 +0800
Subject: [PATCH 3/4] =?UTF-8?q?=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/page/Meeting/index.tsx | 29 +++++++++++++++++------------
1 file changed, 17 insertions(+), 12 deletions(-)
diff --git a/src/page/Meeting/index.tsx b/src/page/Meeting/index.tsx
index efff682..27c8ee6 100644
--- a/src/page/Meeting/index.tsx
+++ b/src/page/Meeting/index.tsx
@@ -160,7 +160,7 @@ const Meeting: React.FC = () => {
const [noViewChatList, setNoViewChatList] = useState(0)
const [currentLookUserAccount, setCurrentLookUserAccount] = useState('')
const [recorder, setRecorder] = useState('')
- const [mediaStream, setMediaStream] = useState('')
+ const [_mediaStream, setMediaStream] = useState('')
const [isShare, setIsShare] = useState(null)
const [isSharePopConfirm, setIsSharePopConfirm] = useState(false)
const [isShareUser, setIsShareUser] = useState(null)
@@ -570,6 +570,8 @@ const Meeting: React.FC = () => {
const buffer = Buffer.from(reader.result);
const mp4Path = `${setting.recordingFilesPath}会议录制_${state.roomName}_${state.channelId}_${dayjs().format('YYYY年MM月DD日HH时mm分')}.webm`;
await fs.writeFile(mp4Path, buffer, {});
+ setRecorder('')
+ setMediaStream('')
confirm({
title: '提示',
icon: ,
@@ -1071,7 +1073,6 @@ const Meeting: React.FC = () => {
footerListTemplate[itemIndex][rowIndex].title = '录制中';
footerListTemplate[itemIndex][rowIndex].active = true;
setFooterList(footerListTemplate);
-
window.electron.getSources().then(async (sources: any) => {
const screenId = sources[0].id;
const stream = await navigator.mediaDevices.getUserMedia({
@@ -1167,16 +1168,20 @@ const Meeting: React.FC = () => {
}
// 停止录制
const stopRecorderMedia = async (): Promise => {
- if (recorder) {
- await recorder.stop();
- }
- if (mediaStream) {
- await mediaStream.getTracks().forEach((track: any) => {
- track.stop()
- });
- }
- setRecorder('')
- setMediaStream('')
+ setRecorder((res: any) => {
+ if (res) {
+ res.stop();
+ }
+ return res
+ })
+ setMediaStream((res: any) => {
+ if (res) {
+ res.getTracks().forEach((track: any) => {
+ track.stop()
+ });
+ }
+ return res
+ })
}
// 退出房间
const leaveChannel = async (bool: boolean = true): Promise => {
From 88c19a327daed4c3a4d12c1d1d58dec5b5598bd0 Mon Sep 17 00:00:00 2001
From: yj <1336058017@qq.com>
Date: Fri, 27 Sep 2024 16:41:42 +0800
Subject: [PATCH 4/4] =?UTF-8?q?=E4=BC=98=E5=8C=96?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
src/page/Meeting/index.tsx | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/page/Meeting/index.tsx b/src/page/Meeting/index.tsx
index 27c8ee6..2e66fb9 100644
--- a/src/page/Meeting/index.tsx
+++ b/src/page/Meeting/index.tsx
@@ -1193,11 +1193,13 @@ const Meeting: React.FC = () => {
} catch (error) {
}
await agora.leaveChannel()
- if (user.isAnonymous) {
- storage.setItem('userLogin', false)
- } else {
- navigate('/home/index')
- }
+ setTimeout(() => {
+ if (user.isAnonymous) {
+ storage.setItem('userLogin', false)
+ } else {
+ navigate('/home/index')
+ }
+ }, 0)
}
// 分享屏幕
const clickSharedScreen = async (): Promise => {