# JavaScript replace, insert audio file if text string

**URL:** <https://forums.ankiweb.net/t/javascript-replace-insert-audio-file-if-text-string/35730>\
**Category:** Card Design\
**Created:** [October 14, 2023, 11:16am UTC](https://forums.ankiweb.net/t/javascript-replace-insert-audio-file-if-text-string/35730 "2023-10-14T11:16:17Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![mlmmr](https://avatars.discourse-cdn.com/v4/letter/m/df705f/32.png) [@mlmmr](https://forums.ankiweb.net/u/mlmmr)\
**Post date:** [October 14, 2023, 11:16am UTC](https://forums.ankiweb.net/t/javascript-replace-insert-audio-file-if-text-string/35730/1 "2023-10-14T11:16:17Z")

</div>

Hi!

I use this script to replace certain text strings with images whenever they are present in a field:

```auto
<div id=front>{{Front}}</div>
<script>
    var str = document.getElementById("front").innerHTML;
        var res = str.replace('1', "<img src='_1.png'>");
    document.getElementById("front").innerHTML = res;
</script>

```

Is it possible to do the same for audio?

So whenever `1` is present in the field, the saved audio file `_1.wav` is played, just as if the field were to contain `[sound:_1.wav]`.

I’ve tried a few different things but can’t get it to work. This for example just plays the audio regardless of if `1` is present in the field or not:

```auto
var res = str.replace('1', "[sound:_1.wav]");

```

If I instead use this script I get what I want…

```auto
<script>
var audioElement = new Audio('_1.wav');
var field = document.getElementById('front').innerText;
if (field.includes('1')) {
  audioElement.play();
}
</script>

```

… only it results in all audio files playing at the same time if I have several present in the field.

Could someone help me out a bit?

---

<div class="post-metadata">

**Author:** ![hkr](https://avatars.discourse-cdn.com/v4/letter/h/c6cbf5/32.png) [@hkr](https://forums.ankiweb.net/u/hkr)\
**Post date:** [October 14, 2023, 7:22pm UTC](https://forums.ankiweb.net/t/javascript-replace-insert-audio-file-if-text-string/35730/2 "2023-10-14T19:22:10Z")

</div>

You can try the following:

```html
<div id="front">{{Front}}</div>
<div id="audio-players" />

<script>
    var audioMap = [
        ["foo", "_foo.mp3"],
        ["bar", "_bar.mp3"],
        ["baz", "_baz.mp3"],
    ];

    var field = document.getElementById("front").innerText;
    var index = 0;
    var audios = audioMap
        .filter(([word, _]) => field.includes(word))
        .map(([_, file]) => {
            const audio = new Audio(file);
            audio.controls = true;
            audio.addEventListener(
                "ended",
                () => {
                    if (++index < audios.length) {
                        audios[index].play();
                    }
                },
                { once: true },
            );
            return audio;
        });

    document.getElementById("audio-players").append(...audios);

    if (audios.length) {
        audios[0].play();
    }
</script>

```

If you do not wish to display the players, delete the following three lines:

- `<div id="audio-players" />`
- `audio.controls = true;`
- `document.getElementById("audio-players").append(...audios);`

---

<div class="post-metadata">

**Author:** ![mlmmr](https://avatars.discourse-cdn.com/v4/letter/m/df705f/32.png) [@mlmmr](https://forums.ankiweb.net/u/mlmmr)\
**Post date:** [October 15, 2023, 6:48am UTC](https://forums.ankiweb.net/t/javascript-replace-insert-audio-file-if-text-string/35730/3 "2023-10-15T06:48:10Z")

</div>

Thank you @hkr, I’ve tried your script now. I have two issues, the audio is played in the order of the ` var audioMap = [` mapping and not the order of the card (so if I have `1 3 2` in a field it is played as `1 2 3` regardless). And if the same text string exists at several different places in a field it is only played once, I need it to be played for every instance. Can this be fixed?

---

<div class="post-metadata">

**Author:** ![hkr](https://avatars.discourse-cdn.com/v4/letter/h/c6cbf5/32.png) [@hkr](https://forums.ankiweb.net/u/hkr)\
**Post date:** [October 15, 2023, 4:47pm UTC](https://forums.ankiweb.net/t/javascript-replace-insert-audio-file-if-text-string/35730/4 "2023-10-15T16:47:09Z")

</div>

I misunderstood what you want to do. I think maybe the following is what you want (or something close to it).

```html
<div id="front">{{Front}}</div>
<div id="audio-players" />

<script>
    var audioMap = new Map([
        ["foo", "_foo.mp3"],
        ["bar", "_bar.mp3"],
        ["baz", "_baz.mp3"],
    ]);

    // https://stackoverflow.com/a/3561711
    function escapeRegex(string) {
        return string.replace(/[/\-\\^$*+?.()|[\]{}]/g, "\\$&");
    }

    var words = [...audioMap.keys()].map(escapeRegex);
    var regexp = new RegExp(words.join("|"), "g");
    var field = document.getElementById("front").innerText;
    var index = 0;
    var audios = [...field.matchAll(regexp)].map(([word]) => {
        const audio = new Audio(audioMap.get(word));
        audio.controls = true;
        audio.addEventListener(
            "ended",
            () => {
                if (++index < audios.length) {
                    audios[index].play();
                }
            },
            { once: true },
        );
        return audio;
    });

    document.getElementById("audio-players").append(...audios);

    if (audios.length) {
        audios[0].play();
    }
</script>

```

---

<div class="post-metadata">

**Author:** ![mlmmr](https://avatars.discourse-cdn.com/v4/letter/m/df705f/32.png) [@mlmmr](https://forums.ankiweb.net/u/mlmmr)\
**Post date:** [October 15, 2023, 5:59pm UTC](https://forums.ankiweb.net/t/javascript-replace-insert-audio-file-if-text-string/35730/5 "2023-10-15T17:59:30Z")

</div>

Works like a charm 👍 Thank you for the help, I appreciate it!

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex002/uploads/anki2/original/1X/8f1279ababc5879d54e4838989f606cfe55af8c7.jpeg) [@system](https://forums.ankiweb.net/u/system)\
**Post date:** [November 14, 2023, 6:00pm UTC](https://forums.ankiweb.net/t/javascript-replace-insert-audio-file-if-text-string/35730/6 "2023-11-14T18:00:04Z")

</div>

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.
