2

How to merge (not concat) two audio files with just_audio for playing both at the same time?

I want to merge it to avoid a hardware limit of just_audio instances playing at the same time. To play with just one instance of just_audio.

JavaRunner
  • 2,455
  • 5
  • 38
  • 52
  • Does this answer your question? [How to play two (or more) audio files simultaneously with just\_audio and audio\_service?](https://stackoverflow.com/questions/65390691/how-to-play-two-or-more-audio-files-simultaneously-with-just-audio-and-audio-s) – Ryan Heise Feb 26 '21 at 03:12
  • @RyanHeise, no, I want to merge it to avoid a limit of just_audio instances playing at the same time. To play with just one instance of just_audio. – JavaRunner Feb 27 '21 at 12:41
  • Did the question change? If the question is now about avoiding a limit, the answer is that there is no way to avoid the limit. If you are merging N audio sources simultaneously, you need N decoders. The fact that each decoder represents an `AudioPlayer` instance in just_audio doesn't add anything extra to the minimum resources required to solve the problem, so feel free to just create as many instances you need until you hit a limit for the number of simultaneous decoders that the device can cope with. – Ryan Heise Feb 27 '21 at 14:09
  • @RyanHeise, I mean I wanna get a waveform of a first file plus waveform of a second file to play the output waveform using just one instance of just_audio. – JavaRunner Feb 27 '21 at 15:47
  • I can theoretically redesign just_audio for you to do this in a single instance. But the catch is that mixing two audio sources in a single just_audio instance will still use double the resources because as I already said above, there is no way to avoid the hardware limit. If you push the air bubble down somewhere, it will pop up elsewhere. When it comes to the hardware resources required to decode audio, it doesn't come for free. Decoding two waveforms is twice the work as decoding one waveform, so there is obviously a limit to how much simultaneous work can be done at once. – Ryan Heise Feb 27 '21 at 16:30

1 Answers1

4

The only way I have found to concatenate multiple audio files is to use ffmpeg. Add this to your pub.dev flutter_ffmpeg and add this class to your lib folder:

class FFmpeg {

  static Future<File> concatenate(List<String> assetPaths, {String output = "new.mp3"})async{

    final directory = await getTemporaryDirectory();
    final file = File("${directory.path}/$output");

    final ffm = FlutterFFmpeg();
    final cmd = ["-y"];
    for(var path in assetPaths){
      final tmp = await copyToTemp(path);
      cmd.add("-i");
      cmd.add(tmp.path);
    }

    cmd.addAll([
      "-filter_complex",
      "[0:a] [1:a] concat=n=${assetPaths.length}:v=0:a=1 [a]",
      "-map", "[a]", "-c:a", "mp3", file.path
    ]);

    await ffm.executeWithArguments(cmd);
    return file;
  }

  static Future<File>copyToTemp(String path)async{
    Directory tempDir = await getTemporaryDirectory();
    final tempFile = File('${tempDir.path}/${path.split("/").last}');
    if(await tempFile.exists()){
      return tempFile;
    }
    final bd = await rootBundle.load(path);
    await tempFile.writeAsBytes(bd.buffer.asUint8List(), flush: true);
    return tempFile;
  }
}

Example:

final track = await FFmpeg.concatenate(
      [
        "assets/audios/test1.mp3",
        "assets/audios/test2.mp3",
        "assets/audios/test3.mp3",
      ],
      output: "output.mp3"
    );
Marian
  • 355
  • 4
  • 5
  • Hi @Marian I am able to concat the mp3 file but as soon as i change mp3 to wav it's fialing. Can you please help me here – N J Jan 08 '23 at 10:17
  • Found the answer for wav file. Use `pcm_s24le` for anyone for the future reference – N J Jan 08 '23 at 10:44