So I am opening a websocket connection with elevenlabs api like this and fetching stream of audio data :
final socketChannel = IOWebSocketChannel.connect(
'wss://api.elevenlabs.io/v1/text-to-speech/${widget.voiceId}/stream-input?model_id=$model');
final AudioPlayer audioPlayer = AudioPlayer();
final streamController = StreamController<List<int>>();
final myCustomSource = MyCustomSource(streamController.stream);
final bosMessage = {
"text": " ",
"voice_settings": {"stability": 0.5, "similarity_boost": true},
"xi_api_key": "api_key",
};
socketChannel.sink.add(jsonEncode(bosMessage));
socketChannel.stream.listen((message) async {
final response = jsonDecode(message);
if (response['audio'] != null) {
try {
final audioChunk = response['audio'] as String;
final uint8List = Uint8List.fromList(base64.decode(audioChunk));
streamController.add(uint8List);
} catch (e) {
print("Error setting audio source and playing: $e");
}
}
}, onDone: () async {
print('we are done here');
await audioPlayer.setAudioSource(myCustomSource);
print('source is done');
try {
audioPlayer.play();
} catch (e) {
print('error is $e');
}
MyCustomSource is set up like this :
class MyCustomSource extends StreamAudioSource {
final Stream<List<int>> byteStream;
final List<int> bytes = [];
MyCustomSource(this.byteStream) {
byteStream.listen((data) {
bytes.addAll(data);
});
}
@override
Future<StreamAudioResponse> request([int? start, int? end]) async {
start ??= 0;
end ??= bytes.length;
return StreamAudioResponse(
sourceLength: bytes.length,
contentLength: end - start,
offset: start,
stream: Stream.value(bytes.sublist(start, end)),
contentType: 'audio/mpeg',
);
}
}
Now the issue is audio plays smoothly when I am setting the source and playing the audio inside onDone(){}. But my expected behaviour is that to play audio as the streamed chunks arrive and keep playing it. The issue right now iis that if I amove the .setAudioSource and .play beofre onDone and inside listen, each time a new audio chunk comes in, a new audiosource is set which starts from the beginning and goes as far as the new streamed chunk. So what happens is that anytime a new streamed chunk arrives, it starts playing from the beginning essentially repeating itself before finishing it up.
How can I fix it so that it starts playing immediately and continue playing rather than restarting from the beginning