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

Django网站音频在iPhone/iPad无法播放问题求助

问题分析与修复方案

你的问题核心是MediaRecorder并未生成真正的MP3格式音频。虽然你手动将Blob的type设为audio/mp3并命名为audio.mp3,但实际上浏览器的MediaRecorder默认输出的是WebM(Opus编码)或WAV格式——这些格式被强行标记为MP3后,iOS Safari无法正确识别解析,导致播放失败。


修复方案1:前端录制通用格式,后端转标准MP3

这是兼容性最强的方案,后端转换能确保生成全设备支持的标准MP3文件。

前端代码修改

放弃强行指定MP3类型,改用MediaRecorder实际支持的格式:

record_btn.onclick = () => {
  $('#stop_btn').removeClass('hidden');
  $('#record_btn').addClass('hidden');
  $('#voice-bars').removeClass('hidden');
  device = navigator.mediaDevices.getUserMedia({ audio: true});
  
  device.then(stream => {
    recorder = new MediaRecorder(stream);
    var items = [];
    recorder.start();

    recorder.addEventListener('dataavailable', e => {
      items.push(e.data);
    });

    recorder.addEventListener('stop', e => {
      // 使用MediaRecorder原生支持的MIME类型,避免伪造格式
      const actualMimeType = recorder.mimeType || 'audio/webm';
      blob = new Blob(items, { 'type': actualMimeType });
      // 文件名对应真实格式
      myFile = new File([blob], `audio.${actualMimeType.split('/')[1]}`);
      $('#source').attr("src", URL.createObjectURL(blob));
    });
  });
}

Django后端转换处理

使用pydub库(依赖FFmpeg)将上传的WebM/WAV文件转为标准MP3:

  1. 安装依赖:
pip install pydub
# 需额外安装FFmpeg:
# Ubuntu/Debian: sudo apt install ffmpeg
# macOS: brew install ffmpeg
# Windows: 下载FFmpeg并配置系统环境变量
  1. 上传处理示例:
from pydub import AudioSegment
from django.http import HttpResponse

def save_recorded_audio(request):
    if request.method == 'POST':
        audio_file = request.FILES.get('recorded_audio')
        if not audio_file:
            return HttpResponse("No audio file uploaded", status=400)
        
        # 读取上传的音频文件
        raw_audio = AudioSegment.from_file(audio_file)
        # 导出为标准MP3
        mp3_output_path = f"media/recordings/{audio_file.name.split('.')[0]}.mp3"
        raw_audio.export(mp3_output_path, format='mp3', bitrate='128k')
        
        # 后续业务逻辑...
        return HttpResponse("Audio processed successfully")

修复方案2:前端直接编码为MP3(兼容性稍弱)

若需前端直接生成MP3,可使用第三方编码库(如lamejs)处理原始音频数据,而非依赖MediaRecorder的默认输出:

// 引入lamejs库(可通过CDN或本地文件引入)
record_btn.onclick = () => {
  $('#stop_btn').removeClass('hidden');
  $('#record_btn').addClass('hidden');
  $('#voice-bars').removeClass('hidden');
  
  navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
    const audioContext = new AudioContext();
    const source = audioContext.createMediaStreamSource(stream);
    const processor = audioContext.createScriptProcessor(4096, 1, 1);
    
    // 初始化MP3编码器(单声道、采样率、比特率)
    const mp3Encoder = new lamejs.Mp3Encoder(1, audioContext.sampleRate, 128);
    const mp3Data = [];

    source.connect(processor);
    processor.connect(audioContext.destination);

    // 实时编码音频数据
    processor.onaudioprocess = function(e) {
      const inputData = e.inputBuffer.getChannelData(0);
      const mp3Chunk = mp3Encoder.encodeBuffer(inputData);
      if (mp3Chunk.length > 0) {
        mp3Data.push(new Int8Array(mp3Chunk));
      }
    };

    // 绑定停止录制逻辑到stop_btn
    $('#stop_btn').click(() => {
      processor.disconnect();
      source.disconnect();
      stream.getTracks().forEach(track => track.stop());
      
      // 完成编码,生成MP3 Blob
      const finalMp3Chunk = mp3Encoder.flush();
      if (finalMp3Chunk.length > 0) {
        mp3Data.push(new Int8Array(finalMp3Chunk));
      }
      const mp3Blob = new Blob(mp3Data, { type: 'audio/mp3' });
      myFile = new File([mp3Blob], 'audio.mp3');
      $('#source').attr("src", URL.createObjectURL(mp3Blob));
      
      // 恢复按钮状态
      $('#stop_btn').addClass('hidden');
      $('#record_btn').removeClass('hidden');
      $('#voice-bars').addClass('hidden');
    });
  });
};

方案对比

  • 方案1兼容性拉满,后端转换不受浏览器限制,能确保生成全设备支持的标准MP3,推荐优先使用。
  • 方案2无需后端参与,但需引入第三方库,部分旧版浏览器可能不支持AudioContext相关API。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 03:10:36