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

如何实现浏览器端录音并上传至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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.23 15:18:07