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

如何使用Dash应用录制客户端麦克风音频为WAV文件?

解决Dash客户端麦克风录音问题

问题根源

你当前的代码里,record_from_mic()函数运行在服务器端的Python环境中,调用的是服务器的麦克风设备,完全无法获取客户端的音频。要实现客户端录音,必须借助浏览器提供的Web API(MediaRecorder),用前端JavaScript代码处理录音逻辑。

实现方案

下面是完整的可运行Dash应用代码,通过嵌入JavaScript实现客户端录音:点击按钮后录制5秒音频,完成后自动生成WAV文件供客户端下载,同时支持将音频上传到服务器保存(可选)。

import dash
from dash import html, Output, Input
from dash.exceptions import PreventUpdate

app = dash.Dash(__name__)

app.layout = html.Div([
    html.Button('Start Recording', id='record-button', n_clicks=0),
    html.Div(id='recording-status', style={'margin-top': '10px'}),
    # 用于传递音频数据到服务器的隐藏元素(可选)
    html.Div(id='audio-data', style={'display': 'none'})
])

# 可选:将客户端录音上传到服务器保存
@app.callback(
    Output('recording-status', 'children'),
    Input('audio-data', 'children'),
    prevent_initial_call=True
)
def save_audio_to_server(audio_base64):
    if not audio_base64:
        raise PreventUpdate
    
    # 解码base64音频数据并保存为WAV文件
    import base64
    from io import BytesIO
    
    audio_data = audio_base64.split(',')[1]
    wav_bytes = base64.b64decode(audio_data)
    with open('/home/user/Downloads/client_recording.wav', 'wb') as f:
        f.write(wav_bytes)
    
    return '录音已保存到服务器'

# 客户端JavaScript处理录音逻辑
app.clientside_callback(
    """
    function(n_clicks) {
        if (n_clicks === 0) {
            window.recorder = null;
            window.audioChunks = [];
            return '';
        }
        
        const statusEl = document.getElementById('recording-status');
        const button = document.getElementById('record-button');
        
        // 切换录音状态:停止正在进行的录音
        if (window.recorder && window.recorder.state === 'recording') {
            window.recorder.stop();
            button.textContent = 'Start Recording';
            statusEl.textContent = '正在处理音频...';
            return '';
        }
        
        // 开始录音流程
        button.textContent = 'Stop Recording';
        statusEl.textContent = '正在录音(5秒后自动停止)';
        
        // 请求麦克风权限并初始化MediaRecorder
        navigator.mediaDevices.getUserMedia({ audio: true })
            .then(stream => {
                window.recorder = new MediaRecorder(stream);
                window.audioChunks = [];
                
                // 收集录音数据
                window.recorder.ondataavailable = event => {
                    window.audioChunks.push(event.data);
                };
                
                // 录音停止后的处理
                window.recorder.onstop = () => {
                    const audioBlob = new Blob(window.audioChunks, { type: 'audio/wav' });
                    const audioUrl = URL.createObjectURL(audioBlob);
                    
                    // 自动生成下载链接,触发客户端下载
                    const downloadLink = document.createElement('a');
                    downloadLink.href = audioUrl;
                    downloadLink.download = 'client_recording.wav';
                    downloadLink.click();
                    
                    // 可选:将音频转为base64传递给服务器
                    const reader = new FileReader();
                    reader.onload = () => {
                        document.getElementById('audio-data').textContent = reader.result;
                    };
                    reader.readAsDataURL(audioBlob);
                    
                    statusEl.textContent = '录音完成,已生成WAV文件';
                    // 关闭麦克风流
                    stream.getTracks().forEach(track => track.stop());
                };
                
                window.recorder.start();
                
                // 5秒后自动停止录音
                setTimeout(() => {
                    if (window.recorder && window.recorder.state === 'recording') {
                        window.recorder.stop();
                        button.textContent = 'Start Recording';
                    }
                }, 5000);
            })
            .catch(err => {
                statusEl.textContent = `录音失败:${err.message}`;
                button.textContent = 'Start Recording';
            });
            
        return '';
    }
    """,
    Output('recording-status', 'children'),
    Input('record-button', 'n_clicks'),
    prevent_initial_call=True
)

if __name__ == '__main__':
    app.run_server(debug=False, host='0.0.0.0')

关键说明

  • 客户端录音核心:通过clientside_callback嵌入JavaScript,调用浏览器原生的MediaRecorder API直接在客户端获取麦克风音频,完全绕过服务器设备。
  • 自动停止与下载:点击按钮后启动录音,5秒后自动停止,生成WAV格式文件并触发客户端下载。
  • 可选服务器保存:将音频转为Base64格式传递给Python回调,解码后保存到服务器指定路径,不需要的话可移除对应代码块。
  • 状态反馈:实时更新页面文本,告知用户录音进度、结果或错误信息。

注意事项

  • 首次使用时,浏览器会请求麦克风访问权限,用户需要允许。
  • 主流浏览器均支持MediaRecorder API,若遇到兼容性问题,可调整音频格式参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 19:45:00