How to Play Multiple Audio Files Simultaneously

How to play multiple audio files simultaniously in flutter

May be their are more appropriate solutions but this solved my problem at the moment, I have used the plugin audioplayers and created multiple instances for each audio file.

Updated: For example for two audio files it's done like below:

enum PlayerState { stopped, playing, paused } 
enum PlayerState1 { stopped1, playing1, paused1 }

class AudioScreen extends StatefulWidget {

@override
_AudioScreenState createState() =>_AudioScreenState();
}

class _AudioScreenState extends State<AudioScreen> {
//for first audio
AudioPlayer audioPlayer;
PlayerState playerState = PlayerState.stopped;
get isPlaying => playerState == PlayerState.playing;
//for second audio
AudioPlayer audioPlayer1;
PlayerState1 playerState1 = PlayerState1.stopped1;
get isPlaying1 => playerState1 == PlayerState1.playing1;

@override
void initState() {
super.initState();
audioPlayer = new AudioPlayer();
audioPlayer1 = new AudioPlayer();
}
Future play() async {
await audioPlayer.play(url);
setState(() {
playerState = PlayerState.playing;
});
await audioPlayer1.play(url1);
setState(() {
playerState1 = PlayerState1.playing1;
});
}
Future stop() async {
await audioPlayer.stop();
setState(() {
playerState = PlayerState.stopped;
});
await audioPlayer1.stop();
setState(() {
playerState1 = PlayerState1.stopped1;
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
body:Column(
children:[
IconButton(
onPressed:() play(),
iconSize: 70.0,
icon:Icon(Icons.play_circle_outline, size: 55),
),
IconButton(
onPressed: stop(),
iconSize: 55.0,
icon: Icon(Icons.stop),
),
]
),
);
}
}

JS: play multiple audio sources simultaneously when loaded

MediaElements are meant for normal playback of media and aren't optimized enough to get low latency. The best is to use the Web Audio API, and AudioBuffers.

You will first fetch each file's data in memory, then decode the audio data from these, and once all the audio data has been decoded, you'll be able to schedule playing all at the same precise moment:

(async() => {
const urls = [ "layer1_big.mp3", "layer2_big.mp3", "layer3_big.mp3" ]
.map( (url) => "https://cdn.jsdelivr.net/gh/jacksorjacksor/jacksorjacksor/soundblocks/audio/" + url );
// first, fetch each file's data
const data_buffers = await Promise.all(
urls.map( (url) => fetch( url ).then( (res) => res.arrayBuffer() ) )
);
// get our AudioContext
const context = new (window.AudioContext || window.webkitAudioContext)();
// decode the data
const audio_buffers = await Promise.all(
data_buffers.map( (buf) => context.decodeAudioData( buf ) )
);
// to enable the AudioContext we need to handle a user gesture
const btn = document.querySelector( "button" );
btn.onclick = (evt) => {
const current_time = context.currentTime;
audio_buffers.forEach( (buf) => {
// a buffer source is a really small object
// don't be afraid of creating and throwing it
const source = context.createBufferSource();
// we only connect the decoded data, it's not copied
source.buffer = buf;
// in order to make some noise
source.connect( context.destination );
// make it loop?
//source.loop = true;
// start them all 0.5s after we began, so we're sure they're in sync
source.start( current_time + 0.5 );
} );
};
btn.disabled = false;
})();
<button disabled>play</button>

Is possible to play multiple audio files simultaneously in android / ios / flutter?

For flutter, you should try this resource: https://pub.dev/packages/audioplayers

It supports playing multiple audio files, preloading audio files and playing them with minimal delay as possible

How to play multiple Audio Files simultaneously using AVPlayer?

You would be better off using AVAudioPlayerNode, AVAudioMixerNode, AVAudioEngine. Using these classes you won't have problems like you have right now. It's also not that difficult to set up.

You can check out my gist, in order to play the sounds in your Playgrounds you would need to put audio files into Resources folder in Project Navigator:
https://gist.github.com/standinga/24342d23acfe70dc08cbcc994895f32b

The code works without stopping background audio when top sounds are triggered.

Here's also the same code:

import AVFoundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

class AudioPlayer {
var backgroundAudioFile:AVAudioFile
var topAudioFiles: [AVAudioFile] = []
var engine:AVAudioEngine
var backgroundAudioNode: AVAudioPlayerNode
var topAudioAudioNodes = [AVAudioPlayerNode]()
var mixer: AVAudioMixerNode
var timer: Timer!
var urls: [URL] = []

init (_ url: URL, urls: [URL] = []) {
backgroundAudioFile = try! AVAudioFile(forReading: url)
topAudioFiles = urls.map { try! AVAudioFile(forReading: $0) }

engine = AVAudioEngine()
mixer = AVAudioMixerNode()

engine.attach(mixer)
engine.connect(mixer, to: engine.outputNode, format: nil)
self.urls = urls
backgroundAudioNode = AVAudioPlayerNode()
for _ in topAudioFiles {
topAudioAudioNodes += [AVAudioPlayerNode()]
}
}

func start() {
engine.attach(backgroundAudioNode)
engine.connect(backgroundAudioNode, to: mixer, format: nil)
backgroundAudioNode.scheduleFile(backgroundAudioFile, at: nil, completionHandler: nil)

try! engine.start()
backgroundAudioNode.play()

for node in topAudioAudioNodes {
engine.attach(node)
engine.connect(node, to: mixer, format: nil)
try! engine.start()
}
// simulate rescheduling files played on top of background audio
DispatchQueue.global().async { [unowned self] in
for i in 0..<1000 {
sleep(2)
let index = i % self.topAudioAudioNodes.count
let node = self.topAudioAudioNodes[index]
node.scheduleFile(self.topAudioFiles[index], at: nil, completionHandler: nil)
node.play()
}
}
}
}

let bundle = Bundle.main
let beepLow = bundle.url(forResource: "beeplow", withExtension: "wav")!
let beepMid = bundle.url(forResource: "beepmid", withExtension: "wav")!
let backgroundAudio = bundle.url(forResource: "backgroundAudio", withExtension: "wav")!
let audioPlayer = AudioPlayer(backgroundAudio, urls: [beepLow, beepMid])
audioPlayer.start()

How to play multiple audio files one by one in html 5?

I would do something like that:

var mySound = document.getElementById("mySound");
var mySound1 = document.getElementById("mySound1");
var mySound2 = document.getElementById("mySound2");
var mySound3 = document.getElementById("mySound3");

var mySoundArray = [mySound, mySound1, mySound2, mySound3];
var mySoundArrayPos = 0;

var myButton = document.getElementById("myButton");
myButton.addEventListener("click", function(event) {
mySound.play();
mySoundArrayPos = 0;
startSoundTimer();
});

const startSoundTimer = () => {
var mySoundTimer = setInterval(() => {
if (mySoundArray[mySoundArrayPos].currentTime >= mySoundArray[mySoundArrayPos].duration) {
if (mySoundArrayPos < mySoundArray.length -1) {
mySoundArrayPos += 1;
mySoundArray[mySoundArrayPos].play();
} else {
clearInterval(mySoundTimer);
}
}
}, 10);
};

I don't know if the 10ms are a bit too fast, but I think, it's legit.

play multiple sounds simultaneously in javascript

You can use the Audio constructor

const music = new Audio('myPathTo/music.mp3')
const soundEffects = new Audio('myPathTo/effects.mp3')

and then

music.play()
soundEffects.play()


Related Topics



Leave a reply



Submit