Play/Pause/Stop Audio in Typewriter

Viewed 58

I will start streaming soon. I'm using Streamelements. So I found an overlay and was making a few changes to it. Typewrite is used when making alert boxes and I like it. I just want to add keyboard sound to it. But I couldn't do it. The sound I added continues to play until the alert ends. I want the sound to pause/stop after some words and the texts are over.

I tried to show what I am trying to do in the JS section. (Because my English is not too good.) I hope I explained what I want.

JS:


    const name='{name}';
    const amount='{amount}';
    const wrapData=(message)=>{
      return message.replace(/\b{name}\b/g, '<span class="username">{name}</span>').replace(/\{currency}{amount}\b/g, '<span class="amount">\{currency}{amount}</span>').replace(/\b{amount}\{currency}/g, '<span class="amount">{amount}\{currency}</span>').replace(/\b{amount}\b/g, '<span class="amount">{amount}</span>').replace(/\{currency}/g, '<span class="amount">\{currency}</span>');
    }
        const typewriter = new Typewriter('.text-container', {
        skipAddStyles:true,
        delay:50
    });
    
    const row1a=wrapData(`{row1}`);
    const row2a=wrapData(`{row2}`);
    const row3a=wrapData(`{row3}`);
    const row4a=wrapData(`{row4}`);
    var audio = new Audio('keyboard.wav');
    audio.play();
    typewriter.typeString(`<div class="row1 message" style="display: inline-block;">${row1a}</div>`)
          .pauseFor(200)
          .stop();
    audio.pause();
    typewriter.typeString(`<div class="added-divs">.</div>`)
          .pauseFor(200)
          .typeString(`<div class="added-divs">.</div>`)
          .pauseFor(200)
          .typeString(`<div class="added-divs">.</div>`)
          .pauseFor(200)
          .typeString(`<div class="added-divs">DONE!</div>`)
          .pauseFor(50)
          .stop();
    audio.play();
    typewriter.typeString(`<div class="row2 message">${row2a}</div>`)
          .pauseFor(50)
          .typeString(`<div class="row3 message">${row3a}</div>`)
          .pauseFor(50)
          .typeString(`<div class="row4 message">System Message: <span class="username">Thank you!</span></div>`)
          .pauseFor(50)
          .typeString(`<div class="row4 message" style="display: inline-block;">${row4a}</div>`)
          .pauseFor(200)
          .stop();
    audio.pause();
    typewriter.typeString(`<div class="added-divs">.</div>`)
          .pauseFor(200)
          .typeString(`<div class="added-divs">.</div>`)
          .pauseFor(200)
          .typeString(`<div class="added-divs">.</div>`)
          .pauseFor(200)
          .typeString(`<div class="added-divs">DONE!</div>`)
          .pauseFor(50)
          .start();

CSS

    @import url('https://fonts.googleapis.com/css?family={fontName}');
    * {
        font-family: '{{fontName}}', sans-serif;
        color:{{fontColor}};
        font-weight:{{fontWeight}};
    }
    
    body{
      background-image:url('{image}');
      background-size:contain;
      background-repeat:no-repeat;
      position:relative;
      margin:0px;
    
    }
    
    .text-container{
     width:100%;
      height:100%;
      position: absolute;
      top: 10px;
      padding-left:15px;
    }
    .alertbox-message-emote{
     height:1em; 
    }
    
    
    .added-divs {
        display: inline-block;
        color:{{row1FontColor}};
        font-weight:{{row1FontWeight}};
        font-size:{{row1FontSize}}px;
    }
    
    .row1{
        color:{{row1FontColor}};
        font-weight:{{row1FontWeight}};
        font-size:{{row1FontSize}}px;
        animation-delay:1s;
    }
    .row2{
        color:{{row2FontColor}};
        font-weight:{{row2FontWeight}};
        font-size:{{row2FontSize}}px; 
        animation-delay:3.5s;
    }
    .row3{
        color:{{row3FontColor}};
        font-weight:{{row3FontWeight}};
        font-size:{{row3FontSize}}px; 
        animation-delay:5.5s;
    }
    .row4{
        color:{{row4FontColor}};
        font-weight:{{row4FontWeight}};
        font-size:{{row4FontSize}}px; 
        animation-delay:7.5s;
    }
    .username{
      color:{usernameFontColor};
    }
    .amount{
      color:{amountFontColor};
    }

HTML

    <script src="https://unpkg.com/typewriter-effect@latest/dist/core.js"></script>
    
    <div class="text-container">
      <div class="row1 message"></div>
      <div class="row2 message"></div>
      <div class="row3 message"></div>
      <div class="row4 message"></div>
    </div>
1 Answers

The play method returns a Promise: https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play. The library you are using offers a callFunction method that you can run before start so that it will run after all previous methods finished.

Combining the two:

const startTyping = async () => {
  await audio.play()
  typewriter
    .typeString(...)
    .callFunction(() => audio.pause())
    .start()
}

startTyping()
Related