You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React按钮onClick中同时调用ReactMediaRecorder内置方法与自定义函数

问题原因

你外层自定义的startRecording、stopRecording方法,和render回调参数里组件提供的内置同名方法是完全独立的两个函数,你之前直接把外层自定义方法传给Controls组件,全程没有调用组件内置的录制控制方法,所以原生录制功能自然不会触发。

解决方案

只需要在你的自定义逻辑执行前后,主动调用组件提供的内置方法即可,两种实现方式可选:

方式1:内联组合(代码更简洁)

直接在给Controls传参时拼接自定义逻辑和内置方法调用:

function RecordAudio(props) {
  const isVideo = false; // 补充const避免污染全局变量

  return (
    <ReactMediaRecorder
      audio
      render={({ status, startRecording, stopRecording, previewStream, mediaBlobUrl }) => (
        <Row>
          {status === 'recording' ? (
            <AudioPreview stream={previewStream} />
          ) : (
            <audio src={mediaBlobUrl} controls autoPlay />
          )}
          <Controls
            status={status}
            startRecording={(evt) => {
              // 你的自定义逻辑
              console.log('start streaming');
              fetch('/api/stream/start', { method: 'post' }).then((response) => {
                console.log('stream requested');
              });
              // 调用组件内置的启动录制方法
              startRecording();
              // 如果你需要等接口返回后再启动录制,把startRecording()移到上面的then回调里即可
            }}
            stopRecording={(evt) => {
              // 你的自定义逻辑
              console.log('stop streaming');
              fetch('/api/stream/stop', { method: 'post' }).then((response) => {
                audioStreamer.stopStreaming();
                console.log('streaming ended');
              });
              // 调用组件内置的停止录制方法
              stopRecording();
            }}
            mediaBlobUrl={mediaBlobUrl}
          />
        </Row>
      )}
    />
  );
}

方式2:外层封装方法(逻辑复用性更高)

如果你的自定义逻辑需要在多处复用,可以单独封装成高阶函数,传入内置方法生成最终的事件处理函数:

function RecordAudio(props) {
  const isVideo = false;

  // 封装启动逻辑
  const wrapStart = (originalStart) => (evt) => {
    console.log('start streaming');
    fetch('/api/stream/start', { method: 'post' }).then((response) => {
      console.log('stream requested');
    });
    originalStart();
  };

  // 封装停止逻辑
  const wrapStop = (originalStop) => (evt) => {
    console.log('stop streaming');
    fetch('/api/stream/stop', { method: 'post' }).then((response) => {
      audioStreamer.stopStreaming();
      console.log('streaming ended');
    });
    originalStop();
  };

  return (
    <ReactMediaRecorder
      audio
      render={({ status, startRecording, stopRecording, previewStream, mediaBlobUrl }) => (
        <Row>
          {status === 'recording' ? (
            <AudioPreview stream={previewStream} />
          ) : (
            <audio src={mediaBlobUrl} controls autoPlay />
          )}
          <Controls
            status={status}
            startRecording={wrapStart(startRecording)}
            stopRecording={wrapStop(stopRecording)}
            mediaBlobUrl={mediaBlobUrl}
          />
        </Row>
      )}
    />
  );
}

内容的提问来源于stack exchange,提问作者jdog

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 18:54:03