This commit is contained in:
parent
c9362fc14d
commit
b86c4230bb
|
|
@ -573,14 +573,14 @@ const Meeting: React.FC = () => {
|
||||||
const outputFilePath = mp4Path.replace('_beforehanlder',''); // 输出文件路径
|
const outputFilePath = mp4Path.replace('_beforehanlder',''); // 输出文件路径
|
||||||
const command = `${ffmpegPath} -i "${inputFilePath}" -vcodec copy -acodec copy "${outputFilePath}"`;
|
const command = `${ffmpegPath} -i "${inputFilePath}" -vcodec copy -acodec copy "${outputFilePath}"`;
|
||||||
|
|
||||||
exec(command, (error, stdout, stderr) => {
|
exec(command, (error:any, stdout:any, stderr:any) => {
|
||||||
if (error) {
|
if (error) {
|
||||||
console.error('Error executing ffmpeg command:', error);
|
console.error('Error executing ffmpeg command:', error);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除输入文件
|
// 删除输入文件
|
||||||
fs.unlink(inputFilePath, (err) => {
|
fs.unlink(inputFilePath, (err:any) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error('Error deleting input file:', err);
|
console.error('Error deleting input file:', err);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1065,77 +1065,70 @@ const Meeting: React.FC = () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
break;
|
break;
|
||||||
case '录制':
|
case '录制':
|
||||||
const setting = await JSON.parse(storage.getItem('setting') as string);
|
const setting = await JSON.parse(storage.getItem('setting') as string);
|
||||||
try {
|
try {
|
||||||
await fs.access(setting.recordingFilesPath, fs.constants.F_OK);
|
await fs.access(setting.recordingFilesPath, fs.constants.F_OK);
|
||||||
footerListTemplate[itemIndex][rowIndex].title = '录制中';
|
footerListTemplate[itemIndex][rowIndex].title = '录制中';
|
||||||
footerListTemplate[itemIndex][rowIndex].active = true;
|
footerListTemplate[itemIndex][rowIndex].active = true;
|
||||||
setFooterList(footerListTemplate);
|
setFooterList(footerListTemplate);
|
||||||
|
|
||||||
window.electron.getSources().then(async (sources: any) => {
|
window.electron.getSources().then(async (sources: any) => {
|
||||||
const screenId = sources[0].id;
|
const screenId = sources[0].id;
|
||||||
|
const stream = await navigator.mediaDevices.getUserMedia({
|
||||||
const stream = await navigator.mediaDevices.getUserMedia({
|
audio: {
|
||||||
audio: {
|
mandatory: {
|
||||||
mandatory: {
|
chromeMediaSource: 'desktop',
|
||||||
chromeMediaSource: 'desktop',
|
chromeMediaSourceId: screenId,
|
||||||
chromeMediaSourceId: screenId,
|
}
|
||||||
}
|
} as any,
|
||||||
},
|
video: {
|
||||||
video: {
|
mandatory: {
|
||||||
mandatory: {
|
chromeMediaSource: 'desktop',
|
||||||
chromeMediaSource: 'desktop',
|
chromeMediaSourceId: screenId,
|
||||||
chromeMediaSourceId: screenId,
|
}
|
||||||
}
|
} as any
|
||||||
|
});
|
||||||
|
// 获取所有音频输入设备
|
||||||
|
const devices = await navigator.mediaDevices.enumerateDevices();
|
||||||
|
const audioInputDevices = devices.filter(device => device.kind === 'audioinput' &&
|
||||||
|
device.deviceId !== 'default' &&
|
||||||
|
device.deviceId !== 'communications');
|
||||||
|
// 使用Web Audio API来捕获系统声音和麦克风声音,将它们合并到同一个MediaStream中。
|
||||||
|
const audioCtx = new (window.AudioContext || (window as any).webkitAudioContext)();
|
||||||
|
const systemSoundSource = audioCtx.createMediaStreamSource(stream);
|
||||||
|
const systemSoundDestination = audioCtx.createMediaStreamDestination();
|
||||||
|
systemSoundSource.connect(systemSoundDestination);
|
||||||
|
// 录制所有音频输入设备
|
||||||
|
audioInputDevices.forEach(async device => {
|
||||||
|
const micStream = await navigator.mediaDevices.getUserMedia({ audio: { deviceId: { exact: device.deviceId } } });
|
||||||
|
setMediaStream(micStream);
|
||||||
|
const micSoundSource = audioCtx.createMediaStreamSource(micStream);
|
||||||
|
micSoundSource.connect(systemSoundDestination);
|
||||||
|
})
|
||||||
|
// 合并音频流与视频流
|
||||||
|
const combinedSource = new MediaStream([...stream.getVideoTracks(), ...systemSoundDestination.stream.getAudioTracks()]);
|
||||||
|
// 开始录制
|
||||||
|
const mediaRecorder = new MediaRecorder(combinedSource, {
|
||||||
|
mimeType: 'video/webm;codecs=vp9,opus',
|
||||||
|
videoBitsPerSecond: 1.5e6,
|
||||||
|
});
|
||||||
|
setRecorder(mediaRecorder);
|
||||||
|
});
|
||||||
|
} catch (error: any) {
|
||||||
|
if (error.code === 'ENOENT') {
|
||||||
|
message.error({
|
||||||
|
content: <div>文件夹不存在 <span style={{ color: '#606fc7', cursor: 'pointer' }} onClick={() => {
|
||||||
|
stupWizardRef.current.changeModal(3);
|
||||||
|
}}>前往设置</span></div>
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
message.error(error);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
// 获取所有音频输入设备
|
break;
|
||||||
const devices = await navigator.mediaDevices.enumerateDevices();
|
|
||||||
const audioInputDevices = devices.filter(device => device.kind === 'audioinput' &&
|
|
||||||
device.deviceId !== 'default' &&
|
|
||||||
device.deviceId !== 'communications' );
|
|
||||||
|
|
||||||
// 使用Web Audio API来捕获系统声音和麦克风声音,将它们合并到同一个MediaStream中。
|
|
||||||
const audioCtx = new (window.AudioContext || window.webkitAudioContext)();
|
|
||||||
const systemSoundSource = audioCtx.createMediaStreamSource(stream);
|
|
||||||
const systemSoundDestination = audioCtx.createMediaStreamDestination();
|
|
||||||
systemSoundSource.connect(systemSoundDestination);
|
|
||||||
|
|
||||||
// 录制所有音频输入设备
|
|
||||||
audioInputDevices.forEach( async device=>{
|
|
||||||
const micStream = await navigator.mediaDevices.getUserMedia({ audio: { deviceId: { exact: device.deviceId } }});
|
|
||||||
const micSoundSource = audioCtx.createMediaStreamSource(micStream);
|
|
||||||
micSoundSource.connect(systemSoundDestination);
|
|
||||||
})
|
|
||||||
|
|
||||||
// 合并音频流与视频流
|
|
||||||
const combinedSource = new MediaStream([...stream.getVideoTracks(), ...systemSoundDestination.stream.getAudioTracks()]);
|
|
||||||
|
|
||||||
// 开始录制
|
|
||||||
const recorder = new MediaRecorder(combinedSource, {
|
|
||||||
mimeType: 'video/webm;codecs=vp9,opus',
|
|
||||||
videoBitsPerSecond: 1.5e6,
|
|
||||||
});
|
|
||||||
|
|
||||||
setMediaStream(combinedSource);
|
|
||||||
setRecorder(recorder);
|
|
||||||
});
|
|
||||||
} catch (error: any) {
|
|
||||||
if (error.code === 'ENOENT') {
|
|
||||||
message.error({
|
|
||||||
content: <div>文件夹不存在 <span style={{ color: '#606fc7', cursor: 'pointer' }} onClick={() => {
|
|
||||||
stupWizardRef.current.changeModal(3);
|
|
||||||
}}>前往设置</span></div>
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
message.error(error);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
case '录制中':
|
case '录制中':
|
||||||
footerListTemplate[itemIndex][rowIndex].title = '录制'
|
footerListTemplate[itemIndex][rowIndex].title = '录制'
|
||||||
footerListTemplate[itemIndex][rowIndex].active = false
|
footerListTemplate[itemIndex][rowIndex].active = false
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue