likes
comments
collection
share

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

作者站长头像
站长
· 阅读数 18

背景

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

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

工具

  • 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元素上,以便实时预览录音。
// 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
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组件,包括开始、暂停和停止录音的按钮。
<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事件。
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();
});
// 静音
function muteRecording() {
    if (audioTrack.current) {
        audioTrack.current.enabled = false; // 关闭音频轨道
        setIsMute(true);
        console.log("录音已静音");
    }
}
// 取消静音
function unmuteRecording() {
    if (audioTrack.current) {
        audioTrack.current.enabled = true; // 开启音频轨道
        setIsMute(false);
        console.log("取消静音");
    }
}
// 恢复录制
function resumeRecording() {
    if (isPause && mediaRecorder.current.state === "paused") {
        mediaRecorder.current.resume();
        setIsPause(false);
        wavesurferRef.current.play();
        timer.start();
        console.log("恢复录音...");
    }
}
// 暂停录制
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上,以便用户可以下载录音文件。
// 停止录制,并将录制的音频数据导出为 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