如何实现浏览器端录音并上传至Django服务器?
浏览器端音频录制并上传Django服务器实现方案
一、前端音频录制与上传逻辑
使用浏览器原生MediaRecorder API实现音频录制,无需引入第三方库,示例代码如下:
<!-- 页面操作按钮 --> <button id="startBtn">开始录制</button> <button id="stopBtn" disabled>结束录制</button> <button id="uploadBtn" disabled>上传音频</button> <script> let mediaRecorder; let audioChunks = []; const startBtn = document.getElementById('startBtn'); const stopBtn = document.getElementById('stopBtn'); const uploadBtn = document.getElementById('uploadBtn'); // 开始录制 startBtn.addEventListener('click', async () => { const stream = await navigator.mediaDevices.getUserMedia({ audio: true }); mediaRecorder = new MediaRecorder(stream); mediaRecorder.ondataavailable = e => audioChunks.push(e.data); mediaRecorder.onstop = () => { // 录制结束生成Blob对象 const audioBlob = new Blob(audioChunks, { type: 'audio/webm' }); // 挂到全局对象上后续提交用 window.recordedAudio = audioBlob; }; mediaRecorder.start(); startBtn.disabled = true; stopBtn.disabled = false; }); // 结束录制 stopBtn.addEventListener('click', () => { mediaRecorder.stop(); mediaRecorder.stream.getTracks().forEach(track => track.stop()); stopBtn.disabled = true; uploadBtn.disabled = false; }); // 上传音频 uploadBtn.addEventListener('click', async () => { const formData = new FormData(); // 对应后端request.FILES里的key为audio formData.append('audio', window.recordedAudio, 'recorded_audio.webm'); // 发送请求,注意带CSRF Token const res = await fetch('/audio-analysis/', { method: 'POST', body: formData, headers: { 'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value } }); const result = await res.json(); console.log('上传结果', result); }); </script>
注意:如果你的页面是Django模板渲染的,需要在页面任意位置加入
{% csrf_token %}模板标签,用于生成CSRF Token供请求使用。
二、Django后端代码调整
你现有代码存在逻辑冲突:使用DRF的@api_view装饰器但返回页面渲染响应,上传接口更适合返回JSON格式响应,调整后代码如下:
from django.http import JsonResponse from rest_framework.decorators import api_view import os from django.conf import settings @api_view(['POST']) def audio_analysis(request): # 先校验是否上传了音频文件 if 'audio' not in request.FILES: return JsonResponse({'code': 400, 'msg': '未检测到上传的音频文件'}, status=400) audio_data = request.FILES['audio'] # 示例:保存音频文件到media目录 save_path = os.path.join(settings.MEDIA_ROOT, audio_data.name) with open(save_path, 'wb+') as f: for chunk in audio_data.chunks(): f.write(chunk) # 此处补充你的音频分析业务逻辑 # view content return JsonResponse({'code': 200, 'msg': '音频上传处理成功'})
同时需要在settings.py中添加媒体文件配置:
# 配置媒体文件存储路径 MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_URL = '/media/' # 可选:调整最大上传文件大小,默认是2.5M FILE_UPLOAD_MAX_MEMORY_SIZE = 10 * 1024 * 1024 # 10M
三、注意事项
- 前端提交FormData时不要手动设置
Content-Type请求头,由浏览器自动生成带分隔符的请求头即可,否则会导致后端无法解析文件 - 若前后端分离部署,需要安装
django-cors-headers包配置跨域规则,允许前端域名请求接口 - 生产环境需要补充文件校验逻辑:限制音频格式、文件大小,避免恶意文件上传带来的安全风险
内容的提问来源于stack exchange,提问作者Nicola Mezzale
相关产品推荐
相关产品推荐

