Javascript play Audio after other without audio-collapse - javascript

I am trying to play one audio after another using Javascript. I get the audio file name from a vector (int) and from some strings I have created.
This is my code but I can't make it works.
var audio = new Audio();
function playAll(){
var folder_name = "synthex/";
var file_name = ".sentence";
var audio_file = ".wav";
for(i=0;i<18;++i)
{
var dir_file = folder_name + voicesClicks[i];
dir_file = dir_file + file_name;
if(voicesClicks[i] == null){
continue;
}
//var value = voicesClicks[i];
dir_file = dir_file + i;
dir_file = dir_file + audio_file;
console.log(dir_file);
audio.src = dir_file;
audio.play();
}
}

One major problem that I find with your code is, audio's src keep changing in each iteration, so even if the audio.src value is a vaild wav file, you code would end up playing the last one...
I had a similar requirement, I did...
function playAll() {
// CHANGE this list to as per your requirement.
var urls = ['http://upload.wikimedia.org/wikipedia/en/f/f9/Beatles_eleanor_rigby.ogg',
'http://upload.wikimedia.org/wikipedia/commons/5/5b/Ludwig_van_Beethoven_-_Symphonie_5_c-moll_-_1._Allegro_con_brio.ogg'
];
var idx = 0;
var aud = new Audio();
aud.src = urls[idx];
aud.addEventListener('ended', function() { // for automatically starting the next.
idx++;
if (idx === urls.length) idx = 0;
aud.src = urls[idx];
aud.play();
});
aud.play();
}
document.addEventListener("DOMContentLoaded", playAll); // you can change this to button.onclick handler.
Edit: you can change the urls to ...
var urls = [];
for(i=0;i<18;++i){
if(!voicesClicks[i]){
continue;
}
urls.push(folder_name + voicesClicks[i] + file_name + i + audio_file);
}
console.log(JSON.stringify(urls)); // for debug

Related

use for-loop in javascript to assign different sources for audiofiles

I'm trying to build a soundboard (similar to therapboard dot com) - and i want javascript to create the images (named niels1.png, niels2.png...) alongside the fitting sound (1.ogg, 2.ogg,...) when the image is clicked, via a loop.
The image part works, there's also a sound being played when i click on any of the images, but it's the same sound (in this case the last from the loop... so 3.ogg). Is what i want doable with the fairly easy start i've come up with so far?
<script>
var i;
for(i=0; i<4; i++){
var imgsrc = "niels" + i + ".png";
var audiosrc = i + ".ogg";
var image = document.createElement("IMG");
image.setAttribute("src", imgsrc);
image.addEventListener('click', myPlay);
var audio = document.createElement('audio');
audio.src = audiosrc;
function myPlay(){
var audio = new Audio (audiosrc);
audio.play();
}
document.body.appendChild(image);
}
</script>
Try this. You have a closure issue and this removes the need for a closure
document.body.addEventListener('click', function(e) {
var tgt = e.target;
if (tgt.tagName === "IMG") {
var audiosrc = tgt.getAttribute("data-audio");
if (audiosrc) {
var audio = new Audio(audiosrc);
audio.play();
}
}
})
for (var i = 0; i < 4; i++) {
var imgsrc = "niels" + i + ".png";
var audiosrc = i + ".ogg";
var image = document.createElement("IMG");
image.setAttribute("data-audio", audiosrc)
image.setAttribute("src", imgsrc);
document.body.appendChild(image);
}

Why does my second audio file not play using the currentTime property?

I would like my audio2 file to play when audio1.currentTime is 3 seconds, but I'm not able to make it work. I'm a newbie in javascript, what am I missing?. This is my current javascript code:
function initAudioPlayer(){
var audio1, audio2, ext, agent;
ext = ".mp3";
agent = navigator.userAgent.toLocaleLowerCase();
if(agent.indexOf('firefox') != -1 || agent.indexOf('opera') != -1) { ext = ".ogg";}
//Audio Objects: audio1 and audio2
audio1 = new Audio();
audio1.src = "folder/Audio1"+ext;
audio1.loop = false;
audio1.play();
audio2 = new Audio();
audio2.src = "folder/Audio2"+ext;
audio2.loop = false;
audio2.play();
//Function that reproduces the second audio file at second 3 of the first audio file
function audio2(){
if(audio1.currentTime == 3) {audio2.play();}
};
}
window.addEventListener("load", initAudioPlayer);
You Must use Audio Api and fetch buffers of your files.
Then you must plus each byte and copy to another new buffer.
this code can help you:
let idnex=0;
samples.forEach(buufer => {
if (index === 0) {
tempBuf = buufer;
} else {
tempBuf = this.appendBuffer(tempBuf, buufer);
}
index++;
});
and by thi method you can append two buffer:
private appendBuffer(buffer1, buffer2) {
const numberOfChannels = Math.min(buffer1.numberOfChannels, buffer2.numberOfChannels);
const tmp = this.audioContextService.createBuffer(Math.max(buffer1.numberOfChannels, buffer2.numberOfChannels),
Math.max(buffer1.length, buffer2.length), buffer1.sampleRate);
for (let i = 0; i < numberOfChannels; i++) {
const channel = tmp.getChannelData(i);
let finallArray = [];
let d = [];
const chanelTemp = buffer1.getChannelData(i);
if (buffer2.numberOfChannels <= i) {
finallArray = chanelTemp;
} else {
const c = buffer2.getChannelData(i);
if (chanelTemp.length > c.length) {
finallArray = chanelTemp;
d = c;
} else {
finallArray = c;
d = chanelTemp;
}
for (let j = 0; j < d.length; j++) {
finallArray[j] += d[j] / 2;
}
}
channel.set(finallArray, i);
}
you can see my demo here
Also You Can See this Answer
If you truly want this to be accurate in time, you can't use Audio() - that's the HTML5 <audio> element, which is not sample-accurate. Javascript is also not accurate enough in event delivery to use a callback to do this (to be fair, neither are most general-purpose native OS APIs). You need to schedule the playback in advance, which is where Web Audio (https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) comes in. You need to load both samples, decode them into AudioBuffers, and then schedule playing back each of them with an AudioBufferSourceNode.

Dynamically playing multiple sounds using javascript

var actions = function(){return {whichPattern:"pattern1"}};
var audio = new Audio();
var _play = function(){
var l = pattern[actions().whichPattern].instrument.length,
times_played =0;
var p = setInterval(function(){
var x = pattern[actions().whichPattern][times_played];
for(var i=0; i<x.length;i++){
var toBePlayed = pattern[actions().whichPattern][times_played][i],
url= "All Drums sounds/"+toBePlayed+".wav";
audio.src = url;
audio.play();
console.log(audio);
times_played++;
}
}, pattern_config[actions().whichPattern].delay);
if(times_played === l){
clearInterval(p);
};
var pp=document.getElementById("play_pause");
pp.style.background="url('graphics/pause.png') no-repeat";
pp.style.backgroundSize ="30px 28px"
audio.source='All Drums sounds/'+pattern['pattern1'][1][0]+'.wav';
audio.play();
};
var pattern_config = {
pattern1:{
WP_slotsCounter:0,
instrument:["Kick_02", "F_T_03", "Rude_cymbal_02"],
delay:10
},
};
var pattern={
pattern1: [], // [['asas', 'sf', 'asd'], ['svv','dgh','sdgh']]
}
The above code is very simple. The first function return an object ...
well the main motive of mine is like :
assuming that pattern.pattern1 = [['asas', 'sf', 'asd'], ['svv','dgh','sdgh']] so i what that the all the strings in the pattern['pattern1'][0] should play at same instant and then with a delay of patter_config[actions().whichPattern].delay that sound files with that names of pattern['pattern1'][1] should play together.
so to achieve this i made the above function _play()
well the problem is that it is not playing the music files and not giving any errors too so that i can identify where is that problem.
pattern["pattern1"] is an array of strings and does not have any 'instrument' property
maybe you were trying to use pattern_config["pattern1"]
var actions = function () {
return {
whichPattern: "pattern1"
}
};
var audio = new Audio();
var _play = function () {
var l = pattern_config[actions().whichPattern].instrument.length,
times_played = 0;
var p = setInterval(function () {
var x = pattern_config[actions().whichPattern][times_played];
for (var i = 0; i < x.length; i++) {
var toBePlayed = pattern_config[actions().whichPattern][times_played][i],
url = "All Drums sounds/" + toBePlayed + ".wav";
audio.src = url;
audio.play();
console.log(audio);
times_played++;
}
}, pattern_config[actions().whichPattern].delay);
if (times_played === l) {
clearInterval(p);
};
var pp = document.getElementById("play_pause");
pp.style.background = "url('graphics/pause.png') no-repeat";
pp.style.backgroundSize = "30px 28px"
audio.source = 'All Drums sounds/' + pattern['pattern1'][1][0] + '.wav';
audio.play();
};
var pattern_config = {
pattern1: {
WP_slotsCounter: 0,
instrument: ["Kick_02", "F_T_03", "Rude_cymbal_02"],
delay: 10
},
};
var pattern = {
pattern1: [['asas', 'sf', 'asd'], ['svv','dgh','sdgh']],
}

loading an unknown number of images

I'm trying to create a lightbox for my site, and I want it to load all the images from a given directory with a filename like image#.jpg.
This is the code I have:
for(var i=0; i<1000; i++)
{
var filename = "images/image"+i+".jpg";
$.get(filename)
.done(function() {
$('#lightbox').append('<img src="placeholder.gif">');
})
.fail(function() {
i=1000; //ugh
});
}
It kind of works, but only tries to load image1000.jpg.
Also, is there a better way to do something like this? I'm sure saying 'do this a ton of times and stop when I manually change the for loop counter' is frowned on.
If your image names are sequential like your said, you can create a loop for the names, checking at every iteration if image exists - and if it doesn't - break the loop:
var bCheckEnabled = true;
var bFinishCheck = false;
var img;
var imgArray = new Array();
var i = 0;
var myInterval = setInterval(loadImage, 1);
function loadImage() {
if (bFinishCheck) {
clearInterval(myInterval);
alert('Loaded ' + i + ' image(s)!)');
return;
}
if (bCheckEnabled) {
bCheckEnabled = false;
img = new Image();
img.onload = fExists;
img.onerror = fDoesntExist;
img.src = 'images/myFolder/' + i + '.png';
}
}
function fExists() {
imgArray.push(img);
i++;
bCheckEnabled = true;
}

Detect img src and then change it with javascript

This is my code:
var i;
var pic = document.getElementById('image');
var picSrc = pic.src;
var fullSrc = picSrc.split('h.jpg')[0] + '.jpg';
pic.src = fullSrc;
document.getElementById('next').onmousedown = function () {
i = 0;
// it works up to here
pic.addEventListener("DOMAttrModified", function(event) {
if (i == 0 && event.attrName == "src") {
pic = document.getElementById('image');
i = 1; // this is to prevent endless loop
picSrc = pic.src;
fullSrc = picSrc.split('h.jpg')[0] + '.jpg';
pic.src = fullSrc;
}
});
return true;
};
It should work on imgur's horizontal layout albums, and replace the low-res images with full-res ones, one image at a time (currently displayed image).
On click of the "next" button, a new image is displayed. However, the script does not load the next full-res image. It only works with the first image loaded.
You're messing up your scope completely, invalidating the entire code after the first run. This should also pop up more than enough errors in your console. Reshuffle assignments to the right spot:
document.getElementById('next').onmousedown = function () {
var i;
var pic = document.getElementById('image');
var picSrc = pic.src;
var fullSrc = picSrc.split('h.jpg')[0] + '.jpg';
pic.src = fullSrc;
pic.addEventListener("DOMAttrModified", function(event) {
if (i == 0 && event.attrName == "src") {
pic = document.getElementById('image');
i = 1; // this is to prevent endless loop
picSrc = pic.src;
fullSrc = picSrc.split('h.jpg')[0] + '.jpg';
pic.src = fullSrc;
}
});
return true;
};
Depending on how the page works specifically (I can't see without having a real world use case) you might have to reassign the entire mousedown event as well.
On every mousedown you are adding a new DOMAttrModified event listener.
Try arranging your code to something like following:
var pic = document.getElementById('image');
var i;
pic.addEventListener("DOMAttrModified", function(event) {
if (i == 0 && event.attrName == "src") {
//pic = document.getElementById('image');
i = 1; // this is to prevent endless loop
picSrc = pic.src;
fullSrc = picSrc.split('h.jpg')[0] + '.jpg';
pic.src = fullSrc;
i = 0;
});
document.getElementById('next').onmousedown = function () {
var picSrc = pic.src;
var fullSrc = picSrc.split('h.jpg')[0] + '.jpg';
pic.src = fullSrc;
});
You should also try using the addEventListener instead of onmousedown

Categories