๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
web

Web Speech API ์™„๋ฒฝ ๊ฐ€์ด๋“œ - ์Œ์„ฑ ์ธ์‹๊ณผ TTS๋กœ ์›น์•ฑ ์ ‘๊ทผ์„ฑ ๋†’์ด๊ธฐ

by bamsik 2026. 2. 15.
๋ฐ˜์‘ํ˜•

๐ŸŽค Web Speech API๋ž€?

Web Speech API๋Š” ์›น ๋ธŒ๋ผ์šฐ์ €์—์„œ ์Œ์„ฑ ์ธ์‹(Speech Recognition)๊ณผ ์Œ์„ฑ ํ•ฉ์„ฑ(Text-to-Speech)์„ ํ‘œ์ค€ํ™”ํ•œ JavaScript API์ž…๋‹ˆ๋‹ค. 2026๋…„ ํ˜„์žฌ, ๋ชจ๋“  ์ฃผ์š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ด๋ฅผ ์ง€์›ํ•˜๋ฉฐ, ์›น ์ ‘๊ทผ์„ฑ๊ณผ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ํ˜์‹ ์ ์œผ๋กœ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ๋กœ ์ž๋ฆฌ์žก์•˜์Šต๋‹ˆ๋‹ค.

์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ

SpeechRecognition API: ์‚ฌ์šฉ์ž์˜ ์Œ์„ฑ์„ ํ…์ŠคํŠธ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์‹ค์‹œ๊ฐ„ ์Œ์„ฑ ๋ช…๋ น, ์Œ์„ฑ ๊ฒ€์ƒ‰, ๋ฐ›์•„์“ฐ๊ธฐ ๊ธฐ๋Šฅ ๋“ฑ์— ํ™œ์šฉ๋ฉ๋‹ˆ๋‹ค.

SpeechSynthesis API: ํ…์ŠคํŠธ๋ฅผ ์Œ์„ฑ์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์žฌ์ƒํ•ฉ๋‹ˆ๋‹ค. ์Šคํฌ๋ฆฐ ๋ฆฌ๋” ๋Œ€์•ˆ, ์•Œ๋ฆผ ์ฝ์–ด์ฃผ๊ธฐ, ์˜ค๋””์˜ค๋ถ ์ƒ์„ฑ ๋“ฑ์— ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๐Ÿ”ง Speech Recognition ์‹ค์ „ ํ™œ์šฉ

์Œ์„ฑ ์ธ์‹ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ธฐ๋ณธ ์ฝ”๋“œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

const recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition)();
recognition.lang = 'ko-KR';
recognition.continuous = false;
recognition.interimResults = true;

recognition.onresult = (event) => {
  const transcript = event.results[0][0].transcript;
  console.log('์ธ์‹๋œ ํ…์ŠคํŠธ:', transcript);
};

recognition.start();

์‹ค์šฉ์ ์ธ ์‘์šฉ ์‚ฌ๋ก€

์Œ์„ฑ ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ: ๊ฒ€์ƒ‰์ฐฝ์—์„œ ๋งˆ์ดํฌ ์•„์ด์ฝ˜ ํด๋ฆญ ์‹œ ์Œ์„ฑ์œผ๋กœ ๊ฒ€์ƒ‰์–ด๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋ฐ”์ผ ํ™˜๊ฒฝ์—์„œ ํŠนํžˆ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์Œ์„ฑ ๋ช…๋ น ์ธํ„ฐํŽ˜์ด์Šค: "ํŽ˜์ด์ง€ ์Šคํฌ๋กค", "๋‹ค์Œ ํ•ญ๋ชฉ", "๋ฉ”๋‰ด ์—ด๊ธฐ" ๊ฐ™์€ ์Œ์„ฑ ๋ช…๋ น์œผ๋กœ ์›น์‚ฌ์ดํŠธ๋ฅผ ์กฐ์ž‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์‹ค์‹œ๊ฐ„ ์ž๋ง‰ ์ƒ์„ฑ: ํ™”์ƒ ํšŒ์˜๋‚˜ ๋™์˜์ƒ ์žฌ์ƒ ์‹œ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ž๋ง‰์„ ์ƒ์„ฑํ•˜์—ฌ ์ฒญ๊ฐ ์žฅ์• ์ธ์˜ ์ ‘๊ทผ์„ฑ์„ ๋†’์ž…๋‹ˆ๋‹ค.

๐Ÿ”Š Speech Synthesis๋กœ ์Œ์„ฑ ์ถœ๋ ฅํ•˜๊ธฐ

ํ…์ŠคํŠธ๋ฅผ ์Œ์„ฑ์œผ๋กœ ๋ณ€ํ™˜ํ•˜๋Š” ๊ธฐ๋Šฅ์€ ์›น ์ ‘๊ทผ์„ฑ์˜ ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค. ๊ฐ„๋‹จํ•œ ๊ตฌํ˜„ ์˜ˆ์‹œ:

const utterance = new SpeechSynthesisUtterance('์•ˆ๋…•ํ•˜์„ธ์š”, Web Speech API์ž…๋‹ˆ๋‹ค.');
utterance.lang = 'ko-KR';
utterance.rate = 1.0;
utterance.pitch = 1.0;

window.speechSynthesis.speak(utterance);

์Œ์„ฑ ์ปค์Šคํ„ฐ๋งˆ์ด์ง•

๋ชฉ์†Œ๋ฆฌ ์„ ํƒ: ๋ธŒ๋ผ์šฐ์ €๋Š” ์—ฌ๋Ÿฌ ์Œ์„ฑ(๋ชฉ์†Œ๋ฆฌ)์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. `speechSynthesis.getVoices()`๋กœ ๋ชฉ๋ก์„ ๊ฐ€์ ธ์™€ ์›ํ•˜๋Š” ๋ชฉ์†Œ๋ฆฌ๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์†๋„์™€ ์Œ๋†’์ด ์กฐ์ ˆ: `rate` (0.1~10), `pitch` (0~2) ๊ฐ’์„ ์กฐ์ •ํ•˜์—ฌ ์ž์—ฐ์Šค๋Ÿฝ๊ณ  ๋“ฃ๊ธฐ ํŽธํ•œ ์Œ์„ฑ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โ™ฟ ์ ‘๊ทผ์„ฑ ํ–ฅ์ƒ ๋ฒ ์ŠคํŠธ ํ”„๋ž™ํ‹ฐ์Šค

Web Speech API๋ฅผ ์ ‘๊ทผ์„ฑ ๊ฐœ์„ ์— ํ™œ์šฉํ•  ๋•Œ ๊ณ ๋ คํ•  ์‚ฌํ•ญ๋“ค:

1. ์‹œ๊ฐ ์žฅ์• ์ธ์„ ์œ„ํ•œ ์Šคํฌ๋ฆฐ ๋ฆฌ๋” ๋ณด์กฐ

๊ธฐ์กด ์Šคํฌ๋ฆฐ ๋ฆฌ๋”์™€ ์ถฉ๋Œํ•˜์ง€ ์•Š๋„๋ก `aria-live` ์†์„ฑ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ค‘์š”ํ•œ ์•Œ๋ฆผ์ด๋‚˜ ํผ ์—๋Ÿฌ ๋ฉ”์‹œ์ง€๋ฅผ ์Œ์„ฑ์œผ๋กœ ์ฝ์–ด์ฃผ๋ฉด ํšจ๊ณผ์ ์ž…๋‹ˆ๋‹ค.

2. ์ฒญ๊ฐ ์žฅ์• ์ธ์„ ์œ„ํ•œ ์‹ค์‹œ๊ฐ„ ์ž๋ง‰

Speech Recognition์„ ํ™œ์šฉํ•ด ์˜ค๋””์˜ค ์ฝ˜ํ…์ธ ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ํ…์ŠคํŠธํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ •ํ™•๋„๋ฅผ ๋†’์ด๊ธฐ ์œ„ํ•ด ์–ธ์–ด ๋ชจ๋ธ(`lang`)์„ ์ •ํ™•ํžˆ ์„ค์ •ํ•˜์„ธ์š”.

3. ์šด๋™ ์žฅ์• ์ธ์„ ์œ„ํ•œ ์Œ์„ฑ ๋‚ด๋น„๊ฒŒ์ด์…˜

๋งˆ์šฐ์Šค๋‚˜ ํ‚ค๋ณด๋“œ ์‚ฌ์šฉ์ด ์–ด๋ ค์šด ์‚ฌ์šฉ์ž๋ฅผ ์œ„ํ•ด ์Œ์„ฑ ๋ช…๋ น๋งŒ์œผ๋กœ ์›น์‚ฌ์ดํŠธ๋ฅผ ํƒ์ƒ‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. "ํด๋ฆญ", "์ œ์ถœ", "๋’ค๋กœ๊ฐ€๊ธฐ" ๊ฐ™์€ ๊ธฐ๋ณธ ๋ช…๋ น์–ด ์„ธํŠธ๋ฅผ ์ œ๊ณตํ•˜์„ธ์š”.

โš ๏ธ ๋ธŒ๋ผ์šฐ์ € ํ˜ธํ™˜์„ฑ๊ณผ ์ œ์•ฝ์‚ฌํ•ญ

2026๋…„ ํ˜„์žฌ ๋Œ€๋ถ€๋ถ„์˜ ๋ชจ๋˜ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ Web Speech API๋ฅผ ์ง€์›ํ•˜์ง€๋งŒ, ๋ช‡ ๊ฐ€์ง€ ์ฃผ์˜์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค:

HTTPS ํ•„์ˆ˜: ๋ณด์•ˆ์ƒ์˜ ์ด์œ ๋กœ HTTPS ํ™˜๊ฒฝ์—์„œ๋งŒ ๋งˆ์ดํฌ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ๋กœ์ปฌ ๊ฐœ๋ฐœ ์‹œ์—๋Š” `localhost`๋Š” ์˜ˆ์™ธ์ž…๋‹ˆ๋‹ค.

์‚ฌ์šฉ์ž ๊ถŒํ•œ: ์ฒ˜์Œ ์Œ์„ฑ ์ธ์‹ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๋•Œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋งˆ์ดํฌ ๊ถŒํ•œ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ๊ฑฐ๋ถ€ ์‹œ ๋Œ€์ฒด ์ž…๋ ฅ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์–ธ์–ด ์ง€์›: ํ•œ๊ตญ์–ด๋Š” ๋Œ€๋ถ€๋ถ„ ๋ธŒ๋ผ์šฐ์ €์—์„œ ์ž˜ ์ง€์›๋˜์ง€๋งŒ, ์ผ๋ถ€ ์†Œ์ˆ˜ ์–ธ์–ด๋Š” ์ •ํ™•๋„๊ฐ€ ๋‚ฎ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿš€ 2026๋…„ ํŠธ๋ Œ๋“œ: AI์™€์˜ ๊ฒฐํ•ฉ

Web Speech API์™€ LLM(๋Œ€๊ทœ๋ชจ ์–ธ์–ด ๋ชจ๋ธ)์„ ๊ฒฐํ•ฉํ•˜๋ฉด ๋”์šฑ ๊ฐ•๋ ฅํ•œ ์Œ์„ฑ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

์ž์—ฐ์–ด ์ดํ•ด ๊ฐ•ํ™”: ์Œ์„ฑ ์ธ์‹ ๊ฒฐ๊ณผ๋ฅผ GPT-4๋‚˜ Claude์—๊ฒŒ ์ „๋‹ฌํ•˜์—ฌ ์˜๋„๋ฅผ ํŒŒ์•…ํ•˜๊ณ  ์ ์ ˆํ•œ ์•ก์…˜์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

๋Œ€ํ™”ํ˜• ์›น ์–ด์‹œ์Šคํ„ดํŠธ: "์˜ค๋Š˜ ๋‚ ์”จ ์•Œ๋ ค์ค˜", "์žฅ๋ฐ”๊ตฌ๋‹ˆ์— ๋‹ด๊ธด ์ƒํ’ˆ ์ฝ์–ด์ค˜" ๊ฐ™์€ ๋ณต์žกํ•œ ๋ช…๋ น์„ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๊ตญ์–ด ์‹ค์‹œ๊ฐ„ ๋ฒˆ์—ญ: ์Œ์„ฑ ์ธ์‹ → AI ๋ฒˆ์—ญ → ์Œ์„ฑ ํ•ฉ์„ฑ ํŒŒ์ดํ”„๋ผ์ธ์œผ๋กœ ์‹ค์‹œ๊ฐ„ ํ†ต์—ญ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๐Ÿ“ ์‹ค์ „ ํ”„๋กœ์ ํŠธ: ์Œ์„ฑ ๋ฉ”๋ชจ ์•ฑ ๋งŒ๋“ค๊ธฐ

Web Speech API๋ฅผ ํ™œ์šฉํ•œ ๊ฐ„๋‹จํ•œ ์Œ์„ฑ ๋ฉ”๋ชจ ์•ฑ์„ ๋งŒ๋“ค์–ด๋ด…์‹œ๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๊ณ  ๋งํ•˜๋ฉด ํ…์ŠคํŠธ๋กœ ๋ณ€ํ™˜๋˜์–ด ์ €์žฅ๋˜๊ณ , ์ €์žฅ๋œ ๋ฉ”๋ชจ๋ฅผ ์Œ์„ฑ์œผ๋กœ ์ฝ์–ด์ฃผ๋Š” ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค.

let recognition;
let synthesis = window.speechSynthesis;

function startRecording() {
  recognition = new webkitSpeechRecognition();
  recognition.lang = 'ko-KR';
  recognition.onresult = (e) => {
    const memo = e.results[0][0].transcript;
    saveMemo(memo);
    readMemo(memo);
  };
  recognition.start();
}

function readMemo(text) {
  const utterance = new SpeechSynthesisUtterance(text);
  synthesis.speak(utterance);
}

โœ… ๊ฒฐ๋ก 

Web Speech API๋Š” ์›น ์ ‘๊ทผ์„ฑ์„ ํš๊ธฐ์ ์œผ๋กœ ํ–ฅ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ๊ฐ•๋ ฅํ•˜๋ฉด์„œ๋„ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. 2026๋…„ ํ˜„์žฌ, ํ‘œ์ค€ํ™”๊ฐ€ ์™„๋ฃŒ๋˜์–ด ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ ์•ˆ์ •์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, AI ๊ธฐ์ˆ ๊ณผ ๊ฒฐํ•ฉํ•˜๋ฉด ๋”์šฑ ์ง€๋Šฅ์ ์ธ ์Œ์„ฑ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ์‚ฌ์šฉ์ž๊ฐ€ ํ‰๋“ฑํ•˜๊ฒŒ ์›น์„ ๊ฒฝํ—˜ํ•  ์ˆ˜ ์žˆ๋„๋ก, ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ์ ํŠธ์— ์Œ์„ฑ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•ด๋ณด์„ธ์š”!

๋ฐ˜์‘ํ˜•