본문 바로가기

web tts

web by 코나인 2023. 5. 15.
반응형

html과 javascript를 사용해서 텍스트를 읽어주는 코드.

 

 

HTML(voice.html)

<html>
<head>
<script src="./voice.js" defer></script>
</head>
<body onload="loadVoices()">
<div>
    <label for="inputThingsToSay">Things to Say:</label>
</div>
<div>
    <textarea id="inputThingsToSay" rows="10" cols="50">This is a test!</textarea>
</div>
<div>
    <label for="selectTimbre">Timbre:</label>
    <select id="selectTimbre"></select>
</div>
<div>
    <label for="inputPitch">Pitch:</label>
    <input id="inputPitch" type="number" value="1"></input>
</div>
<div>
    <label for="inputSpeed">Speed:</label>
    <input id="inputSpeed" type="number" value="1"></input>
</div>
<div>
    <button id="buttonSay" onclick="buttonSay_Clicked()">시작</button>
    <button id="buttonStop" onclick="buttonStop_Clicked()">종료</button>
</div>

</body>
</html>

 

Script(voice.js)


function loadVoices() {
  var synthesizer = window.speechSynthesis;
  synthesizer.onvoiceschanged = loadVoices_VoicesLoaded;
  synthesizer.getVoices();
}

function handleError(error) {
  console.error("TTS 에러 발생:", error);
  alert("TTS를 사용할 수 없습니다. 브라우저 설정을 확인해주세요.");
}


function loadVoices_VoicesLoaded() {
  window.speechSynthesis.onerror = handleError;
  var synthesizer = window.speechSynthesis;
  var systemVoices = synthesizer.getVoices();
  systemVoices.addLookups("name");
  Voice.systemVoiceLookup = systemVoices;

  var selectTimbre = document.getElementById("selectTimbre");
  for (var i = 0; i < systemVoices.length; i++) {
    var systemVoice = systemVoices[i];
    var optionTimbre = document.createElement("option");
    optionTimbre.text = systemVoice.name;
    optionTimbre.systemVoice = systemVoice;
    selectTimbre.appendChild(optionTimbre);
  }
}

var voice;
function buttonStop_Clicked() {
  if (voice) {
    voice.stop();
  }
}

function buttonSay_Clicked() {
  var inputThingsToSay = document.getElementById
    (
      "inputThingsToSay"
    );
  var selectTimbre = document.getElementById("selectTimbre");
  var inputPitch = document.getElementById("inputPitch");
  var inputSpeed = document.getElementById("inputSpeed");

  var timbreName = selectTimbre.selectedOptions[0].text;
  var pitch = parseFloat(inputPitch.value);
  var speed = parseFloat(inputSpeed.value);
  var thingsToSay = inputThingsToSay.value;

  voice = new Voice
    (
      "Default",
      timbreName,
      pitch,
      speed
    );
  voice.say(thingsToSay);
}

function ArrayHelper() {
  // extension class
}
{
  Array.prototype.addLookups = function (keyName) {
    for (var i = 0; i < this.length; i++) {
      var item = this[i];
      var keyValue = item[keyName];
      this[keyValue] = item;
    }
  }
}

function Voice(name, timbreName, pitch, speed) {
  this.name = name;
  this.timbreName = timbreName;
  this.pitch = (pitch == null ? 1 : pitch);
  this.speed = (speed == null ? 1 : speed);

  this.systemUtterance = new SpeechSynthesisUtterance();
  this.systemUtterance.onend = this.say_Ended.bind(this);
  this.systemUtterance.onpause = this.stop.bind(this);
}
{
  // instance methods

  Voice.prototype.say = function (thingToSay, callback, contextForCallback) {
    this.callback = callback;
    this.contextForCallback = contextForCallback;

    this.isSpeaking = true;

    var voices = Voice.systemVoiceLookup;

    var utterance = this.systemUtterance;
    utterance.voice = voices[this.timbreName];
    utterance.text = thingToSay;
    utterance.pitch = this.pitch;
    utterance.rate = this.speed;

    window.speechSynthesis.speak(utterance);
  }

  Voice.prototype.say_Ended = function () {
    this.isSpeaking = false;
    if (this.callback != null) {
      this.callback.call(this.contextForCallback);
    }
  }

  Voice.prototype.stop = function () {
    window.speechSynthesis.cancel();
  }
}
반응형

댓글