JRS
April 30, 2025, 2:43pm
1
I have a card type with two audio fields on the front that I would like to autoplay when the card is shown.
I have the same two audio fields on the back of the card. I don’t want them to auto play, but I do want to be able to click them to play if needed.
Currently I have autoplay turned off, and I have pasted the below script (from another thread) into the front field of the card. This autoplays the first audio on front but doesn’t autoplay the second.
<script>
var elem = document.querySelector(".soundLink, .replaybutton");
if (elem) {
elem.click();
}else{
window.onload = function(){
var elem = document.querySelector(".soundLink, .replaybutton");
if (elem) { elem.click();}
}
}
</script>
Can this script be edited to autoplay all audio fields on the front of the card?
Or alternatively, could I just turn the deck autoplay setting on and add some kind of script so it is ignored on the back of the cards?
Thanks for the help.
It probably just needs a for
loop, which loops over all elements with the “.soundLink, .replaybutton” classes, then clicks using .click()
.
I don’t think that’s possible. The autoplay setting plays audio with python as far as I know, which isn’t controllable via js.
If you use the {{FrontSide}}
special field on your back template, the same 2 audio fields will show and not autoplay. Field Replacements - Anki Manual
Anon_0000:
It probably just needs a for
loop, which loops over all elements with the “.soundLink, .replaybutton” classes, then clicks using .click()
.
A simple loop won’t do, unfortunately, as every next click
will interrupt the audio playback initiated by the previous one. A fixed delay can be added, but it’s not ideal solution, if the audio lengths vary too much. (it would be nice to have some kind of an API for that )
Also, if using the .click()
with AnkiDroid, this should be taken into account as well:
opened 06:45AM - 19 Mar 23 UTC
closed 06:45AM - 19 Mar 23 UTC
Bug
Needs Triage
### Checked for duplicates?
- [X] This issue is not a duplicate
### What are t… he steps to reproduce this bug?
1. Unzip the file and import the collection: [money.zip](https://github.com/ankidroid/Anki-Android/files/11010259/money.zip)
2. Preview the card with the Front side of "Money with Mathjax".
3. Reveal the backside.
<details> <summary>Card Details:</summary>
The card contains 4 fields: Front, Back, Audio, and AudioMoney.
Front:
```
{{Front}}
```
Back:
```
{{Front}}
<hr id=answer>
{{Back}}
{{Audio}}
<span id="audiomoney">{{AudioMoney}}</span>
<script>
( () => {
let x = document.querySelector("#audiomoney .soundLink, #audiomoney .replaybutton");
if (x) {
console.log("going to click money...");
x.click();
console.log("clicked on money");
}
})();
</script>
```
</details>
### Expected behaviour
The backside should show the loaded card.
### Actual behaviour
The backside is not displayed.
<details>
<summary>Screenshot:</summary>

</details>
### Debug info
```text
AnkiDroid Version = 2.16alpha94-debug
Android Version = 13
Manufacturer = Google
Model = sdk_gphone64_x86_64
Hardware = ranchu
Webview User Agent = Mozilla/5.0 (Linux; Android 13; sdk_gphone64_x86_64 Build/TE1A.220922.021; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/103.0.5060.71 Mobile Safari/537.36
ACRA UUID = 2daf5ce1-b594-44bb-b526-3ccb31f1a1e6
New schema = true
Scheduler = std2
Crash Reports Enabled = false
DatabaseV2 Enabled = true
```
### (Optional) Anything else you want to share?
This was tested multiple ways:
- My physical phone, with release 2.16alpha94 (from Github)
- Built with Android Studio and ran it on an emulator to [this commit](https://github.com/ankidroid/Anki-Android/commit/b07bf4dc5f90015ede4af51705d112bd67ec2f8c)
- The latest stable release version on Github (2.15.6), with the same emulator
### Background on what this code is doing in the first place (to prevent the x-y problem):
The main problem I was trying to solve is **to have a play button on the front side of the card, without having the audio played automatically**. However, I want audio to be automatically played on the backside of the card. There does not seem to be a built-in approach to simply not have an audio file play on any Anki implementation without turning off audio replays on all card sides, so my current approach is to have two audio files: `silence.wav` and (some sentence audio).wav, and use javascript to immediately play the `silence.wav` file. This approach only plays silence.wav, and overrides the natural order of how the audio is played (as if the user played `silence.wav` manually), thus the sentence audio does not play. (A different approach that I believe would work is to have a very very long silence.wav file, i.e. 24 hours long. This would remove the need of using javascript to play the file in order to stop the other file from playing).
Unfortunately, something weird is happening with AnkiDroid. The audio plays as expected, i.e. the card with the front side "Money" has two audio files: the first one plays "Realm of the mad god", and the second one plays "Money x7". The second audio file is correctly played, and skips the first audio file. However, adding mathjax (i.e. the card with "Money with Mathjax") visually reveals the main problem: it seems like the card never "fully loads". The webview on **both of these cards displays a persistent blue line at the top**, suggesting that some javascript is still running and never finishes. This also suggests that **Mathjax itself is not actually related to the problem**, but simply a side effect that visually reveals the problem.
<details>
<summary>Screenshot of blue line on card "Money"</summary>

</details>
Using Chrome's webview on the "Money with Mathjax" card, the `mathjax-needs-to-render` CSS class is forever present on the backside of the card, and is not replaced with `mathjax-rendered`, which is the reason why the card doesn't show in the first place. I believe this suggests that something in the `onPageFinished` function of `AnkiDroid/src/main/assets/scripts/card.js` doesn't properly run in the first place.
---
### Workaround
While writing this bug report, I basically rubber-ducked myself into a satisfactory workaround: we can use `onShownHook` and append a function to this array to play the audio. For example:
```js
(() => {
async function playMoney() {
let x = document.querySelector("#audiomoney .soundLink, #audiomoney .replaybutton");
if (x) {
console.log("going to click money...");
x.click();
console.log("clicked on money");
}
}
if (onShownHook !== undefined) {
onShownHook.push(playMoney);
}
})();
```
Due to a) "Javascript functionality is provided without any support or warranty" according to the Anki manual, b) this is a very niche bug that most people probably won't deal with, and c) there exists a satisfactory workaround, I'll be closing this issue despite it not being technically fixed. Hopefully, if anyone comes across the same issue, this can serve as a good reference for them!
### Research
- [X] I am reporting a bug specific to AnkiDroid (Android app)
- [X] I have checked the [manual](https://ankidroid.org/docs/manual.html) and the [FAQ](https://github.com/ankidroid/Anki-Android/wiki/FAQ) and could not find a solution to my issue
- [X] (Optional) I have confirmed the issue is not resolved in the latest alpha release ([instructions](https://docs.ankidroid.org/manual.html#betaTesting))
2 Likes
Why use .click()
anyways? Is there any advantage to just using .play()
(which works fine for ankidroid and desktop)? I did help another user once set it up in Conditional Audio Playback - #27 by Anon_0000 so I do have some experience with .play()
.
So it should be possible to play all audios using a loop after grabing them with something like a .querySelector
. The only thing that might be an issue is waiting for audio #1 to finish playing before audio #2 is played. Though I assume it should be solveable with HTMLMediaElement: ended event - Web APIs | MDN .
1 Like
Those would only work for audio files inserted as <audio>
tags instead of Anki’s native [sound:...]
, which makes it less convenient to add and harder to manage, since one will have to rename all files, adding underscores, and manually keep track of which files in the collection are used and which ones are not.
Yeah, this kind of threads seems to converge to the same kind of solutions each time :Selective autoplay of audio for certain notes - #22 by Eltaurus
1 Like
JRS
May 3, 2025, 2:30am
8
Thanks! Using {{FrontSide}} works well.
1 Like