[Web] SpeechSynthesis - TTS API

SpeechSynthesis는 Web Speech API의 하나로 주어진 텍스트를 소리로 바꿔주는 TTS API이다. SpeechSynthesis 이전에도 TTS 서비스가 있었지만, 이들은 유료이거나 웹에서 사용하기 불편한 경우가 대부분이었는데 SpeechSynthesis의 경우 브라우저에 내장되는 API이므로 무료로 쉽게 사용할 수 있다는 장점이 있다.

물론 Web Speech API 자체가 아직 draft에 해당하기 때문에 브라우저가 지원해야만 사용 가능하다는 문제는 있지만, 2016년 8월 15일 현재 데스크탑에서는 크롬과 사파리, 안드로이드 기본 브라우저인 크롬, 아이폰의 기본 브라우저인 사파리에 지원하고, 파이어폭스는 9월에 지원할 예정이므로 대부분의 모던 브라우저에서는 사용할 수 있다.

speechSynthesis는 5개의 함수를 가지고 있다. 그중 4개는 speak, cancel, pause, resume이다. 이를 이용해서 재생할 음성을 추가하거나 취소하거나 일시 정지할 수 있다.

이 중 speak 함수는 SpeechSynthesisUtterance를 인자로 받는다. speak 함수를 호출했을 때, 이미 재생 중인 utterance가 없고 speechSynthesis가 pause 되어 있지 않으면, 요청된 utterance는 즉시 재생된다. 하지만 이미 재생 중인 utterance가 있거나 speechSynthesispause 되어 있다면, utterance는 바로 재생되지 않고 queue에 저장되었다가 후에 재생된다.

따라서 실제로 언제 재생되는지는 utterance의 콜백을 통해서만 알 수 있다. 이벤트의 종류에 따라서 onstart, onend, onerror, onpause, onresume 등의 콜백을 등록할 수 있다.

또한, SpeechSynthesisUtterance는 6개의 속성을 가지고 있다.

첫 번째 속성은 text로 읽을 텍스트를 지정한다. 객체를 생성할 때 생성자에 넘겨줄 수도 있고, 생성한 뒤 text attribute에 값을 할당할 수도 있다.

두 번째 속성은 lang으로 어떤 언어로 읽을지를 결정해준다. 만약 아무런 값도 지정하지 않으면 기본적으로는 html 태그의 lang 값을 이용한다.

세 번째 속성은 voice다. voiceSpeechSynthesisVoice 객체를 값으로 설정할 수 있는데, 아무런 값도 할당 안 하면 default voice를 사용하게 된다.

네 번째 속성은 volume이다. volume은 최소 0에서 최대 1의 값을 가질 수 있다. 아무런 값을 주지 않으면 기본값은 1이 된다.

다섯 번째 속성인 rate는 소리의 속도를 결정한다. 기본값은 1이고, 값이 커지면 빠른 속도로, 값이 작으면 느린 속도로 발음한다.

마지막 속성인 pitch는 소리의 전체적인 높이를 결정한다. 기본값은 1이고, 0에서 2 사이의 값을 가질 수 있는데 최저와 최고일때 어떤 음을 가질지는 브라우저의 구현에 따라서 다르다.

speechSynthesis에 있는 마지막 함수는 getVoices다. 이 함수는 SpeechSynthesis가 사용할 수 있는 SpeechSynthesisVoice 목록을 반환한다. 하지만 처음에는 아무런 값도 없을 수도 있다. 사용할 수 있는 voice 목록이 초기화되면 voiceschanged 이벤트가 호출되는데, 이 이벤트가 호출되어야 getVoices 이벤트가 정상적으로 사용할 수 있는 voice 목록을 리턴한다.

이렇게 가지고 온 SpeechSynthesisVoicename, lang, voiceURI, localService, default 5개의 속성을 가진다. 이때 lang은 해당 목소리가 어느 나라의 언어를 표현하는지를 나타내고, name은 목소리의 이름을 나타낸다. 하지만 이 둘 다 유일할 것이 보장되지 않는다. 어떤 나라의 언어를 표현하는 목소리가 여러 개 있을 수 있고, 같은 이름의 서로 다른 목소리가 존재할 수도 있다. 하지만 현재 안드로이드 크롬에는 버그가 있어서 voice를 설정해도 목소리가 변하지 않고, lang을 설정해야 목소리가 변한다. 따라서 한 언어에 여러 개의 목소리가 있다고 해도 한 가지 목소리밖에 쓰지 못한다.

SpeechSynthesis는 데스크탑과 모바일 등 다양한 플랫폼에서 사용할 수 있고, 사용하기도 편하다. 하지만 현재 크롬 구현체에는 약간 문제가 있다. 현재는 크롬은 60개 이상의 문자를 말하고 나면 그다음 utterance에 대해서 소리가 끝나도 end 이벤트도 error 이벤트도 발생하지 않는다. 라이브러리의 버그로 보이는데 작년 6월부터 이슈가 나왔던 문제인데 올해 6월 드디어 원인이 나왔다. 가비지 컬렉팅과 관련된 문제로 보이는데, utterance를 전역변수로 보관하고 있으면 문제가 발생하지 않는다. 원인이 나왔으니 곧 고쳐질 것으로 보이지만, 그동안은 utterance를 전역변수에 저장하는 식으로 우회해야 한다.

댓글

이 블로그의 인기 게시물

[C++] enum class - 안전하고 쓰기 쉬운 enum

RAII는 무엇인가

Log Aggregator 비교 - Scribe, Flume, Fluentd, logstash

[Python] cache 데코레이터로 최적화하기