Reputation: 4514
I have a bit of code in javascript that generates a wav file and then attaches it to a button so it can be played:
function makeWav(){
$.get(("../testsound/getsound.pl?text="+document.myform.outputtext.value));
setTimeout(callback, 500);
return false;
}
function callback() {
var audio = new Audio('http://www.joereddington.com/testsound/hope.wav');
audio.load();
audio.play();
// $("#player").html("<embed src=http://www.joereddington.com/testsound/hope.wav autostart=true >");
}
Obviously the hope.wav file changes very regularly. But my problem is that only the first .wav to be generated is played unless I completely reload the site each time. How do I make the (presumably) callback function go and get a new version of the .wav rather than the cache?
EDIT: Works fine on the iPad - I'm having this problem in firefox.
Upvotes: 17
Views: 25344
Reputation: 2421
In Vue 3 it helped me to use preload="none"
and to change the fileURL with an ?[Date.now()]
suffix, every time there is an update in the audio file (change shown with loading prop).
It seems the ?[date12233333]
suffix tricks browsers cache, and makes it load the audio file again.
// VUE 3 example
<template>
<div v-if="!src || loading">
... loading
</div>
<audio v-else controls preload="none" :src="src" type="audio/mpeg" />
</template>
<script>
import {ref, watch} from "vue";
export default {
name: "Audio",
props: {
loading: {
type: Boolean,
required: true,
},
src: {
type: String,
required: true,
},
setup(props) {
const srcUpdated = ref(null)
watch(() => props.loading, () => {
srcUpdated.value = props.src + "?" + Date.now();
})
return {
srcUpdated
}
}
}
}
</script>
Upvotes: 0
Reputation: 1895
For those trying to change the src
attribute of a source element, I found this spec note .
Dynamically modifying a source element and its attribute when the element is already inserted in a video or audio element will have no effect. To change what is playing, just use the src attribute on the media element directly
So lets say you have:
<audio>
<source src='./first-src'/>
</audio>
To modify the src:
<audio src='./second-src'/>
<source src='./first-src'/>
</audio>
Upvotes: 10
Reputation: 1
function Speech()
{
var fileName = new Date().getTime();
$.ajax({
url: Host + "api/speech",
data: {
'text': $("input[id='searchBox']").val(),
'language': $("input[id='languageChoice']:checked").val(),
'fileName': fileName
},
dataType: "json",
type: "Get",
contentType: "application/json; charset=utf-8",
success: function () {
var audioUrl = Host + '/Assets/Audio/' + fileName + '.mp3';
var audio = new Audio(audioUrl);
audio.load();
audio.play();
}
});
}
Upvotes: 0
Reputation: 6072
You can't directly control the caching from within your JavaScript. Retrieving files is the responsibility of the browser, which is why you're getting different results on different browsers.
When a web server sends a file to the browser, it also sends some headers with extra details about that file. One of them is the Cache-Control
header, which tells the browser if the file is cacheable. Sending a Cache-Control: no-cache
header should stop browsers caching the file, and make subsequent requests retrieve the file from your server.
On Apache, you can use an .htaccess
file or a <Directory>
rule in your server configuration to change the caching for files in the /testsound
directory. Put the following in /testsound/.htaccess
:
<ifModule mod_headers.c>
Header set Cache-Control no-cache
</ifModule>
Another technique is to include a "cache-busting" parameter in your request. Your web server is serving a static file - but your web browser doesn't know that. For all it knows, a request for /testsound/hope.wav?cb=foo
could return a completely different file to a request for /testsound/hope.wav?cb=bar
. Thus, if you include an always-changing parameter in your web request, the browser won't find it in its cache and it will retrieve the new file. A timestamp is a good choice:
function callback() {
var url = "http://www.joereddington.com/testsound/hope.wav?cb=" + new Date().getTime();
var audio = new Audio(url);
audio.load();
audio.play();
}
Upvotes: 35