I have this radio and I'm currently working on getting it to Play, Stop, Play Last, and Play Next. While trying to figure out the Play Last and Play when you get an error on the first load, I ended up running into an issue where it tries to run through my loop again before being called to and fails to load the content as it already has content. After 3-4 tries it stops looping as it should have.
Currently it plays the same song over and over if I click next instead of playing the next song it plays the same thing. Otherwise it does nothing automatically. I believe the issue is with a code; somewhere being wrong.
In the code I tried to set a var code; to route the actions through the program.
My idea of how the code should work:
code = 1; This should loop though songs after song endlessly playing.
code = 0; This should play the last played song unless the current is the first song. Then become code 1.
code = 2; It looked to me like there was an endless loop so I used 2 as a stop point for loops.
This is all of the parts that has something to do with the current song.
It's probably easier to understand the code if you read the controls first. It ALWAYS starts with playNext();
Part one gets the link to the file
//Part One - Get file directory
function partOne(){
$.ajax({
url: '../scripts/radio.php',
data: {
attr1: 'value1'
},
success: function(returnData) {
data = returnData;
lastData = data;
console.log(data);
console.log('Step1')
playFirst();
}
});
};
partOne();
This part routes the code to the correct location.
//Step 2 - Code Highway - Gets new song or sends loop to trash and plays last/current song.
function codeRoute(){
document.getElementById("playSampleButton").disabled = true;
setTimeout(function(){document.getElementById("playSampleButton").disabled = false;},5000);
if (code === 1){
$.ajax({
url: '../scripts/radio.php',
data: {
attr1: 'value1'
},
success: function(returnData) {
data = returnData;
console.log(data);
code=2;
sourceNode.stop(0);
playFirst();
}
});
}if(code === 0);{
code = 2;
sourceNode.stop(0);
console.log(code)
console.log('0step2')
playFunct();
}
console.log('Step2')
};
Probably useless but this part loads and plays the selected file.
//Step 3 Loads and plays song
//Load and Play current/next song
function playFirst(){
document.getElementById("songName").innerHTML = data;
fileChosen = true;
setupAudioNodes();
var request = new XMLHttpRequest();
console.log('Step3')
request.addEventListener("progress", updateProgress);
request.addEventListener("load", transferComplete);
request.addEventListener("error", transferFailed);
request.addEventListener("abort", transferCanceled);
request.open('GET', data, true);
request.responseType = 'arraybuffer';
// When loaded decode the data
request.onload = function() {
code=1;
$("#title").html("Infinite");
$("#album").html("Infinite");
$("#artist").html("Valence");
onWindowResize();
$("#title, #artist, #album").css("visibility", "visible");
// decode the data
context.decodeAudioData(request.response, function(buffer) {
// when the audio is decoded play the sound
sourceNode.buffer = buffer;
sourceNode.start(0);
$("#freq, body").addClass("animateHue");
//on error
}, function(e) {
console.log(e);
});
};
request.send();
};
//Load and Play last/Current when autoplay blocked.
function playFunct(){
document.getElementById("songName").innerHTML = lastData;
fileChosen = true;
setupAudioNodes();
console.log('Step3.5')
var request = new XMLHttpRequest();
request.addEventListener("progress", updateProgress);
request.addEventListener("load", transferComplete);
request.addEventListener("error", transferFailed);
request.addEventListener("abort", transferCanceled);
request.open('GET', lastData, true);
request.responseType = 'arraybuffer';
// When loaded decode the lastData
request.onload = function() {
$("#title").html("Infinite");
$("#album").html("Infinite");
$("#artist").html("Valence");
onWindowResize();
$("#title, #artist, #album").css("visibility", "visible");
// decode the lastData
context.decodeAudioData(request.response, function(buffer) {
// when the audio is decoded play the sound
sourceNode.buffer = buffer;
sourceNode.start(0);
console.log(lastData)
console.log(code)
console.log('0step3')
$("#freq, body").addClass("animateHue");
//on error
}, function(e) {
console.log(e);
});
};
request.send();
};
//Step 4
//Auto plays next song. Trashes loop.
var audioBuffer;
var sourceNode;
function setupAudioNodes() {
// setup a analyser
analyser = context.createAnalyser();
// create a buffer source node
sourceNode = context.createBufferSource();
//connect source to analyser as link
sourceNode.connect(analyser);
// and connect source to destination
sourceNode.connect(context.destination);
//start updating
rafID = window.requestAnimationFrame(updateVisualization);
sourceNode.onended = function() {
console.log('Step4')
if(code === 1){
codeRoute();
}if(code === 2){
console.log('Trash Deleted')
}
}
};
Update: The full above code fully working if anyone is interested:
//Part One - Get file directory
function partOne(){
$.ajax({
url: '../scripts/radio.php',
data: {
attr1: 'value1'
},
success: function(returnData) {
data = returnData;
lastData = data;
console.log(data);
console.log('Step1')
playFirst();
}
});
};
partOne();
//Step 2 - Code Highway - Gets new song or sends loop to trash and plays last/current song.
function codeRoute(){
document.getElementById("playSampleButton").disabled = true;
setTimeout(function(){document.getElementById("playSampleButton").disabled = false;},5000);
if (code === 1){
$.ajax({
url: '../scripts/radio.php',
data: {
attr1: 'value1'
},
success: function(returnData) {
data = returnData;
console.log(data);
code=2;
sourceNode.stop(0);
playFirst();
}
});
}if(code === 0){
code = 2;
sourceNode.stop(0);
console.log(code)
console.log('0step2')
playFunct();
}
console.log('Step2')
};
//Step 3 Loads and plays song
//Load and Play current/next song
function playFirst(){
document.getElementById("songName").innerHTML = data;
fileChosen = true;
setupAudioNodes();
var request = new XMLHttpRequest();
console.log('Step3')
request.addEventListener("progress", updateProgress);
request.addEventListener("load", transferComplete);
request.addEventListener("error", transferFailed);
request.addEventListener("abort", transferCanceled);
request.open('GET', data, true);
request.responseType = 'arraybuffer';
// When loaded decode the data
request.onload = function() {
code=1;
$("#title").html("Infinite");
$("#album").html("Infinite");
$("#artist").html("Valence");
onWindowResize();
$("#title, #artist, #album").css("visibility", "visible");
// decode the data
context.decodeAudioData(request.response, function(buffer) {
// when the audio is decoded play the sound
sourceNode.buffer = buffer;
sourceNode.start(0);
$("#freq, body").addClass("animateHue");
//on error
}, function(e) {
console.log(e);
});
};
request.send();
};
//Load and Play last/Current when autoplay blocked.
function playFunct(){
document.getElementById("songName").innerHTML = lastData;
fileChosen = true;
setupAudioNodes();
console.log('Step3.5')
var request = new XMLHttpRequest();
request.addEventListener("progress", updateProgress);
request.addEventListener("load", transferComplete);
request.addEventListener("error", transferFailed);
request.addEventListener("abort", transferCanceled);
request.open('GET', lastData, true);
request.responseType = 'arraybuffer';
// When loaded decode the lastData
request.onload = function() {
code=1;
$("#title").html("Infinite");
$("#album").html("Infinite");
$("#artist").html("Valence");
onWindowResize();
$("#title, #artist, #album").css("visibility", "visible");
// decode the lastData
context.decodeAudioData(request.response, function(buffer) {
// when the audio is decoded play the sound
sourceNode.buffer = buffer;
sourceNode.start(0);
console.log(lastData)
console.log(code)
console.log('0step3')
$("#freq, body").addClass("animateHue");
//on error
}, function(e) {
console.log(e);
});
};
request.send();
};
//Controls
//Play A Song Again
function playAgain(){
console.log(data);
code = 0;
codeRoute();
}
//Stop Playing
function stopPlaying(){
code = 2;
sourceNode.stop(0);
}
//Play Next Song
//Step 1
function playNext(){
if(context.state == 'suspended'){
code =0;
playFunct();
}else{
code =1;//0; to play last song.
console.log(code)
codeRoute();
}
}
//Step 4
//Auto plays next song. Trashes loop.
var audioBuffer;
var sourceNode;
function setupAudioNodes() {
// setup a analyser
analyser = context.createAnalyser();
// create a buffer source node
sourceNode = context.createBufferSource();
//connect source to analyser as link
sourceNode.connect(analyser);
// and connect source to destination
sourceNode.connect(context.destination);
//start updating
rafID = window.requestAnimationFrame(updateVisualization);
sourceNode.onended = function() {
console.log('Step4')
if(code === 2){
console.log('Trash Deleted')
}else{
if(code === 1){
codeRoute();
}
}
}
};
In the section labeled "This part routes to the current location" the snippet:
if(code === 0);{
code = 2;
sourceNode.stop(0);
console.log(code)
console.log('0step2')
playFunct();
}
The if statement should not have a semi-colon (i.e.)
if(code === 0){
code = 2;
sourceNode.stop(0);
console.log(code)
console.log('0step2')
playFunct();
}
Related
Below is the snippet of my code that I am using. Actually video that I am loading is of about 1GB, so incase user has medium internet connection, the ajax times out the request, before the video gets fully loaded.
Hence I want to reset ajax time out period to 1 day, so that it doesn't gets timed out.
$(window).load(function(){
console.log("Downloading video...hellip;Please wait...");
var xhr = new XMLHttpRequest();
xhr.open('GET', 'video/video.m4v', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
console.log("got it");
var myBlob = this.response;
var vid = (window.webkitURL ? webkitURL : URL).createObjectURL(myBlob);
// myBlob is now the blob that the objec8t URL pointed to.
var video = document.getElementById("video");
console.log("Loading video into element");
video.src = vid;
// not needed if autoplay is set for the video element
// video.play()
//alert(1);
windowLoad();
$('body').removeClass('loading');
}
}
xhr.send();
});
Thanks
You can set the XMLHttpRequest.timeout
xhr.timeout = 86400000; // 1 day in milliseconds
xhr.ontimeout = function (e) {
// XMLHttpRequest timed out. Do something here.
};
I've read a lot of topics and questions on this matter, but I can't find a solution. I can play sound on every Android browser, on every desktop browser, but not on Safari on iPhone 5c.
I'm trying to do it with Web Audio API (I'm definitly not an expert), here's my code:
window.addEventListener ('load', loadSound);
canvas.addEventListener ('touchend', loadSound);
canvas.addEventListener ('mouseup', loadSound);
window.AudioContext = window.AudioContext || window.webkitAudioContext;
var audioContext = new window.AudioContext();
var playSoundBuffer;
var source;
function loadSound() {
setTimeout(function() {
var request = new XMLHttpRequest();
var audioURL = "media/sound/WW_start.wav";
request.open("GET", audioURL, true);
request.responseType = "arraybuffer";
request.onload = function() {
audioContext.decodeAudioData(request.response, function(buffer) {
playSoundBuffer = buffer;
playSound();
}, function(error) {
console.error("Error in sound", error);
});
request.send();
}
}, 50);
}
function playSound() {
source = audioContext.createBufferSource();
source.buffer = playSoundBuffer;
source.connect(audioContext.destination);
source.start(0);
}
I also tried with source.noteOn(), source.noteOn(0), webkitAudioContext...
Howler is the solution:
<script src="lib/howler.js-master/howler.js-master/dist/howler.js"></script>
...
var sound = new Howl({
src: ['file.wav', 'file.mp3', 'file.ogg'],
volume: 1,
buffer: false
});
window.addEventListener('mousedown', function() {
sound.play();
}, false);
I am sure there is something that I am missing from this code, I just can not figure out what it is.
Here is the main page:
<script>
function wwCallback(e) {
document.write(e.data);
}
function wwError(e) {
alert(e.data)
}
$(document).ready(function () {
var worker = new Worker("sync.js");
worker.onmessage = wwCallback;
worker.onerror = wwError;
worker.postMessage({
'cmd': 'downloadUser',
'url': 'server.php'
});
console.log("WW Started");
});
</script>
Server.php simply echoes a JSON string and I have verified that it is both valid and working using normal ajax requests.
Here is my web workers code:
function getData(url) {
var req = new XMLHttpRequest();
//expect json
req.open('GET', url);
req.send(null);
req.onreadystatechange = function () {
if (req.readyState == 4) {
if (req.status == 200) {
self.postMessage(req.responseText);
}
}
}
}
self.addEventListener('message', function (e) {
var data = e.data;
switch (data.cmd) {
case 'downloadUser':
getData(data.url);
}
self.close();
}, false);
Could anyone point me in the right direction?
Your problem is in your WebWorker XHR call. You've opened the request, then immediately sent it before you've set up the event handler to handle the response. You just need to move the req.send(null); call below the code that sets up the event handler.
Try this:
function getData(url) {
var req = new XMLHttpRequest();
//expect json
req.open('GET', url);
// req.send(null); // remove this line from here.
req.onreadystatechange = function () {
if (req.readyState == 4) {
if (req.status == 200) {
self.postMessage(req.responseText);
}
}
}
req.send(null); // make the request after your readystatechange
// handler is set up.
}
self.addEventListener('message', function (e) {
var data = e.data;
switch (data.cmd) {
case 'downloadUser':
getData(data.url);
}
self.close();
}, false);
I am trying to play sounds with a .keydown() event in jQuery. I would like the sounds to play quickly, but there seems to be a lag time when I perform the keydown event faster than about 3 times per second.
Here is a jsFiddle of my sample code: http://jsfiddle.net/pfrater/FRudg/3/
I am using the audio html tags for the sound and playing:
<audio controls id="sound" preload="auto">
<source src="http://www.wavlist.com/soundfx/011/duck-baby.wav" type="audio/wav"/>
</audio>
<audio controls id="sound2" preload="auto">
<source src="http://rezound.sourceforge.net/examples/chirp.wav" type="audio/wav"/>
</audio>
<audio controls id="sound3" preload="auto">
<source src="http://www.all-birds.com/Sound/downychirp.wav" type="audio/wav"/>
</audio>
and here's my jQuery:
$(document).ready( function() {
var playing;
$(document).bind("keydown", function(key) {
playing = undefined;
switch(parseInt(key.which, 10)) {
case 65:
playing = $("#sound").get(0);
break;
case 83:
playing = $("#sound2").get(0);
break;
case 68:
playing = $("#sound3").get(0);
break;
};
if (playing) {
playing.play();
}
}).on("keyup", function() {
if(playing){
playing.pause();
playing.currentTime=50;
playing = undefined;
}
});
});
Does anyone know of a way to get rid of this lag? Also, the actual files that I'll be playing are mpegs. The ones above are just an example.
Thanks for any help,
Paul
You won't be able to do this with the audio element. This is because the cost setting up and filling the buffers will take too much time.
The good news though is that you can do it using the Web Audio API instead.
I made you an example based on this code from HTML5 rocks (which you should check out for more details) and your original fiddle.
Currently this API is supported in Chrome, Firefox, Safari and Opera will be able to use this:
Fiddle demo
window.AudioContext = window.AudioContext || window.webkitAudioContext;
/// custom buffer loader
/// see http://www.html5rocks.com/en/tutorials/webaudio/intro/
function BufferLoader(context, urlList, callback) {
this.context = context;
this.urlList = urlList;
this.onload = callback;
this.bufferList = new Array();
this.loadCount = 0;
}
BufferLoader.prototype.loadBuffer = function (url, index) {
var request = new XMLHttpRequest();
request.open("GET", url, true);
request.responseType = "arraybuffer";
var loader = this;
request.onload = function () {
// Asynchronously decode the audio file data in request.response
loader.context.decodeAudioData(
request.response,
function (buffer) {
if (!buffer) {
alert('error decoding file data: ' + url);
return;
}
loader.bufferList[index] = buffer;
if (++loader.loadCount == loader.urlList.length)
loader.onload(loader.bufferList);
},
function (error) {
console.error('decodeAudioData error', error);
});
}
request.onerror = function (e) {
alert('BufferLoader: XHR error');
}
request.send();
}
BufferLoader.prototype.load = function () {
for (var i = 0; i < this.urlList.length; ++i)
this.loadBuffer(this.urlList[i], i);
}
The main code:
/// setup audio context and start loading samples
var actx = new AudioContext(),
blst,
bLoader = new BufferLoader(
actx, [
'duck-baby.wav', 'chirp.wav', 'downychirp.wav'],
done),
isReady = false;
/// start loading the samples
bLoader.load();
function done(bl) {
blst = bl; /// buffer list
isReady = true; /// enable keys
$('#status').html('Ready!'); /// update statusw
}
/// this sets up chain so we can play audio
function play(i) {
var src = actx.createBufferSource(); /// prepare sample
src.buffer = blst[i]; /// set buffer from loader
src.connect(actx.destination); /// connect to speakers
src.start(0); /// play sample now
}
/// check keys
$(window).bind("keydown", function (key) {
if (!isReady) return;
switch (parseInt(key.which, 10)) {
case 65:
play(0);
return;
case 83:
play(1);
return;
case 68:
play(2);
return;
}
})
NOTE: When using external samples you must make sure they can be used cross-origin or else loading will fail (I used my DropBox to enable the samples to be loaded with fiddle).
I'm trying to implement a upload progress bar the HTML5 way, by using the XMLHttpRequest level 2 support for progress events.
In every example you see, the method is to add an event listener to the progress event like so:
req.addEventListener("progress", function(event) {
if (event.lengthComputable) {
var percentComplete = Math.round(event.loaded * 100 / event.total);
console.log(percentComplete);
}
}, false);
Such examples always seem to assume that event.lengthComputable will be true. After all, the browser knows the length of the request it's sending, surely?
No matter what I do, event.lengthComputable is false. I've tested this in Safari 5.1.7 and Firefox 12, both on OSX.
My site is built using Django, and I get the same problem on my dev and production setups.
The full code I'm using to generate the form upload is shown below (using jQuery):
form.submit(function() {
// Compile the data.
var data = form.serializeArray();
data.splice(0, 0, {
name: "file",
value: form.find("#id_file").get(0).files[0]
});
// Create the form data.
var fd = new FormData();
$.each(data, function(_, item) {
fd.append(item.name, item.value);
});
// Submit the data.
var req = new XMLHttpRequest();
req.addEventListener("progress", function(event) {
if (event.lengthComputable) {
var percentComplete = Math.round(event.loaded * 100 / event.total);
console.log(percentComplete);
}
}, false);
req.addEventListener("load", function(event) {
if (req.status == 200) {
var data = $.parseJSON(event.target.responseText);
if (data.success) {
console.log("It worked!")
} else {
console.log("It failed!")
}
} else {
console.log("It went really wrong!")
}
}, false);
req.addEventListener("error", function() {
console.log("It went really really wrong!")
}, false);
req.open("POST", "/my-bar/media/add/");
req.setRequestHeader("X-Requested-With", "XMLHttpRequest");
req.send(fd);
// Don't really submit!
return false;
});
I've been tearing my hair out for hours on this. Any help appreciated!
Hey I found the answer from #ComFreek:
I made the same mistake.
The line I wrote was:
xhr.onprogress = uploadProgress;
The correct one should be
xhr.upload.onprogress = uploadProgress;
take a look into this :
https://developer.mozilla.org/en-US/docs/Using_files_from_web_applications
xhr.upload.addEventListener('progress',function(e){}) will also work.
I also had problem with sending multiple big files using AJAX (xmlhttprequest).
Found a solution and here is whole script that I use.
All you need is to place next line in your HTML page:
<input type="file" multiple name="file" id="upload_file" onchange="handleFiles(this)">
and use next script:
<script type="text/javacript">
var filesArray;
function sendFile(file)
{
var uri = "<URL TO PHP FILE>";
var xhr = new XMLHttpRequest();
var fd = new FormData();
var self = this;
xhr.upload.onprogress = updateProgress;
xhr.addEventListener("load", transferComplete, false);
xhr.addEventListener("error", transferFailed, false);
xhr.addEventListener("abort", transferCanceled, false);
xhr.open("POST", uri, true);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4 && xhr.status == 200) {
alert(xhr.responseText); // handle response.
}
};
fd.append('myFile', file);
// Initiate a multipart/form-data upload
xhr.send(fd);
}
function updateProgress (oEvent)
{
if (oEvent.lengthComputable)
{
var percentComplete = oEvent.loaded / oEvent.total;
console.log(Math.round(percentComplete*100) + "%");
} else {
// Unable to compute progress information since the total size is unknown
console.log("Total size is unknown...");
}
}
function transferComplete(evt)
{
alert("The transfer is complete.");
}
function transferFailed(evt)
{
alert("An error occurred while transferring the file.");
}
function transferCanceled(evt)
{
alert("The transfer has been canceled by the user.");
}
function handleFiles(element)
{
filesArray = element.files;
if (filesArray.length > 0)
{
for (var i=0; i<filesArray.length; i++)
{
sendFile(filesArray[i]);
}
filesArray = '';
}
}
</script>
Your result will be in console