Android中合并多段WAV流数据后仅播放首段音频的问题排查
解决多段WAV合并后仅播放首段的问题
你之前的方法只跳过了后续分段的头部,但没更新第一段WAV头部里的文件总大小和音频数据总长度字段,播放器会根据第一段头部的大小值只播放对应长度的内容,后面的音频数据会被直接忽略。
核心解决步骤:
- 提取所有分段的纯音频数据(跳过每段的WAV头部)
- 计算所有音频数据的总长度,修改第一段的WAV头部,更新其中的大小字段
- 将修改后的头部 + 所有纯音频数据写入最终文件
修正后的Kotlin代码示例:
// 假设allClipData是所有获取到的分段WAV字节数组列表 val audioDataList = mutableListOf<ByteArray>() var totalDataSize = 0 // 遍历所有分段,提取纯音频数据 for (clipData in allClipData) { if (clipData.size >= 44) { // 跳过标准44字节WAV头部,只保留音频数据部分 val audioData = clipData.copyOfRange(44, clipData.size) audioDataList.add(audioData) totalDataSize += audioData.size } } // 获取第一段的原始头部,修改大小字段 val firstHeader = allClipData.first().copyOf(44) // 计算总文件大小:头部(44字节) + 总数据长度 - 8(WAV文件大小字段定义为总字节数减8) val totalFileSize = 44 + totalDataSize - 8 // 小端模式写入文件大小到头部第4-7字节 firstHeader[4] = (totalFileSize and 0xFF).toByte() firstHeader[5] = ((totalFileSize shr 8) and 0xFF).toByte() firstHeader[6] = ((totalFileSize shr 16) and 0xFF).toByte() firstHeader[7] = ((totalFileSize shr 24) and 0xFF).toByte() // 写入音频数据总长度到头部第40-43字节 firstHeader[40] = (totalDataSize and 0xFF).toByte() firstHeader[41] = ((totalDataSize shr 8) and 0xFF).toByte() firstHeader[42] = ((totalDataSize shr 16) and 0xFF).toByte() firstHeader[43] = ((totalDataSize shr 24) and 0xFF).toByte() // 写入最终合并文件 val output = FileOutputStream(file) output.write(firstHeader) audioDataList.forEach { output.write(it) } output.close()
关键注意事项:
- 必须保证所有分段的WAV参数完全一致:采样率、位深、声道数、编码格式,否则合并后音频会出现杂音或无法播放
- WAV头部的大小字段采用小端字节序,所以需要按字节拆分后依次写入,不能直接写入int值
- 如果分段的WAV头部不是标准44字节(比如包含额外元数据),需要先确认头部实际长度,再调整跳过的字节数
内容的提问来源于stack exchange,提问作者im07
相关产品推荐
相关产品推荐

