使用expo-av录制音频发送至Flask API,如何获取正确音频波形数据?
问题解答
图A代表什么?
图A是3GP音频容器文件的原始字节序列波形。你直接将expo-av录制并发送的完整二进制数据(包含3GP文件的文件头、元数据、编码后的音频帧等所有结构)转换为uint8数组绘制,得到的是文件每个字节的数值波动,完全不是实际的音频采样信号——这就是为什么它和标准音频波形(图B)差异巨大。
在Flask中获取可绘制标准波形的采样数据
要提取能生成类似WAV波形图的采样数据,核心是解码3GP容器,提取原始音频采样。以下是两种可行的Python实现方案:
方案1:使用soundfile + ffmpeg(推荐)
soundfile需要依赖ffmpeg来解码3GP这类非WAV格式,先安装依赖:
pip install soundfile # 系统层面需安装ffmpeg:Ubuntu用apt install ffmpeg,mac用brew install ffmpeg,Windows可从官网下载
Flask中的处理代码:
from flask import Flask, request import soundfile as sf import numpy as np import matplotlib.pyplot as plt app = Flask(__name__) @app.route('/upload-audio', methods=['POST']) def upload_audio(): # 接收二进制音频数据 audio_data = request.get_data() # 将二进制数据写入临时文件 with open('temp_audio.3gp', 'wb') as f: f.write(audio_data) # 解码音频,获取采样数据和采样率 samples, sample_rate = sf.read('temp_audio.3gp') # 绘制标准音频波形 plt.plot(samples) plt.savefig('audio_waveform.png') return {'sample_rate': sample_rate, 'sample_length': len(samples)} if __name__ == '__main__': app.run(debug=True)
方案2:使用pydub
pydub同样依赖ffmpeg,安装依赖:
pip install pydub # 系统层面需安装ffmpeg
Flask处理代码:
from flask import Flask, request from pydub import AudioSegment import io import numpy as np import matplotlib.pyplot as plt app = Flask(__name__) @app.route('/upload-audio', methods=['POST']) def upload_audio(): audio_data = request.get_data() # 直接从二进制数据加载3GP音频 audio_segment = AudioSegment.from_file(io.BytesIO(audio_data), format='3gp') # 转换为numpy采样数组 samples = np.array(audio_segment.get_array_of_samples()) # 立体声场景下取单通道示例 if audio_segment.channels == 2: samples = samples.reshape((-1, 2))[:, 0] # 绘制标准音频波形 plt.plot(samples) plt.savefig('audio_waveform.png') return {'sample_rate': audio_segment.frame_rate, 'sample_length': len(samples)} if __name__ == '__main__': app.run(debug=True)
关键说明
expo-av默认录制的是3GP编码的音频文件(从你提供的二进制数据开头ftyp3gp4可确认),这是一个封装了编码音频数据的容器格式,而非原始的PCM采样数据。你之前的代码直接处理容器的二进制字节,自然无法得到音频信号波形。必须先解码容器,提取出PCM采样数据,才能绘制出类似WAV文件的标准波形。
内容的提问来源于stack exchange,提问作者Claudio Paladini
相关产品推荐
相关产品推荐

