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

如何在Django后端从audio/mp4 Blob获取音频时长并限制为30秒

解决方案:无文件化获取音频时长并限制30秒

前端预校验(优先做,大幅减少后端压力)

在发送请求前先在前端完成时长校验,避免无效请求:

  • 方法1:直接追踪录制时长
    启动录制时记录时间戳,停止时计算时长差值,超过30秒直接拦截请求:
    let startTime;
    const mediaRecorder = new MediaRecorder(stream);
    
    mediaRecorder.start();
    startTime = Date.now();
    
    mediaRecorder.addEventListener('stop', () => {
      const duration = (Date.now() - startTime) / 1000;
      if (duration > 30) {
        alert('音频时长不能超过30秒');
        return;
      }
      // 发送Blob到后端
      const formData = new FormData();
      formData.append('audio', blob);
      fetch('/upload-audio/', { method: 'POST', body: formData });
    });
    
  • 方法2:用AudioContext解析精确时长
    若需要更精准的时长(比如处理已录制好的Blob),用AudioContext解码音频数据:
    async function checkAudioDuration(blob) {
      const arrayBuffer = await blob.arrayBuffer();
      const audioContext = new (window.AudioContext || window.webkitAudioContext)();
      const audioBuffer = await audioContext.decodeAudioData(arrayBuffer);
      return audioBuffer.duration;
    }
    
    // 使用示例
    checkAudioDuration(blob).then(duration => {
      if (duration > 30) {
        alert('音频时长不能超过30秒');
        return;
      }
      // 发送请求
    });
    

后端解析二进制数据(兜底校验,防止前端校验被绕过)

直接在内存中处理Blob二进制数据,无需写入文件即可计算时长:

处理WAV格式(推荐,可配置MediaRecorder录制为WAV)

用Python内置wave模块结合BytesIO解析:

from django.http import JsonResponse
from io import BytesIO
import wave

def upload_audio(request):
    if request.method == 'POST':
        audio_blob = request.FILES['audio'].read()
        # 内存中解析WAV头信息
        try:
            with wave.open(BytesIO(audio_blob), 'rb') as wav_file:
                frames = wav_file.getnframes()
                sample_rate = wav_file.getframerate()
                duration = frames / sample_rate
                if duration > 30:
                    return JsonResponse({'error': '音频时长不能超过30秒'}, status=400)
                # 存入BinaryField
                # your_model_instance.audio_data = audio_blob
                # your_model_instance.save()
                return JsonResponse({'success': True})
        except wave.Error:
            return JsonResponse({'error': '无效的WAV文件'}, status=400)

处理WebM格式(前端默认录制格式)

若前端录制的是WebM,用pydub库(需依赖FFmpeg)在内存中解析:

from django.http import JsonResponse
from io import BytesIO
from pydub import AudioSegment

def upload_audio(request):
    if request.method == 'POST':
        audio_blob = request.FILES['audio'].read()
        try:
            audio = AudioSegment.from_file(BytesIO(audio_blob), format='webm')
            duration = audio.duration_seconds
            if duration > 30:
                return JsonResponse({'error': '音频时长不能超过30秒'}, status=400)
            # 存入BinaryField
            # your_model_instance.audio_data = audio_blob
            # your_model_instance.save()
            return JsonResponse({'success': True})
        except Exception as e:
            return JsonResponse({'error': f'解析音频失败: {str(e)}'}, status=400)

额外提示

  • 前端尽量配置MediaRecorder录制WAV,降低后端解析复杂度:
    const mediaRecorder = new MediaRecorder(stream, { mimeType: 'audio/wav' });
    
  • 后端校验必须保留,防止前端校验被篡改或绕过。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 05:50:51