Flutter: AudioPlayer выдает ошибку «Соединение прервано» после навигации по странице, последующие попытки терпят неудачуAndroid

Форум для тех, кто программирует под Android
Ответить
Anonymous
 Flutter: AudioPlayer выдает ошибку «Соединение прервано» после навигации по странице, последующие попытки терпят неудачу

Сообщение Anonymous »

Я разрабатываю приложение Flutter, которое реализует функцию разговора с использованием записи и воспроизведения звука. Я столкнулся с проблемой, из-за которой воспроизведение звука прекращается после перехода со страницы, содержащей эту функцию, и обратно.
Вот поведение, которое я наблюдаю:
Когда я ухожу на странице я вызываю метод Dispose() в своем классе ConversationHandler.
После возвращения на страницу и начала первого диалога я получаю следующую ошибку:

Код: Выделить всё

🆘 Error playing audio: Connection aborted
I/flutter (17214): 🎙️ Switching to listening mode
I/flutter (17214): 🆘 Error playing audio: Connection aborted
I/flutter (17214): 🎙️ Switching to listening mode
I/flutter (17214): 🆘 Error playing audio: Connection aborted
I/flutter (17214): 🎙️ Switching to listening mode
Несмотря на эту ошибку, первая попытка разговора кажется успешной.
Однако при последующих попытках приложение зависает в состоянии «Прослушивание» и не работает.< /p>
При последующих попытках приложение зависает в состоянии «Прослушивание». Я наблюдаю следующие журналы:

Код: Выделить всё

🎵 Sending audio chunk of size: 2560
I/flutter (17214): 🎵 Sending audio chunk of size: 2560
I/flutter (17214): 🎵 Sending audio chunk of size: 2560
I/flutter (17214): 🔄 Raw message from Deepgram: {"type":"Results","channel_index":[0,1],"duration":3.02,"start":0.0,"is_final":true,"speech_final":false,"channel":{"alternatives":[{"transcript":"","confidence":0.0,"words":[]}]},"metadata":{"request_id":"03448721-acf0-4eac-a1c7-d1fcc67f97ba","model_info":{"name":"general","version":"2024-01-26.8851","arch":"base"},"model_uuid":"1ed36bac-f71c-4f3f-a31f-02fd6525c489"},"from_finalize":false}
I/flutter (17214): 🔄 Decoded response: {type: Results, channel_index: [0, 1], duration: 3.02, start: 0.0, is_final: true, speech_final: false, channel: {alternatives: [{transcript: , confidence: 0.0, words: []}]}, metadata: {request_id: 03448721-acf0-4eac-a1c7-d1fcc67f97ba, model_info: {name: general, version: 2024-01-26.8851, arch: base}, model_uuid: 1ed36bac-f71c-4f3f-a31f-02fd6525c489}, from_finalize: false}
Кроме того, я иногда наблюдаю в журналах следующее поведение:

Код: Выделить всё

🎵 Sending audio chunk of size: 2560
I/flutter (17214): 🎵 Sending audio chunk of size: 2560
I/flutter (17214): 🏁 Deepgram WebSocket connection closed
I/flutter (17214): 🎵 Sending audio chunk of size: 2560
Соединение Deepgram WebSocket неожиданно закрывается, но приложение продолжает отправлять аудиофрагменты.
Я использую пакет just_audio для аудио воспроизведение. Вот соответствующие части моего класса ConversationHandler:

Код: Выделить всё

class ConversationHandler {
// ... (other properties)

late AudioRecorder _recorder;
late IOWebSocketChannel _deepgramChannel;
late IO.Socket _conversationSocket;
late IO.Socket _audioSocket;
late AudioPlayer _audioPlayer;

ConversationState _state = ConversationState.idle;
String _currentTranscript = '';

late Stream _audioStream;
StreamSubscription? _audioStreamSubscription;

bool _isInitialized = false;

// ... (constructor and other methods)

Future startConversation() async {
if (!_isInitialized) {
print('❗ ConversationHandler not initialized');
_updateStatus("Oops! Something went wrong. Please try again.");
return;
}

if (_state != ConversationState.idle) {
print('❗ Cannot start conversation: not in idle state');
return;
}
_updateStatus("Listening...");
await _switchToListeningMode();
}

Future _switchToListeningMode() async {
print('🎙️ Switching to listening mode');
_state = ConversationState.listening;

try {
bool hasPermission = await _recorder.hasPermission();
if (!hasPermission) {
print('❌ Microphone permission not granted');
_updateStatus("Microphone access needed.  Please grant permission.");
return;
}

_audioStream = await _recorder.startStream(const RecordConfig(
encoder: AudioEncoder.pcm16bits,
numChannels: 1,
sampleRate: 16000,
));
print('🎙️ Audio stream started');

_initializeDeepgram();

_audioStreamSubscription = _audioStream.listen(
(Uint8List audioChunk) {
if (_state == ConversationState.listening) {
if (audioChunk.isNotEmpty) {
print('🎵 Sending audio chunk of size: ${audioChunk.length}');
_deepgramChannel.sink.add(audioChunk);
_lastAudioDetected = DateTime.now();
} else {
print('❗ Audio chunk is empty');
}
}
},
onError: (error) {
print('🆘 Error in audio stream: $error');
_updateStatus("Oops! Something went wrong. Please try again.");
},
);
} catch (e) {
print('🆘 Error starting audio stream: $e');
_updateStatus("Oops! Something went wrong. Please try again.");
}
}

void _initializeDeepgram() {
final deepgramUrl = 'wss://api.deepgram.com/v1/listen?encoding=linear16&sample_rate=16000&channels=1&endpointing=500';

try {
_deepgramChannel = IOWebSocketChannel.connect(
Uri.parse(deepgramUrl),
headers: {
'Authorization': 'Token $deepgramApiKey',
},
);
print('🌐 Deepgram WebSocket connected');
} catch (e) {
print('🆘 Error connecting to Deepgram WebSocket: $e');
_updateStatus("Oops! Something went wrong. Please try again.");
return;
}

_deepgramChannel.stream.listen(
(message) {
try {
final response = jsonDecode(message);
print('🔄 Raw message from Deepgram: $message');
print('🔄 Decoded response: $response');

if (response['type'] == 'Results' &&
response['channel'] != null &&
response['channel']['alternatives'] != null &&
response['channel']['alternatives'].isNotEmpty) {
final isFinal = response['is_final'] ?? false;
final transcript = response['channel']['alternatives'][0]['transcript'] as String? ?? '';

if (isFinal && transcript.isNotEmpty) {
_currentTranscript += ' ' + transcript;
print('📝 Current transcript: $_currentTranscript');
if (response['speech_final'] == true) {
_handlePause();
}
}
}
} catch (e) {
print('🆘 Error processing Deepgram response: $e');
_updateStatus("Oops! Something went wrong. Please try again.");
}
},
onError: (error) {
print('🆘 Deepgram WebSocket error: $error');
_updateStatus("Oops! Something went wrong. Please try again.");
},
onDone: () {
print('🏁 Deepgram WebSocket connection closed');
},
);
}

Future _playAudio(Uint8List audioBuffer) async {
print('Playing audiooo');
try {
final tempDir = await getTemporaryDirectory();
print('tempr gotten');
final tempFile = File('${tempDir.path}/temp_audio.mp3');
await tempFile.writeAsBytes(audioBuffer);
print('gotten temp fileeee');
await _audioPlayer.setFilePath(tempFile.path);
await _audioPlayer.play();
await _audioPlayer.playerStateStream.firstWhere(
(state) => state.processingState == ProcessingState.completed
);
print('🔊 Audio playback completed');
} catch (e) {
print('🆘 Error playing audio: $e');
_updateStatus("Oops! Something went wrong.  Please try again.");
}
}

Future stopConversation() async {
print('🛑 Stopping conversation');
_state = ConversationState.idle;
_audioStreamSubscription?.cancel();
await _recorder.stop();
_deepgramChannel.sink.close();
await _audioPlayer.stop();
_updateStatus("Conversation ended.");
}

Future dispose() async {
print('♻️ Disposing ConversationHandler');
await stopConversation();
await _conversationSocket.disconnect();
await _audioSocket.disconnect();
await _audioPlayer.dispose();
}

}
Мои вопросы:
Что может быть причиной ошибки «Соединение прервано» при попытке воспроизвести аудио после навигации по странице?
Почему? кажется, что приложение зависает в состоянии «Прослушивание» при последующих попытках разговора, при этом от Deepgram приходят пустые расшифровки?
Как правильно повторно инициализировать или сбросить аудиоплеер, устройство записи и обработчик разговора при возвращении в страницу, чтобы обеспечить согласованное поведение?
Почему соединение Deepgram WebSocket неожиданно закрывается и как я могу гарантировать, что оно останется открытым или правильно инициализировать его после закрытия?
Любые идеи или предложения был бы очень признателен. Заранее благодарю за помощь!

Подробнее здесь: https://stackoverflow.com/questions/790 ... igation-su
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «Android»