上一篇
安卓向服务器发送音频数据库
- 行业动态
- 2025-04-24
- 2
安卓设备通过音频采集接口获取数据,经编码压缩后通过HTTP/HTTPS协议加密传输至服务器, 服务器端接收后存入数据库,过程中需确保数据完整性及传输
音频数据采集
使用MediaRecorder录制音频
// 配置录音参数 MediaRecorder mediaRecorder = new MediaRecorder(); mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); mediaRecorder.setOutputFile(outputFilePath); // 本地存储路径 // 开始录音 mediaRecorder.prepare(); mediaRecorder.start(); // 停止录音(需在子线程执行) mediaRecorder.stop(); mediaRecorder.release();
使用AudioRecord实时采集
int bufferSize = AudioRecord.getMinBufferSize( 44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT ); AudioRecord audioRecord = new AudioRecord( MediaRecorder.AudioSource.MIC, 44100, AudioFormat.CHANNEL_IN_MONO, AudioFormat.ENCODING_PCM_16BIT, bufferSize ); // 创建数据流 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); byte[] buffer = new byte[bufferSize]; while (isRecording) { int read = audioRecord.read(buffer, 0, buffer.length); outputStream.write(buffer, 0, read); } audioRecord.release();
音频数据处理与压缩
原始格式 | 目标格式 | 推荐工具库 | 关键参数 |
---|---|---|---|
PCM原始流 | MP3 | LAME | 128kbps, 44.1kHz |
WAV文件 | AAC | FFmpeg | bitrate=192k, samplerate=48000 |
RAW PCM | Opus | libopus | complexity=10, bitrate=64k |
使用FFmpeg命令行转换示例:
ffmpeg -i input.pcm -ar 44100 -ac 1 -b:a 64k output.mp3
音频数据上传实现
文件分片上传策略
// 计算MD5校验值 MessageDigest md = MessageDigest.getInstance("MD5"); byte[] digest = md.digest(Files.readAllBytes(Paths.get(filePath))); String checksum = Base64.encodeToString(digest, Base64.NO_WRAP); // 分片上传(每片1MB) int chunkSize = 1024 1024; try (InputStream is = new FileInputStream(file)) { byte[] buffer = new byte[chunkSize]; int len; while ((len = is.read(buffer)) > 0) { // 上传单个分片 uploadChunk(buffer, len, currentChunkIndex, totalChunks, checksum); } }
Retrofit多part请求配置
@Multipart @POST("api/upload") Call<ResponseBody> uploadAudio( @Part("file") RequestBody fileBody, @Part("metadata") TypedStringRequestBody metadata );
服务器端接收与存储
Spring Boot接收示例:
@PostMapping("/upload") public ResponseEntity handleAudio( @RequestParam("file") MultipartFile file, @RequestParam("checksum") String checksum ) { // 校验MD5 String actualChecksum = DigestUtils.md5Hex(file.getInputStream()); if (!checksum.equals(actualChecksum)) { return ResponseEntity.badRequest().build(); } // 存储文件 Path targetPath = Paths.get("audio_storage/" + file.getOriginalFilename()); Files.copy(file.getInputStream(), targetPath, StandardCopyOption.REPLACE_EXISTING); return ResponseEntity.ok().build(); }
常见问题与解决方案
问题现象 | 可能原因 | 解决方案 |
---|---|---|
上传失败 | 文件超过服务器限制 | 启用分片上传,设置multipart_max_size |
音质异常 | 采样率不匹配 | 统一客户端采样率(建议44.1kHz) |
延迟过高 | 同步处理耗时 | 使用异步任务队列(如RabbitMQ) |
内存溢出 | 大文件直接加载 | 采用流式处理,避免全量加载 |
相关问题与解答
Q1:如何实现断点续传功能?
A1:需在客户端记录已上传分片索引,服务器端维护上传进度状态,每次上传时携带当前进度信息,跳过已完成分片,关键技术点:
- 客户端本地持久化上传进度(SharedPreferences/SQLite)
- 服务器端设计进度查询接口(如
GET /upload/progress
) - 分片时携带
chunk_index
和total_chunks
参数
Q2:如何保证音频数据传输安全?
A2:可采取以下措施:
- 传输层加密:使用HTTPS协议
- 数据加密:客户端使用AES加密后传输(密钥通过RSA交换)
- 完整性校验:计算SHA-256哈希值并提交服务器比对
- 访问控制:服务器端验证用户权限和API密钥