构建高效、跨平台的录音软件——基于Electron、webrtc和React的完美结合

背景

在现代科技日益发展的今天,我们的电脑和手机设备能够完成许多日常任务,其中之一就是录音。无论是进行会议记录、语音备忘录还是创作音乐,录音是我们生活中经常用到的功能之一。本文将介绍如何使用ElectronwebrtcReact搭建一个高效、跨平台的录音软件,帮助使用者轻松完成各种录音任务。

工具

  • electron
  • react
  • antd
  • webrtc

Electron和React介绍

ElectronReact的协同 Electron是一个基于ChromiumNode.js的开发框架,用于构建跨平台的桌面应用程序。通过与React的结合,可以轻松实现复杂的用户界面和交互体验,既能满足用户需求,又能提高开发效率。因此,将ElectronReact应用于录音软件的开发中,能够为用户提供更好的体验,并且从开发者角度来看,更加便捷和高效。

webrtc介绍

WebRTC技术的应用 WebRTC是一项用于浏览器之间实时通信的开放性标准,它提供了音频、视频和数据传输的能力,适用于广泛的应用场景。在录音软件中,我们可以借助WebRTC技术实现实时录音功能,并且支持在线分享和协作。用户可以通过网页链接,将录音内容分享给其他人,并实现实时的在线播放和评论,极大地提高了录音的灵活性和可用性。

实现

要在WebRTCReact中实现录音功能,我们可以按照以下步骤进行:

步骤一:设置WebRTC音频流

  1. 导入getUserMedia函数,这是一个WebRTC提供的用于获取音频和视频流的函数。
  2. 使用getUserMedia函数请求用户授权获取音频流,并将其保存在React组件中的状态中。
  3. 将音频流绑定到HTML5的audiovideo元素上,以便实时预览录音。
js 复制代码
// html
<div
        className={`${styles.recordAudio} ${
                window.isElectron ? styles.electron : styles.web
        }`}
>
        <div className="timer">
                <Timer
                        seconds={timer.seconds}
                        minutes={timer.minutes}
                        hours={timer.hours}
                />
        </div>
        <Wavesurfer ref={wavesurferRef} />
</div>
js 复制代码
// js
const wavesurferRef = useRef<any>(); // 音波图对象
const mediaStream = useRef<MediaStream>(); //媒体流对象
const mediaRecorder = useRef<MediaRecorder>(); // 媒体录制器对象
const recordedChunks = useRef<Blob[]>([]); // 存储录制的音频数据
const audioTrack = useRef<any>(); // 音频轨道对象
const [isPause, setIsPause] = useState(false); // 标记是否暂停
const [isRecording, setIsRecording] = useState(false); // 标记是否正在录制
const [isMute, setIsMute] = useState(false); // 标记是否静音

function startRecording() {
    navigator.mediaDevices
        .getUserMedia({ audio: true })
        .then((stream) => {
                mediaStream.current = stream;
                audioTrack.current = stream.getAudioTracks()[0];
                audioTrack.current.enabled = true; // 开启音频轨道
                mediaRecorder.current = new MediaRecorder(stream);
                mediaRecorder.current.start();
                setIsRecording(true);
                wavesurferRef.current.play();
                timer.start();
                console.log("开始录音...");
        })
        .catch((error) => {
                console.error("无法获取麦克风权限:", error);
        });
}

步骤二:录音控制

  1. 创建React组件,包括开始、暂停和停止录音的按钮。
js 复制代码
<div className="recorderTools">
    <Button
            shape="circle"
            icon={<BsTrash />}
            className="toolbarIcon resetBtn"
            title="删除"
            disabled={!isRecording}
            onClick={stopRecording}
    />
    {isRecording ? (
            <Button
                    danger
                    type="primary"
                    shape="circle"
                    icon={<BsCheckLg />}
                    className="toolbarIcon stopBtn"
                    title="保存"
                    disabled={!isRecording}
                    onClick={saveRecording}
            />
    ) : (
            <Button
                    danger
                    type="primary"
                    shape="circle"
                    icon={<BsRecordFill />}
                    className="toolbarIcon playBtn"
                    title="开始"
                    onClick={startRecording}
            />
    )}

    {isPause ? (
            <Button
                    type="primary"
                    shape="circle"
                    icon={<BsPlayFill />}
                    className="toolbarIcon resumeBtn"
                    title="继续"
                    disabled={!isRecording}
                    onClick={resumeRecording}
            />
    ) : (
            <Button
                    type="primary"
                    shape="circle"
                    icon={<BsPauseFill />}
                    className="toolbarIcon pauseBtn"
                    title="暂停"
                    disabled={!isRecording}
                    onClick={pauseRecording}
            />
    )}
</div>
  1. 使用MediaRecorder接口,它是WebRTC提供的用于录制音频和视频的接口。
  2. 在开始录音按钮的点击事件中,创建一个新的MediaRecorder实例,将音频流作为输入。
  3. 定义录音的文件格式和音频编码等设置。
  4. 绑定ondataavailableonstop事件监听器,分别处理录制过程中的音频数据和录制结束时的操作。
  5. 在停止录音按钮的点击事件中,调用stop方法停止录音,并触发onstop事件。
js 复制代码
mediaRecorder.current = new MediaRecorder(stream);
mediaRecorder.current.addEventListener("dataavailable", (e) => {
    if (e.data.size > 0) {
        recordedChunks.current.push(e.data);
    }
});
mediaRecorder.current.addEventListener("stop", () => {
    isSave.current && exportRecording();
});
js 复制代码
// 静音
function muteRecording() {
    if (audioTrack.current) {
        audioTrack.current.enabled = false; // 关闭音频轨道
        setIsMute(true);
        console.log("录音已静音");
    }
}
js 复制代码
// 取消静音
function unmuteRecording() {
    if (audioTrack.current) {
        audioTrack.current.enabled = true; // 开启音频轨道
        setIsMute(false);
        console.log("取消静音");
    }
}
js 复制代码
// 恢复录制
function resumeRecording() {
    if (isPause && mediaRecorder.current.state === "paused") {
        mediaRecorder.current.resume();
        setIsPause(false);
        wavesurferRef.current.play();
        timer.start();
        console.log("恢复录音...");
    }
}
js 复制代码
// 暂停录制
function pauseRecording() {
    if (!isPause && mediaRecorder.current.state === "recording") {
        mediaRecorder.current.pause();
        setIsPause(true);
        wavesurferRef.current.pause();
        timer.pause();
        console.log("录音已暂停");
    }
}

步骤三:保存和导出录音文件

  1. onstop事件中,将录音数据存储在React组件的状态中。
  2. 添加保存和导出按钮,用于将录音保存成文件或导出为其他格式。
  3. 在保存按钮的点击事件中,将录音数据转换成Blob对象,并使用URL.createObjectURL生成文件的URL。
  4. 可以使用<a>标签的download属性,将URL绑定到href上,以便用户可以下载录音文件。
js 复制代码
// 停止录制,并将录制的音频数据导出为 Blob 对象
function stopRecording() {
    if (isRecording) {
            mediaRecorder.current.stop();
            mediaStream.current?.getTracks().forEach((track) => track.stop());
            setIsRecording(false);
            timer.reset(null, false);
            wavesurferRef.current.reset();
            recordedChunks.current = [];
            console.log("录音完成!");
    }
}
// 导出录制的音频文件
function saveRecording() {
    stopRecording();
    isSave.current = true;
}

// 导出录制的音频文件
function exportRecording() {
    if (recordedChunks.current.length > 0) {
            const blob = new Blob(recordedChunks.current, { type: "audio/webm" });
            const url = URL.createObjectURL(blob);
            if (window.electronAPI) {
                    window.electronAPI.sendRaDownloadRecord(url);
            } else {
                    const link = document.createElement("a");
                    link.href = url;
                    link.download = `pear-rec_${+new Date()}.webm`;
                    link.click();
                    recordedChunks.current = [];
                    isSave.current = false;
            }
    }
}

需要注意的是,WebRTC和React只提供了录音的底层功能,如获取音频流、录音和编码等,而录音软件的具体界面设计和逻辑控制需要根据实际需求进行开发。同时,为了确保在不同浏览器和平台上的兼容性,可能需要进行一些浏览器特定的处理和适配。

总结

通过ElectronWebRTCReact的结合,我们可以构建一款创新的录音软件,将实时录音和在线分享功能融入其中,为用户提供更加灵活且高品质的录音体验。同时,开发者也可以享受ElectronReact带来的开发效率和便捷性。我们相信,这样的录音软件将成为用户录音需求的最佳解决方案,并推动录音领域的进一步创新。

Q&A

  • Q: 有源码吗?

当然有,地址如下:github.com/027xiguapi/...,有兴趣的话可以大家一起探讨,同时也欢迎大家forkstar

相关推荐
前端大卫24 分钟前
Vue3 + Element-Plus 自定义虚拟表格滚动实现方案【附源码】
前端
却尘39 分钟前
Next.js 请求最佳实践 - vercel 2026一月发布指南
前端·react.js·next.js
ccnocare40 分钟前
浅浅看一下设计模式
前端
Lee川44 分钟前
🎬 从标签到屏幕:揭秘现代网页构建与适配之道
前端·面试
Ticnix1 小时前
ECharts初始化、销毁、resize 适配组件封装(含完整封装代码)
前端·echarts
纯爱掌门人1 小时前
终焉轮回里,藏着 AI 与人类的答案
前端·人工智能·aigc
twl1 小时前
OpenClaw 深度技术解析
前端
崔庆才丨静觅1 小时前
比官方便宜一半以上!Grok API 申请及使用
前端
星光不问赶路人1 小时前
vue3使用jsx语法详解
前端·vue.js
天蓝色的鱼鱼2 小时前
shadcn/ui,给你一个真正可控的UI组件库
前端