Streaming audio on Flutter with websocket not working as expected

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

Leave a Comment