JS Random soundfiles / TTS voices & playback speed

Hi

I have two questions related to playing soundfiles and TTS (in Ankimobile, so no- add-on)

I have a ton of pre-generated sounds via Chinese Support Redux, I’m satisfied with the sound for many of them (especially I can adjust things with specific sound files when a character has multiple pronounciations)

BUT

  1. I’d like to be able to accelerate those pre-recorded soundfiles a little.

  2. Also I’d like to be able to get random voices to not get too used to one version of playback.
    Today I tried different voices of TTS, results are unequal with different words but I think that would be really good if every time a card comes I hear a different version.

(Also, obviously, TTS already allow to change speed to some extent so that’s good)

Obviously when I got all these fields together in my card they all play one after the other which is not great…
{{Audio}}
{{tts zh_CN voices=Apple_Yu-shu:Hanzi}}
{{tts zh_CN voices=Apple_Ting-Ting:Hanzi}}
{{tts zh_CN voices=Apple_Li-mu:Hanzi}}

Any suggestions to do pick up randomly among them which one is played?

Thanks in advance for your help!

Julien

1 Like

EDIT: I just noticed I completely ignored your first request. I vaguely remember Damien replying to a post somewhere (found it) that that function isn’t supported. It’s possible though that was just a reply to a non-technical user, and could be done using JS. I’d be curious to see if someone can figure it out.


But regarding the second point:

Hi there,

this script works for me, with one caveat:

Neither do I use TTS, nor AnkiMobile, so you'll have to see if it works for your use case.

From experience, I think it’s only AnkiDroid that uses a different selector for audio (.replaybutton). And as long as TTS generates the same clickable object as normal audio (which I assume it does), this should be a simple solution for your problem.

<script>
/*-----------------------------------------
 * Choose random audio from card
 * by J. Hirsch | @DonCiervo
-----------------------------------------*/
{
		function randomInt(max) {
			return Math.floor(Math.random() * max);
		}		

		const audios = [...document.querySelectorAll(".soundLink")];
		rand = randomInt(audios.length)
		audios[rand].click();
}
</script>

Please let me know either way, I’m curious.

3 Likes

Hi @ODeer
Thank you so much, I does work in AnkiMobile !
Ok the querySelector detects every player button on the page and clicks one, makes sense !
In case the function is on the front card (ex: front listen → answer vocab) the sound is repeated on the answer side (as part of {{FrontSide}}) , but that’s not too much of an issue I guess.

Yes indeed I saw a few other posts mentioning this question of speed, but they were all quite old posts so I was hoping there would be some news.
Hi Damien by any chance do you know if there’s any news on that front? @dae

Best,

Julien

AnkiMobile doesn’t provide a way to adjust the speed of audio files I’m afraid.

Thanks Damien for your quick reply.
I see, so it really does make sense to randomize different voices with different speeds then, to diversify testing a bit.

Now while I have you @dae, if you look at @ODeer’s code :
I installed it in my decks and while it works seemlessly in Anki desktop, on Anki Mobile for some reason now there’s often a slight delay when open a page containing that random choice of audio to click. Do you see any reason why?
(If you need I can see you a copy of my deck by email)

Best,

Julien

Unless there is something specific you need {{FrontSide}} for, you can just copy the HTML from the front to the back of the template (minus the JavaScript ofc) and it won’t repeat when flipping the card.

Oh sure, I tried that actually, but in that case without the JS the audio will all play in turn.

And if I remove the audio… well the audio buttons disappear, so it’s impossible de replay if needed :frowning:

That’s why I’d rather have repetition on card flip. It’s actually not that bad, and in my case only happens for card 2 with pinyin-audio → character-french. It’s not that bad because the sound may reinforce memorization when discovering the character.

I think you’re making this more complicated than it has to be.

In your deck options, you can find Audio settings. Make sure these are toggled (well, really, the first one is important, but doesn’t matter in your case).

This means you can include Audio fields wherever - and only add the JavaScript whenever you want a random audio to be played.

2 Likes

Oh indeed I completely missed that second option yesterday when I needed to stop autoplay.
Now it works if instead of {{FrontSide}} I just copy the content of the front minus the function, like you suggested.
Thank you so much !

Hi Damien @dae

Sorry to bother you again but I think you missed my second question (related to Anki Mobile) hidden inside the rest of the discussion with ODeer.

I installed his function in my decks to randomize between different voices, and while it works seemlessly in Anki desktop, on Anki Mobile for some reason now there’s almost often a slight delay when open a card containing that random choice of audio to click.

Do you see any reason why?
I tested this on both iPad and iPhone, and result is the same. It seems the function takes a long time to evaluate, or maybe it’s the time to instantiate all the sound objects before clicking one of them randomly?
(If you need I can send you a copy of my deck by email, I just forgot how to create a new support ticket for Anki Mobile…)

Many thanks in advance !
Best,

Julien

Please bear in mind that I can’t provide support for JavaScript: Styling & HTML - Anki Manual

I’m not sure exactly what the problem is, but perhaps you could work around it by deferring the script or performing the click after a delay.

1 Like

Thanks for the tip Damien @dae ! Yes I understand perfectly you can’t handle how everyone use Javascript, especially noobs like me :sweat_smile:

Your answer was a great clue I think :
I put that line inside a 10 milliseconds delay, and it seems it did the trick and the app is much more reactive on iPad. A few cases still slow down, I need to figure out why. I’ll keep experimenting and hopefully I can find the right delayvalue.

setTimeout(function() {
  audios[randomInt(audios.length)].click();
}, 10);

Thanks again !

1 Like

Sorry to bother you. I can’t make your code run on the Anki desktop app.
Am I doing something wrong?

{{Front}}

<br>

{{audio1}}
{{audio2}}
{{audio3}}

<script>

{
		function randomInt(max) {
			return Math.floor(Math.random() * max);
		}		

		const audios = [...document.querySelectorAll(".soundLink")];
		rand = randomInt(audios.length);
		audios[rand].click();
}

</script>

Both tumblers to disable autoplaying audios are enabled. Adding a setTimeout function to add a delay like julienvincenot did doesn’t help. Can it be run on desktop Anki at all?

Does this mean it works on AnkiMobile for you or are you trying to run it on desktop only?

Not as far as I can tell. It works on desktop for me.

What version of Anki are you running? And does the replay button appear on your cards in the first place?

2 Likes

Here’s my code if you want to compare.
Like @ODeer it works on Anki Desktop (and Mobile for me).
I put the function before but I think it works even if I put after the sounds.

<script>
{
		function randomInt(max) {
			return Math.floor(Math.random() * max);
		}	
		const audios = [...document.querySelectorAll(".soundLink")];
setTimeout(function() {
  audios[randomInt(audios.length)].click();
}, 10);
		
}
</script>

<div style='font-family: Hoefler Text; font-size: 70px;'>{{Pinyin}}</div>

  {{Audio}}
  {{tts zh_CN voices=Apple_Ting-Ting:Hanzi}}
  {{tts zh_CN voices=Apple_Li-mu:Hanzi}}
  {{tts zh_CN voices=Apple_Yu-shu:Hanzi}}
  {{tts zh_TW voices=Apple_Mei-Jia:Hanzi}}

I also attach a screenshot of what it’s supposed to look like on the front of a “card 2” on my setup (pinyin + audio)

3 Likes

I am only using the desktop version. I don’t have a mobile one. The version of my Anki app is 2.1.54 (b6a7760c)⁩ for macOS.

And does the replay button appear on your cards in the first place?

No. I don’t have this one. What is the “replay button”? Do you mean some media play button – :arrow_forward: ?

Thanks for the screenshots and code. But I still can’t make the code work for me. Here are mine:



How did you make the circled play buttons :arrow_forward: appear on your cards? I don’t have these ones.

Yeah that’s what I was going to ask you : how come you don’t have any of those buttons? :sweat_smile:

Did you ever get some sound running in Anki cards? Any sound object (fields represented by {{ … }} with Audio in it) should show one such icon. So in my case 5 sounds → 5 icons.

What happens if you remove the <script> ... </script> part?

Also, I wonder, did you try renaming your soundfiles? Mp3 format is fine, but I’ve had some cases where too long phrases in audio filenames could not be read by Anki. Maybe make them shorter and more descriptive…?

If you go to Tools >> Preferences what do you see? There is an option to show play buttons on cards, which should be toggled by default.

 

Try this before you fiddle around with the file names!

2 Likes

Thank you so much! You’ve made my day. Everything works great now.