在真實追星情境中,粉絲聽直播或看演唱會現場時,最常遇到的不是實驗室裡的完美環境,而是
今天我們要實作網路斷線緩衝重連與背景降噪預處理!
當 API 請求因為網路不穩定失敗時,不能直接報錯給用戶看,必須在背景自動重試:
在 lib/core/utils/(或 live_translate/data/services/)建立 network_retry_utils.dart
import 'dart:async';
import 'dart:io';
class NetworkRetryUtils {
/// 自動重試機制(帶有指數退避,最多重試 maxAttempts 次)
static Future<T?> retryOnNetworkError<T>(
Future<T> Function() action, {
int maxAttempts = 3,
Duration initialDelay = const Duration(milliseconds: 500),
}) async {
int attempts = 0;
Duration delay = initialDelay;
while (attempts < maxAttempts) {
try {
attempts++;
return await action();
} catch (e) {
// 若達到最大重試次數,宣告失敗
if (attempts >= maxAttempts) {
print('網路請求重試 $maxAttempts 次後依然失敗: $e');
return null;
}
// 判斷是否為網路相關異常(SocketException, Timeout 等)
if (e is SocketException || e is TimeoutException) {
print('網路不穩定,第 $attempts 次重試中... (${delay.inMilliseconds}ms 後)');
await Future.delayed(delay);
delay *= 2; // 時間加倍 (500ms -> 1000ms -> 2000ms)
} else {
// 非網路問題(如 401 密碼錯),不重試直接拋出
rethrow;
}
}
}
return null;
}
}
在演唱會或有大聲 BGM 的直播中,普通的靜音過濾器(VAD)會被背景聲打穿。我們提升 SilenceFilterUtils,加入動態噪音門檻:
更新 silence_filter_utils.dart
class SilenceFilterUtils {
/// 支援高噪音環境的動態 Noise Gate
static bool isSpeechInNoisyEnv(
Uint8List pcmBytes, {
bool isHighNoiseMode = false, // 是否開啟高噪音/演唱會模式
}) {
if (pcmBytes.isEmpty) return false;
// 高噪音模式下,提高門檻至 -28dB (過濾掉背景音樂與遠處尖叫聲)
// 一般模式下,維持 -40dB
double thresholdDb = isHighNoiseMode ? -28.0 : -40.0;
int sampleCount = pcmBytes.length ~/ 2;
double sumSquares = 0.0;
final buffer = pcmBytes.buffer.asByteData(pcmBytes.offsetInBytes, pcmBytes.lengthInBytes);
for (int i = 0; i < pcmBytes.length - 1; i += 2) {
int sample = buffer.getInt16(i, Endian.little);
double normalized = sample / 32768.0;
sumSquares += normalized * normalized;
}
double rms = (sampleCount > 0) ? (sumSquares / sampleCount) : 0.0;
if (rms < 0.00001) return false;
double db = 20 * (rms > 0 ? rms : 0.00001);
return db > thresholdDb;
}
}
TranslationService 與 UI 降級提示在 translation_service.dart 呼叫 API 時套用 NetworkRetryUtils
Future<String?> translateWithRetry(String rawText) async {
return NetworkRetryUtils.retryOnNetworkError(() async {
// 包裹原本的 http.post 翻譯邏輯
return await translateText(rawText: rawText, targetLanguage: '繁體中文');
});
}
在 UI(multi_lang_page.dart)上加上「高噪音抗噪模式」開關與網路異常離線狀態提示
bool _isHighNoiseMode = false; // 是否開啟高抗噪模式
Widget _buildNoiseModeToggle() {
return SwitchListTile(
title: const Text('高抗噪/演唱會模式', style: TextStyle(fontSize: 14)),
subtitle: const Text('過濾背景音樂與尖叫聲', style: TextStyle(fontSize: 12, color: Colors.grey)),
value: _isHighNoiseMode,
onChanged: (val) {
setState(() => _isHighNoiseMode = val);
},
);
}