如何使用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,调用浏览器原生的MediaRecorderAPI直接在客户端获取麦克风音频,完全绕过服务器设备。 - 自动停止与下载:点击按钮后启动录音,5秒后自动停止,生成WAV格式文件并触发客户端下载。
- 可选服务器保存:将音频转为Base64格式传递给Python回调,解码后保存到服务器指定路径,不需要的话可移除对应代码块。
- 状态反馈:实时更新页面文本,告知用户录音进度、结果或错误信息。
注意事项
- 首次使用时,浏览器会请求麦克风访问权限,用户需要允许。
- 主流浏览器均支持
MediaRecorderAPI,若遇到兼容性问题,可调整音频格式参数。
内容的提问来源于stack exchange,提问作者user3668129
相关产品推荐
相关产品推荐

