cache wav file using javascript - javascript

When I load a sound file with Javascript, the file seems to load from remote server each time. Is it possible to cache the file once loaded? I would like to load once and play as required.
var soundEmbed = null;
function playSound()
{
var myWAVfile = "myfile.wav";
if (soundEmbed)
{
document.body.removeChild(soundEmbed);
}
soundEmbed = document.createElement("embed");
soundEmbed.setAttribute("src", myWAVfile);
soundEmbed.setAttribute("hidden", true);
soundEmbed.setAttribute("autostart", true);
document.body.appendChild(soundEmbed);
}

Related

How to play sound in javascript?

I create websocket server in python to handle notification event. Now, i can receive notification, the problem is i can't play sound because new autoplay policy changed, if i play sound using javascript it give me domexception. Any suggestion please ?
As i know, playing sound is simple in html-javascript. like this example: https://stackoverflow.com/a/18628124/7514010
but it depend to your browsers and how you load and play, so issues is:
Some of browsers wait till user click something, then let you play it (Find a way for it)
In some case browsers never let you play till the address use SSL (means the HTTPS behind your url)
The loading be late so the playing be late / or even not start.
So i usually do this:
HTML
<audio id="notifysound" src="notify.mp3" autobuffer preload="auto" style="visibility:hidden;width:0px;height:0px;z-index:-1;"></audio>
JAVASCRIPT (Generally)
var theSound = document.getElementById("notifysound");
theSound.play();
And the most safe if i want sure it be played when i notify is :
JAVASCRIPT (In your case)
function notifyme(theTitle,theBody) {
theTitle=theTitle || 'Title';
theBody=theBody || "Hi. \nIt is notification!";
var theSound = document.getElementById("notifysound");
if ("Notification" in window && Notification) {
if (window.Notification.permission !== "granted") {
window.Notification.requestPermission().then((result) => {
if (result != 'denied') {
return notifyme(theTitle,theBody);
} else {
theSound.play();
}
});
} else {
theSound.play();
try {
var notification = new Notification(theTitle, {
icon: 'icon.png',
body: theBody
});
notification.onclick = function () {
window.focus();
};
}
catch(err) {
return;
}
}
} else {
theSound.play();
}
}
(and just hope it be played. because even possible to volume or some customization make it failed.)
to bypass new autoplay policy :
create a button that can play the sound, hide it and trigger the sound with :
var event = new Event('click');
playBtn.dispatchEvent(event);
EDIT
assuming you have :
let audioData = 'data:audio/wav;base64,..ᴅᴀᴛᴀ...'; // or the src path
you can use this function to trigger whenever you want without appending or create element to the DOM:
function playSound() {
let audioEl = document.createElement('audio');
audioEl.src = audioData;
let audioBtn = document.createElement('button');
audioBtn.addEventListener('click', () => audioEl.play(), false);
let event = new Event('click');
audioBtn.dispatchEvent(event);
}
usage :
just playSound()
EDIT 2
I re test my code and it does'nt work hum ... weird

Detecting WebAudio sound end

I'm using a javascript build a radio and I'm trying to give it different functionalities but I need to be able to detect the end of a song to make it work. Is there any way to do this?
I've tried different methods I've found online like .ended and such but I don't think those work without using the html audio tag. So I tried to make an audio tag that uses the same data for the source that my js radio uses and get the file length to stop my sourceNode at the end time and make a new one but but i keep getting null returned as the data so that doesn't work either.
I want to do something like:
context.onended = function() {
$.ajax({
url: '../scripts/radio.php',
data: {
attr1: 'value1'
},
success: function(data) {
console.log(data);
fileChosen = true;
setupAudioNodes();
var request = new XMLHttpRequest();
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() {
$("#title").html("Title");
$("#album").html("Goes");
$("#artist").html("Here");
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();
}
});
I want for this to run at the end of a song and play the next file. Which it would work if I could get the end time of the currently playing song.
To fix the above issue I added the .ended event inside the function that the source was set up:
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);
//I had to place a function for the .ended event inside the function sourceNode was set up.
sourceNode.onended = function() {
sourceNode.stop(0);
playFirst();
}
}

Move files to a directory

I am using a Cordova file plugin to create a folder in the file system of devices. This is working.
My issue is I need to move the audio files to the created directory. How can I achieve that?
Below is my code:
function FeedVoicesave(callback, appendData) {
OnCallback = callback;
OnAppendData = appendData;
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, FeedVoicefail);
}
function gotFS(fileSystem) {
// create new folder if not exist
fileSystem.root.getDirectory("Myfolder", { create: true }, gotDir);
}
// I have audio file myaudio, i need to move myaudio to Myfolder
function gotDir(dirEntry) {
dirEntry.getFile(myaudio,null, OnGetFeedVoiceFile);
}

RecordRTC video upload AmazonS3 Timeout error

I am currently developing a component that allows you to make webcam videos and upload them directly to amazon s3. For that purpose I user RecordRTC library and Amazon S3 storage. I have discovered a strange issue, and I am not sure whether it has to do with RecordRTC blobs or with amazon configuration. When the file size is over 1MB, the Amazon server hangs and after 20 seconds returns a timeout error. Could anyone help me figure this out? Here is my code for the recorder component (p() is the same as console.log()):
navigator.record_function = ( navigator.getUserMedia ||
navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia ||
navigator.msGetUserMedia);
if (navigator.record_function) {
navigator.record_function(videoObj, function (stream) {
video.src = window.URL.createObjectURL(stream);
video.play();
$("#stop_recording").click(function () {
stream.stop();
});
// init recorders
audio_recorder = RecordRTC(stream, {type: "audio", bufferSize: 16384});
video_recorder = RecordRTC(stream, videoOptions);
}, errBack);
}
$("#start_recording").click(function () {
// record the audio and video
video_recorder.startRecording();
audio_recorder.startRecording();
});
And for the uploader component:
// Populate the Post paramters.
fd.append('key', "users/" + Main.current_user.id + "/test.webm");
fd.append('AWSAccessKeyId', msg.access_key_id);
fd.append('acl', 'private');
fd.append('policy', msg.policy);
fd.append('signature', msg.signature);
fd.append('Content-Type', '$Content-Type');
fd.append('x-amz-server-side-encryption', 'AES256');
fd.append('success_action_status', '201');
fd.append('name', 'test.webm');
fd.append('Filename', 'test.webm');
fd.append("file", file);
xhr.open('POST', 'https://' + msg.bucket + '.s3.amazonaws.com', true);
xhr.upload.addEventListener('progress', function (e) {
p(e);
}, false);
xhr.onreadystatechange = function () {
p(xhr.readyState);
};
xhr.send(fd);
$("#stop_recording").click(function () {
// stop recorders
audio_recorder.stopRecording(function () {
var audio_blob = audio_recorder.getBlob();
p(audio_blob);
// VideoUploader.upload_user_audio(audio_blob);
}
);
video_recorder.stopRecording(function () {
var video_blob = video_recorder.getBlob();
p(video_blob);
VideoUploader.upload_user_video(video_blob);
});
});
The error message on timeout is:
Your socket connection to the server was not read from or written to within the timeout period. Idle connections will be closed.
I appreciate any help I can get, I am really lost here.
Thanks in advance.
I have managed to find a pretty... strange solution for this issue. It appears the problem comes from the way RecordRTC saves the blob object, which makes it impossible to upload in Firefox 35 on Mac. I could not find the code in RecordRTC that causes the problem, the Blob seems to be generated correctly, but the workaround that worked for me was encoding the Blob again into a new Blob via Filereader.
video_recorder.stopRecording(function () {
var video_blob = video_recorder.getBlob();
var arrayBuffer;
var fileReader = new FileReader();
fileReader.onload = function (ex) {
arrayBuffer = this.result;
video_blob = new Blob([arrayBuffer], {type: "video/webm"});
VideoUploader.upload_user_video(video_blob)
};
fileReader.readAsArrayBuffer(video_blob);
});
As for why that happens, I have no idea, but other projects that use the same technology are affected as well http://videobooth.herokuapp.com/ (the same exact problem in the same exact browser, upload hangs). Maybe this information could be useful for people working on RecordRTC, as I think this workaround could be made into a patch.
Solution is tested on Mac Firefox 35 and Mac Chrome 40.

Loading Javascript and checking once it has loaded

I am using the following JavaScript code and I am trying to find out once the file has been downloaded and added to the header of my page:
function loadjscssfile(filename, filetype)
{
if (filetype=="js"){ //if filename is a external JavaScript file
var fileref=document.createElement('script')
fileref.setAttribute("type","text/javascript")
fileref.setAttribute("src", filename)
}
else if (filetype=="css"){ //if filename is an external CSS file
var fileref=document.createElement("link")
fileref.setAttribute("rel", "stylesheet")
fileref.setAttribute("type", "text/css")
fileref.setAttribute("href", filename)
}
if (typeof fileref!="undefined")
document.getElementsByTagName("head")[0].appendChild(fileref)
}
loadjscssfile("jquery.js","js");
I normally use the following code to find out once my image has loaded:
document.getElementById("header_logo").src = "logo.png"; // load top logo
var header_logo = document.getElementById("header_logo");
header_logo.onload = function(e) {
// do something here, the file has loaded
}
but I can't work out how to check once my JS has been loaded..
Any ideas?
(I can't use jQuery.)
You could add a function to the onload event:
function loadjscssfile(filename, filetype, onload) {
//if filename is a external JavaScript file
if (filetype == "js") {
var fileref = document.createElement('script');
fileref.type = "text/javascript");
fileref.onload = onload;
fileref.src = filename);
document.getElementsByTagName("head")[0].appendChild(fileref);
return;
}
//if filename is an external CSS file
if (filetype == "css") {
var fileref = document.createElement("link");
fileref.rel = "stylesheet";
fileref.type = "text/css";
fileref.onload = onload;
fileref.href = filename;
document.getElementsByTagName("head")[0].appendChild(fileref);
return;
}
}
loadjscssfile("jquery.js","js", function() { alert(this.src); });
In HTML 4.01 the load event was onlly supported by body and frameset elements, though many support it for img elements and some for script elements.
In HTML5, script elements have beforescriptexecute, afterscriptexecute and load events that are dispatched at relevant times in the script element's life. However, support for those events is likely not available in many browsers in use so not to be relied upon.
The most robust way to see if a script has loaded is to test for a value of a variable that is assigned a value by the last bit of code to be executed, e.g. final statements like:
var loadedScripts = loadedScripts || {};
loadedScripts.fooScript = true;
Then you can test for it:
if (loadedScripts.fooScript) {
// loaded
} else {
// not loaded
}

Categories