I see this was brought up before without being resolved. I have several audio files in one field. I only want one of them to randomly play when I click play or if audio plays automatically only one plays.
I’ve been working with code to put in the card template but nothing works. Any advice?
1 Like
The basic approach is described here:
- Randomizing card content
- Playing audio using JS
Feel free to ask if you require more detailed instructions.
There’s also an implementation of exactly what you describe in this template. It is intertwined with other code on the card, though, so the feature might not be as easy as copy and paste onto your cards, but should still be useful as a reference.
6 Likes
Hi, I tried the “Randomizing card content” following your instructions but this didn’t randomize the sound for me. I still had two audio file buttons show up for each “[sound:…]” file.
I worked on the script below with AI and I can now get a file to play randomly, though it only works when the automatic play is turned off. Is there a way to get around this? I have a script that plays a file randomly automatically when loading up a card but likewise the setting in Anki must be turned off. Randomly playing an audio file shouldn’t be this difficult 
{{Audio}}
<script>
(function() {
setTimeout(() => {
// Get all audio buttons that Anki created
let audioButtons = document.querySelectorAll('.replaybutton, .soundLink');
if (audioButtons.length > 1) {
// Pick random index
let randomIndex = Math.floor(Math.random() * audioButtons.length);
// Store original onclick handlers
let originalClicks = [];
audioButtons.forEach((btn, i) => {
originalClicks[i] = btn.onclick;
});
// Hide all original buttons
audioButtons.forEach(btn => {
btn.style.display = 'none';
btn.style.visibility = 'hidden';
});
// Create SINGLE new button
let newButton = document.createElement('a');
newButton.className = 'soundLink';
newButton.href = '#';
newButton.textContent = '🔊';
newButton.style.display = 'inline-block';
// Function to play our random audio
const playRandomAudio = function(e) {
if (e) {
e.preventDefault();
e.stopPropagation();
}
// Stop any currently playing audio
let allAudio = document.querySelectorAll('audio');
allAudio.forEach(audio => {
audio.pause();
audio.currentTime = 0;
});
// Execute the original click handler for our random audio
if (originalClicks[randomIndex]) {
originalClicks[randomIndex].call(audioButtons[randomIndex], e || new Event('click'));
}
};
// Add click handler to our button
newButton.onclick = playRandomAudio;
// Replace container with our new single button
let container = document.getElementById('audio-container');
container.innerHTML = '';
container.appendChild(newButton);
// Override Anki's 'r' key behavior - ALWAYS set this up
document.addEventListener('keydown', function(e) {
if (e.code === 'KeyR' && !e.ctrlKey && !e.altKey && !e.metaKey) {
e.preventDefault();
e.stopPropagation();
playRandomAudio(e); // Use our custom playback function
return false;
}
}, true);
// Optional: Auto-play (remove these 3 lines if you don't want it)
// setTimeout(() => {
// playRandomAudio();
// }, 100);
}
}, 150);
})();
</script>
I can’t say what’s going wrong for you without seeing your implementation, but I tried to put the linked pieces into a fresh basic card template and they functioned as expected:
Before randomization:
After randomization:
AI’s solution tries to do quite a few meaningless things (like calling pause() on <audio> tags, when they don’t exist if [sound:...] is used, or overriding ‘r’ key, when Anki shortcuts are processed outside of the webview and are not accessible to card scripts at all), so it’s hard to say how that was supposed to work in the first place and, consequently, why it didn’t.
I rechecked the JS for playing random audio from the previous post – calling click() on a randomly selected audio does work and stops any previously initiated playback, including autoplayed sound. You might hear a moment of autoplayed audio before it is cut off by the script, but only if the card template as a whole is too large and takes a noticeable amount of time to load. For simple cards, it functions just fine with enabled autoplay.
2 Likes