Flutter获取PCM音频流写入文件含BOM头导致文件损坏的问题求助
Flutter获取PCM音频流写入文件含BOM头导致文件损坏的问题求助
我最近遇到一个棘手的问题:我的Flutter应用从后端获取PCM音频流,用Postman测试时能正常保存并通过ffplay播放,但Flutter本地保存的PCM文件却是损坏的,播放全是噪音。
问题核心对比
后端返回的是纯二进制PCM流,Postman保存的文件Hex开头是正常的原始数据:
03 00 01 00 FC FF FA FF F7 FF FB FF FA FF F8 FF F6 FF F6 FF ...
但Flutter保存的文件开头多了FF FE的BOM头,后续数据还出现了大量异常的重复片段(比如频繁出现A0 00),导致文件损坏:
FF FE 03 00 00 00 01 00 00 00 B3 00 A0 00 B7 00 A0 00 B8 00 A0 00 ...
相关代码片段
ApiService请求部分
static Future<http.StreamedResponse> getAudioById(int id) async { return await _authenticatedStreamRequest('/api/get/audioFile/$id', 'GET'); } static Future<http.StreamedResponse> _authenticatedStreamRequest( String url, String method, ) async { String? accessToken = await SecureStorage.readSecureData('jwt_token'); http.StreamedResponse response = await _makeStreamRequest( url, method, accessToken, ); if (response.statusCode == 401) { debugPrint('Token expired, refreshing...'); bool refreshed = await _refreshTokenIfNeeded(); if (refreshed) { accessToken = await SecureStorage.readSecureData('jwt_token'); response = await _makeStreamRequest(url, method, accessToken); } } return response; } static Future<http.StreamedResponse> _makeStreamRequest( String url, String method, String? token, ) async { final headers = <String, String>{}; if (token != null) { headers['Authorization'] = 'Bearer $token'; headers['Accept'] = 'application/octet-stream'; // headers['Accept-Encoding'] = 'identity'; headers['Connection'] = 'keep-alive'; headers['Content-Type'] = 'application/octet-stream'; } final request = http.Request(method, Uri.parse('$backendUrl$url')); request.headers.addAll(headers); request.followRedirects = true; try { final client = http.Client(); final streamedResponse = await client .send(request) .timeout( const Duration(minutes: 15), onTimeout: () => throw Exception('Timeout fetching audio stream'), ); return streamedResponse; } catch (e) { throw Exception('Error fetching audio stream: $e'); } }
本地保存文件部分
// 获取音频流响应 final audioDataResponse = await ApiService.getAudioById(id); if (audioDataResponse == null) { throw Exception('Response null'); } if (audioDataResponse.statusCode == 401 || audioDataResponse.statusCode == 404) { debugPrint('Error fetching audio data: ${audioDataResponse.statusCode}'); return; } if (audioDataResponse.statusCode == 408) { debugPrint('Error occurred: ${audioDataResponse}'); return; } try { final dir = await getTemporaryDirectory(); final pcmFilePath = '${dir.path}/audio_$id.pcm'; final pcmFile = File(pcmFilePath); if (await pcmFile.exists()) { await pcmFile.delete(); } final sink = pcmFile.openWrite(mode: FileMode.writeOnly); await audioDataResponse.stream.pipe(sink); await sink.close(); final checkBytes = await pcmFile.openRead(0, 20).first; debugPrint( 'Gespeicherte PCM-Datei (direktes Streaming): ${checkBytes.map((b) => '0x${b.toRadixString(16).padLeft(2, '0')}').join(' ')}', ); debugPrint( 'PCM-Datei erfolgreich per direktem Stream gespeichert: ${pcmFile.path}', ); } on Exception catch (e) { throw Exception('Fehler beim Speichern der PCM-Datei: $e'); }
我尝试过的调整
- 启用/注释过
Accept-Encoding: identity头,试图禁用自动压缩 - 尝试移除请求的
accept-encoding头 - 确认请求头的
Accept和Content-Type都设置为application/octet-stream
但问题依然存在,Flutter保存的文件始终带BOM头且数据异常。有没有朋友遇到过类似问题?或者能帮我排查下哪里出了问题?
内容来源于stack exchange
相关产品推荐
相关产品推荐

