필사 모드: Web Audio API & 브라우저 오디오 2026 — AudioWorklet / Tone.js / Howler.js / Wavesurfer / Peaks.js / Meyda / Faust / Csound / Web Speech 심층 가이드
한국어프롤로그 — 브라우저가 오디오 워크스테이션이 된 해
2026년 5월 현재, "브라우저에서 오디오"라는 말의 무게는 5년 전과 완전히 다르다.
- Web Audio API는 W3C Working Draft에서 Candidate Recommendation으로 올라섰고, Level 2 사양이 안정화됐다.
- AudioWorklet은 모든 메이저 브라우저(Chrome, Edge, Firefox, Safari)에서 GA가 됐고, ScriptProcessor는 사실상 사망 선고를 받았다.
- Tone.js는 v15까지 왔고, Yotam Mann이 시작한 이 프로젝트는 이제 음악 프로그래밍의 사실상 표준이다.
- Howler.js는 HTML5 게임 사운드의 절대 다수가 채택했다.
- WaveSurfer.js v8, Peaks.js(BBC), Meyda 같은 분석/시각화 라이브러리가 DAW급 UI를 가능하게 한다.
- Faust2WebAudio와 Csound on WebAssembly가 학술 DSP를 브라우저로 가져왔다.
- WebRTC + Opus + WebTransport로 50ms 미만의 실시간 음성 협업이 가능해졌다.
- Web Speech API의 SpeechRecognition·SpeechSynthesis는 데스크톱·모바일 모두에서 안정 동작한다.
- 한국은 네이버 클로바 TTS·STT, 카카오 i Voice가 사실상 표준이고, 일본은 VOICEVOX·Coeiroink가 로컬·브라우저 양쪽에서 표준이 됐다.
이 글은 그 전체 지도를 한 번에 그린다. 어떤 도구가 어떤 자리를 차지하는지, 무엇이 사라졌고 무엇이 살아남았는지, 그리고 2026년에 새 프로젝트를 시작한다면 무엇을 골라야 하는지.
1. 2026년 Web Audio 지도 — 4분류
생태계는 크게 네 층으로 나뉜다.
[ 1층 ] 사양 — Web Audio API (W3C), Web Speech API
[ 2층 ] 저수준 도구 — AudioContext, AudioWorklet, OfflineAudioContext
[ 3층 ] 라이브러리 — Tone.js, Howler.js, Pizzicato.js, WaveSurfer.js, Peaks.js, Meyda
[ 4층 ] DSL/엔진 — Faust2WebAudio, Csound on Web, Web MIDI 기반 신스
[ 옆 축 ] 실시간/AI — WebRTC + Opus, WebTransport, Coqui XTTS, Suno API, ElevenLabs API
각 층은 **추상화의 수준**으로 나뉜다. 1층은 표준이라 바꿀 수 없고, 2층은 모든 브라우저에 들어 있고, 3층은 골라 쓰는 라이브러리, 4층은 DSP 전문가의 영역이다.
| 영역 | 추천 도구 |
| --- | --- |
| 게임 사운드 | Howler.js |
| 음악·악기·시퀀서 | Tone.js |
| DAW UI 파형 | WaveSurfer.js |
| 방송용 세그먼트 에디터 | Peaks.js |
| 특징 추출(BPM, MFCC) | Meyda |
| 학술 DSP / 신스 | Faust2WebAudio, Csound on Web |
| 화상 회의 / 음성 채팅 | WebRTC + Opus |
| 브라우저 TTS | Web Speech API + 외부 API |
| 한국어 TTS | 네이버 클로바, 카카오 i Voice |
| 일본어 TTS | VOICEVOX, Coeiroink |
2. Web Audio API (W3C) — 모든 브라우저에서 GA
Web Audio API의 핵심은 **그래프 기반 오디오 라우팅**이다. JavaScript에서 노드를 만들어 연결하면, 오디오 처리는 브라우저의 별도 스레드(렌더 스레드)에서 돈다.
const ctx = new AudioContext()
// 노드 생성
const osc = ctx.createOscillator()
const gain = ctx.createGain()
// 그래프 연결: osc -> gain -> 출력
osc.connect(gain)
gain.connect(ctx.destination)
// 파라미터 설정
osc.frequency.value = 440 // A4
gain.gain.value = 0.2
// 재생
osc.start()
osc.stop(ctx.currentTime + 1)
2026년의 핵심 변화는 두 가지다.
1. **AudioParam 자동화 곡선** — `setValueCurveAtTime`이 모든 브라우저에서 정확히 같은 보간을 한다. 더 이상 폴리필이 필요 없다.
2. **AudioRenderCapacity** — 렌더 스레드의 부하를 직접 측정해서 동적으로 노드 수를 조절할 수 있다(Chrome 121+, Safari 18+).
W3C 사양 자체의 표면적은 크지 않다. 약 30개의 노드 타입이 전부고, 이 노드들의 조합으로 거의 모든 오디오 처리가 가능하다.
| 노드 분류 | 대표 노드 |
| --- | --- |
| 소스 | OscillatorNode, AudioBufferSourceNode, MediaElementSourceNode, MediaStreamSourceNode |
| 이펙트 | GainNode, BiquadFilterNode, DelayNode, ConvolverNode, DynamicsCompressorNode, WaveShaperNode |
| 분석 | AnalyserNode |
| 공간 | PannerNode, StereoPannerNode, AudioListener |
| 사용자 정의 | AudioWorkletNode |
| 출력 | AudioDestinationNode, MediaStreamDestination |
3. AudioContext + OfflineAudioContext + MediaStream / MediaElement
세 가지 컨텍스트가 있고, 각각 다른 용도다.
AudioContext — 실시간
기본 컨텍스트. 출력은 스피커 또는 헤드폰. 사용자 제스처(클릭, 키 입력)가 있어야 첫 재생이 시작된다. 모바일 Safari는 이걸 특히 엄격하게 본다.
OfflineAudioContext — 비실시간 렌더링
실시간보다 빠르게 오디오를 렌더링한다. WAV 익스포트, 오프라인 분석, 마스터링 미리듣기에 쓴다.
// 44.1kHz, 스테레오, 10초짜리 버퍼
const offline = new OfflineAudioContext(2, 44100 * 10, 44100)
const osc = offline.createOscillator()
osc.connect(offline.destination)
osc.start()
osc.stop(10)
const rendered = await offline.startRendering()
// rendered는 AudioBuffer — 그대로 WAV로 인코딩 가능
MediaElementAudioSourceNode — `<audio>` / `<video>`를 그래프에 연결
HTML5 audio/video 요소를 노드로 변환한다. iframe 임베드 비디오에는 못 쓴다 (CORS, autoplay 정책).
const audioEl = document.querySelector('audio')
const ctx = new AudioContext()
const source = ctx.createMediaElementSource(audioEl)
source.connect(ctx.destination)
// 이제 audioEl을 재생하면 ctx 그래프를 거쳐 출력된다
MediaStreamAudioSourceNode — getUserMedia 마이크
마이크 입력을 그래프에 넣는다. WebRTC 입력에도 같은 노드를 쓴다.
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
const ctx = new AudioContext()
const mic = ctx.createMediaStreamSource(stream)
const analyser = ctx.createAnalyser()
mic.connect(analyser)
// analyser.getByteFrequencyData()로 실시간 스펙트럼을 뽑는다
4. AudioWorklet — ScriptProcessor의 무덤
여기가 2026년 가장 큰 변화 지점이다.
**과거**: ScriptProcessorNode를 메인 스레드에서 돌렸다. 버퍼 크기 256~16384 샘플, 지연이 컸고 GC가 끼면 클릭(드롭아웃)이 났다.
**현재**: AudioWorklet은 오디오 렌더 스레드에서 직접 도는 별도의 글로벌 스코프다. 메인 스레드와 무관하게 128 샘플 단위(약 2.6ms)로 계산된다.
// worklet.js — 렌더 스레드에서 도는 코드
class WhiteNoiseProcessor extends AudioWorkletProcessor {
process(inputs, outputs, parameters) {
const output = outputs[0]
for (let channel = 0; channel < output.length; channel++) {
const ch = output[channel]
for (let i = 0; i < ch.length; i++) {
ch[i] = Math.random() * 2 - 1
}
}
return true // 노드를 살려둠
}
}
registerProcessor('white-noise', WhiteNoiseProcessor)
// main.js — 메인 스레드에서 등록 후 사용
const ctx = new AudioContext()
await ctx.audioWorklet.addModule('worklet.js')
const noise = new AudioWorkletNode(ctx, 'white-noise')
noise.connect(ctx.destination)
AudioWorklet의 진가는 **WebAssembly와의 결합**이다. Rust나 C++로 짠 DSP 코드를 WASM으로 빌드해서 워클릿 안에서 돌리면, 네이티브에 가까운 성능을 낸다. Faust2WebAudio·Csound on Web 모두 내부적으로 이 패턴을 쓴다.
ScriptProcessorNode는 사양 문서에 **DEPRECATED** 도장이 찍혔다. 신규 코드에서는 절대 쓰면 안 된다.
5. Tone.js (Yotam Mann) — 음악 프로그래밍의 사실상 표준
Tone.js는 2014년 Yotam Mann이 시작했고, 음악 도메인 — 음표, 박자, 신스, 이펙트 체인 — 을 다루기 위한 추상을 제공한다.
// 폴리포닉 신스 + 리버브
const reverb = new Tone.Reverb({ decay: 4 }).toDestination()
const synth = new Tone.PolySynth(Tone.AMSynth).connect(reverb)
// 시퀀서 — 16분음표 단위로 도는 루프
const seq = new Tone.Sequence(
(time, note) => {
synth.triggerAttackRelease(note, '8n', time)
},
['C4', 'E4', 'G4', 'B4', 'C5', 'B4', 'G4', 'E4'],
'8n'
)
await Tone.start() // 사용자 제스처 후
Tone.Transport.bpm.value = 120
Tone.Transport.start()
seq.start(0)
핵심 컴포넌트:
| 카테고리 | 모듈 |
| --- | --- |
| 소스 | Oscillator, Synth, AMSynth, FMSynth, MonoSynth, PolySynth, Sampler, Player |
| 이펙트 | Reverb, Delay, FeedbackDelay, Chorus, Distortion, Phaser, AutoFilter, Compressor |
| 시간 | Transport(BPM 글로벌 클럭), Sequence, Loop, Pattern, Part |
| 시그널 | Signal, Param, LFO, Envelope, ScaledEnvelope |
Tone.js v15는 **Note class**가 완전 새로 작성됐다. 음표를 `'C4'` 같은 문자열뿐 아니라 `{ note: 'C', octave: 4, accidental: '#' }` 형태로도 받는다. 음악 이론을 코드로 다룰 때 가장 직관적인 API다.
6. Howler.js — 게임 사운드의 절대 표준
Howler.js는 "복잡한 그래프는 모르겠고, 그냥 BGM이랑 효과음 재생만 하면 된다"인 사람을 위한 라이브러리다.
const sfx = new Howl({
src: ['shoot.webm', 'shoot.mp3'],
volume: 0.5,
rate: 1.2, // 피치 보존하면서 1.2배 속도
sprite: {
shoot1: [0, 200],
shoot2: [300, 200],
},
})
document.getElementById('fire').addEventListener('click', () => {
sfx.play('shoot1')
})
Howler.volume(0.8) // 글로벌 마스터 볼륨
Howler.js의 장점:
- 단일 객체로 다중 인스턴스 자동 관리(같은 효과음을 빠르게 여러 번 재생해도 풀링이 알아서)
- 페이드 인/아웃, 시크, 스프라이트, 3D 패닝, 글로벌 음소거가 일관된 API로 통합
- 코덱 자동 폴백 — WebM Opus가 안 되면 MP3로
- 모바일 자동재생 정책 자동 처리
거의 모든 HTML5 게임 엔진(Phaser, Pixi.js + 별도 사운드, Construct 3 등)이 Howler.js를 기본 또는 옵션으로 권장한다.
7. Pizzicato.js — 신예 / 데클러레이티브
Pizzicato는 "오디오 노드 그래프를 객체 지향처럼" 다루게 해주는 라이브러리다. Tone.js보다 더 얇고, Howler.js보다 더 그래프 친화적이다.
const sound = new Pizzicato.Sound({
source: 'wave',
options: { type: 'square', frequency: 220 },
})
const delay = new Pizzicato.Effects.Delay({
feedback: 0.5,
time: 0.3,
mix: 0.5,
})
sound.addEffect(delay)
sound.play()
장점: API가 단순. 단점: 커뮤니티가 Tone.js만큼 크지 않아서 깊이 들어가면 자료가 부족하다. 실험·교육용으로 좋다.
8. WaveSurfer.js — 파형 시각화의 정석
WaveSurfer.js v8은 DAW 스타일 파형 디스플레이의 사실상 표준이다. 오디오 파일을 받아서 캔버스에 파형을 그리고, 재생 헤드, 영역 선택, 줌, 미니맵까지 모두 플러그인으로 지원한다.
const ws = WaveSurfer.create({
container: '#wave',
waveColor: '#888',
progressColor: '#4af',
height: 120,
url: '/audio/example.mp3',
})
const regions = ws.registerPlugin(RegionsPlugin.create())
ws.on('ready', () => {
regions.addRegion({
start: 4,
end: 8,
color: 'rgba(0,255,0,0.2)',
drag: true,
resize: true,
})
})
v8의 변화: 렌더링이 OffscreenCanvas + Web Worker로 옮겨가서, 1시간짜리 오디오도 메인 스레드를 멈추지 않고 렌더한다. 모바일에서도 매끄럽다.
9. Peaks.js (BBC R&D) — 방송용 세그먼트 에디터
Peaks.js는 BBC R&D가 만든 라이브러리다. 라디오 / 팟캐스트 편집에서 화자 분리, 광고 구간 마킹, 챕터 표시 같은 작업을 한다.
차별점:
- **줌 가능한 두 단계 뷰** — 위에 미니맵, 아래에 줌된 상세 뷰
- **사전 계산된 wave data 포맷(.dat)** 지원 — 서버에서 미리 계산해두면 클라이언트는 그걸 받아서 즉시 그린다. 1시간 오디오를 클라이언트에서 디코드하지 않아도 됨
- **포인트 / 세그먼트 API** — 시간 위치에 마커를 찍고, 라벨을 붙이고, 드래그로 이동
const options = {
zoomview: { container: document.getElementById('zoomview') },
overview: { container: document.getElementById('overview') },
mediaElement: document.querySelector('audio'),
dataUri: { json: '/audio/example.json' }, // 미리 계산된 파형 데이터
}
Peaks.init(options, (err, peaks) => {
peaks.segments.add({ startTime: 10, endTime: 20, labelText: 'Ad break' })
peaks.points.add({ time: 15.5, labelText: 'Chapter 2' })
})
방송국 워크플로에 최적화돼 있다. BBC Sounds 같은 서비스가 이걸 내부에서 쓴다.
10. Meyda — 오디오 특징 추출
Meyda는 실시간으로 오디오의 **특징(feature)** 을 뽑아내는 라이브러리다. MFCC, 에너지, RMS, 제로 크로싱 레이트, 스펙트럼 센트로이드, 크로마, 라우드니스 등.
const ctx = new AudioContext()
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
const source = ctx.createMediaStreamSource(stream)
const analyzer = Meyda.createMeydaAnalyzer({
audioContext: ctx,
source,
bufferSize: 1024,
featureExtractors: ['rms', 'spectralCentroid', 'mfcc', 'chroma'],
callback: (features) => {
console.log(features.rms, features.spectralCentroid)
},
})
analyzer.start()
쓰임새:
- **BPM 추정** — 실시간 RMS 피크 검출
- **음성 활동 감지(VAD)** — RMS 임계값 + 스펙트럼 센트로이드
- **악기 분류** — MFCC + 머신러닝 모델
- **시각화** — 크로마를 시각화하면 화성 진행이 보인다
ML 모델과 결합해 브라우저에서 장르 분류, 가창 음성 인식 같은 데모를 만들 때 가장 흔하게 쓰는 도구다.
11. Faust2WebAudio — Faust DSL을 Web Audio로
Faust는 INRIA / GRAME에서 만든 함수형 오디오 DSP 언어다. 한 줄로 신스, 이펙트, 필터를 정의할 수 있고, 컴파일러가 C++/Rust/JS/WASM/AudioWorklet 등 여러 타깃으로 출력한다.
Faust 코드 예시(저역 통과 필터):
import("stdfaust.lib");
process = fi.lowpass(3, hslider("Cutoff", 1000, 50, 20000, 1));
이걸 `faust2webaudiowasm` 도구로 컴파일하면 AudioWorklet 기반의 JavaScript 노드가 나온다.
const ctx = new AudioContext()
const node = await FaustAudioWorkletNode.create(ctx, 'lowpass')
document.querySelector('audio').addEventListener('play', (e) => {
const src = ctx.createMediaElementSource(e.target)
src.connect(node).connect(ctx.destination)
})
// 파라미터 자동화
node.setParamValue('/Cutoff', 800)
장점: DSP 알고리즘을 수학적으로 깔끔하게 표현. 단점: 학습 곡선. 신호처리 배경이 없으면 진입이 어렵다.
12. Csound on Web — WASM Csound
Csound는 1986년부터 있는 컴퓨터 음악 언어다. WebAssembly로 포팅돼서 브라우저에서 거의 그대로 돈다.
const csound = await Csound()
await csound.compileOrc(`
instr 1
iFreq = p4
aSig oscili 0.3, iFreq
outs aSig, aSig
endin
`)
await csound.readScore('i1 0 2 440\ni1 2 2 880')
await csound.start()
Csound on Web의 의의: 학술·연구·실험 음악의 거대한 자산(40년치)이 브라우저에서 그대로 돈다. 옛 작품을 디지털 박물관에 올리거나, 전자음악 교육에 쓰기에 좋다.
내부적으로는 AudioWorklet + WASM 조합이다. 메인 스레드와 분리돼 있어 부하가 커도 UI는 멈추지 않는다.
13. WebRTC + Opus + WebTransport — 실시간 오디오
영상 회의, 게임 음성 채팅, 라이브 협업 음악의 핵심 스택이다.
WebRTC + Opus
WebRTC는 P2P 미디어 스트리밍의 표준. Opus 코덱은 16~512kbps 범위에서 음성·음악 모두 효율적으로 인코딩한다. 핸드오프 지연이 50ms 미만.
const pc = new RTCPeerConnection()
const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
stream.getTracks().forEach((t) => pc.addTrack(t, stream))
pc.ontrack = (e) => {
const audio = new Audio()
audio.srcObject = e.streams[0]
audio.play()
}
// SDP offer/answer 교환은 별도 시그널링 채널로 — WebSocket 등
WebTransport — 새 옵션
WebTransport(HTTP/3 위의 QUIC 양방향 스트림)는 WebSocket을 대체하는 저지연 채널이다. WebRTC 데이터 채널보다 더 단순하고, 신뢰성 / 비신뢰성을 명시적으로 고를 수 있다. 게임 음성처럼 패킷 로스를 감수하고 지연을 줄이고 싶을 때 좋다.
2026년 현재 Chrome, Edge, Firefox에서 GA. Safari는 26버전부터 지원.
14. AI 오디오 — Coqui XTTS, Suno API, ElevenLabs
브라우저에서 AI 음성 생성은 두 길이다.
길 1: 서버 API 호출
ElevenLabs, OpenAI TTS, Suno(음악 생성) — 모두 REST/streaming API다.
const res = await fetch('https://api.elevenlabs.io/v1/text-to-speech/VOICE_ID/stream', {
method: 'POST',
headers: {
'xi-api-key': API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
text: 'Hello world',
model_id: 'eleven_multilingual_v2',
}),
})
const audio = new Audio()
audio.src = URL.createObjectURL(await res.blob())
audio.play()
스트리밍(MediaSource Extensions + Opus chunks)을 쓰면 첫 음절까지 200~300ms.
길 2: 클라이언트 로컬 추론
Coqui XTTS-v2가 Hugging Face Transformers.js로 브라우저에서 돈다. WebGPU 기반이라 초기 로딩(~500MB)이 크지만, 일단 로드되면 키워드 잠금처럼 외부 호출 없이 합성이 가능하다.
const synth = await pipeline('text-to-speech', 'coqui-ai/xtts-v2-onnx', {
device: 'webgpu',
})
const audio = await synth('Hello from the browser')
const buffer = ctx.createBuffer(1, audio.audio.length, audio.sampling_rate)
buffer.copyToChannel(audio.audio, 0)
// 재생...
선택 기준: 품질 / 즉응성이면 API, 프라이버시 / 오프라인이면 로컬.
15. Web Speech API — 브라우저 내장 인식 + 합성
Web Speech API에는 두 부분이 있다.
SpeechRecognition — 음성 → 텍스트
const SR = window.SpeechRecognition || window.webkitSpeechRecognition
const rec = new SR()
rec.lang = 'ko-KR'
rec.continuous = true
rec.interimResults = true
rec.onresult = (e) => {
for (const res of e.results) {
console.log(res[0].transcript, res.isFinal)
}
}
rec.start()
주의: Chrome은 구글 클라우드 서비스로 데이터를 보낸다. 프라이버시가 중요하면 로컬 Whisper.cpp(WASM)나 Vosk를 써야 한다.
SpeechSynthesis — 텍스트 → 음성
const utter = new SpeechSynthesisUtterance('안녕하세요')
utter.lang = 'ko-KR'
utter.rate = 1.0
utter.pitch = 1.0
const voices = speechSynthesis.getVoices()
utter.voice = voices.find((v) => v.lang === 'ko-KR' && v.name.includes('Yuna'))
speechSynthesis.speak(utter)
OS별 음성 엔진을 그대로 쓴다. macOS/iOS는 Apple의 Neural Voice, Windows는 Edge TTS와 같은 SAPI Voice, Android는 Google TTS. 품질 편차가 크다.
16. 한국 — 클로바 TTS / 카카오 i Voice
한국어 TTS 시장은 두 거인이 있다.
네이버 클로바 Voice
NCP(네이버 클라우드 플랫폼)에서 제공. 약 50개의 보이스 캐릭터(연령·성별·억양 다양), SSML 지원, 감정 톤 조절. 가격은 1000자당 ~3원(2026년 기준 — 정확한 가격은 공식 페이지 확인).
const res = await fetch('https://naveropenapi.apigw.ntruss.com/tts-premium/v1/tts', {
method: 'POST',
headers: {
'X-NCP-APIGW-API-KEY-ID': CLIENT_ID,
'X-NCP-APIGW-API-KEY': CLIENT_SECRET,
'Content-Type': 'application/x-www-form-urlencoded',
},
body: new URLSearchParams({
speaker: 'nara',
text: '안녕하세요. 클로바입니다.',
volume: '0',
speed: '0',
pitch: '0',
format: 'mp3',
}),
})
const blob = await res.blob()
new Audio(URL.createObjectURL(blob)).play()
카카오 i Voice
Kakao i Open Builder의 음성합성. 캐릭터 수는 클로바보다 적지만 카카오 생태계(카카오워크, 카카오 챗봇)와 통합이 강하다.
선택 기준:
- 콘텐츠 캐릭터 다양성이 중요 → 클로바
- 카카오 챗봇 / 카카오 i와 통합 → 카카오 i Voice
- 비용 — 사용량별로 비교 견적 필요
브라우저에서 직접 호출은 CORS 때문에 보통 안 되고, 백엔드 프록시를 두고 부른다.
17. 일본 — VOICEVOX, Coeiroink
일본의 TTS 풍경은 한국과 매우 다르다. 무료 / 오픈소스 / 캐릭터 보이스가 강세다.
VOICEVOX
VOICEVOX는 Hihosaba Inc.가 운영하는 무료 TTS 엔진이다. 즌다몬, 시키코로네 같은 캐릭터 보이스가 유튜브·니코니코·게임에서 폭발적으로 쓰인다.
본체는 데스크톱 앱이지만, **VOICEVOX Core(C++) + WASM** 빌드가 있어 브라우저에서 돌릴 수 있다.
const core = await VoicevoxCore.create()
await core.loadModel(1) // 즌다몬
const audioQuery = await core.audioQuery('こんにちは', 1)
const wav = await core.synthesis(audioQuery, 1)
const ctx = new AudioContext()
const buf = await ctx.decodeAudioData(wav)
const src = ctx.createBufferSource()
src.buffer = buf
src.connect(ctx.destination)
src.start()
Coeiroink
Coeiroink는 또 다른 무료 TTS. MYCOEIROINK라는 시스템으로 사용자가 자기 목소리를 학습시킬 수 있다. 개인 크리에이터·유튜버가 자기 보이스를 만들어 쓰는 경우가 많다.
선택 기준:
- 인기 캐릭터 보이스(즌다몬 등) → VOICEVOX
- 자기 보이스 학습 / 개인화 → Coeiroink
법적 이용 약관(상업 이용 가부, 크레딧 표기 의무)이 캐릭터마다 다르니 반드시 확인할 것.
18. 누가 무엇을 골라야 하나
매트릭스로 정리.
| 목적 | 추천 스택 |
| --- | --- |
| HTML5 게임 BGM/SFX | Howler.js |
| 음악 시퀀서 / 신스 | Tone.js |
| DAW 스타일 파형 UI | WaveSurfer.js + Tone.js |
| 팟캐스트 / 라디오 편집 | Peaks.js |
| BPM·악기 분류 ML | Meyda + TensorFlow.js |
| 학술 DSP / 신스 연구 | Faust2WebAudio |
| 전자음악 교육 | Csound on Web |
| 음성 채팅 | WebRTC + Opus |
| 저지연 라이브 (게임 음성) | WebRTC 또는 WebTransport |
| 브라우저 내장 TTS | Web Speech API |
| 고품질 영어 TTS | ElevenLabs API |
| 음악 생성 | Suno API |
| 클라이언트 TTS (오프라인) | Coqui XTTS via Transformers.js |
| 한국어 TTS (서비스) | 클로바 / 카카오 i Voice |
| 일본어 TTS (캐릭터) | VOICEVOX |
| 일본어 TTS (자기 목소리) | Coeiroink |
세 가지 큰 결정 축:
1. **실시간 vs 비실시간** — 실시간이면 AudioContext + AudioWorklet, 비실시간이면 OfflineAudioContext.
2. **음악 vs 게임 vs 분석** — 음악은 Tone.js, 게임은 Howler.js, 분석은 Meyda.
3. **온라인 API vs 로컬 추론** — 품질·간편함이면 API, 프라이버시·오프라인이면 Transformers.js 기반 로컬 모델.
19. 마무리 — 브라우저는 오디오 워크스테이션이 되었다
5년 전만 해도 브라우저에서 오디오를 한다는 건 "장난감 수준"의 일이었다. 2026년의 브라우저는 다르다.
- AudioWorklet으로 네이티브 수준의 저지연 DSP가 가능하다.
- WASM으로 C/C++/Rust DSP 알고리즘을 그대로 실행한다.
- Tone.js·Howler.js·WaveSurfer.js·Peaks.js·Meyda 같은 라이브러리가 각 영역의 사실상 표준이 됐다.
- Faust2WebAudio·Csound on Web으로 학술 DSP가 브라우저로 들어왔다.
- WebRTC + Opus + WebTransport로 50ms 미만의 실시간 협업이 가능하다.
- Web Speech API + 클로바 / 카카오 / VOICEVOX / Coeiroink로 다국어 음성이 자연스럽다.
- Coqui XTTS, ElevenLabs, Suno로 AI 오디오가 즉시 사용 가능하다.
이제 남은 건 도구를 골라 작품을 만드는 일이다. 이 글이 그 선택의 출발선이 되기를.
참고 / References
- Web Audio API W3C Spec — [https://www.w3.org/TR/webaudio/](https://www.w3.org/TR/webaudio/)
- MDN Web Audio API — [https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API)
- AudioWorklet MDN — [https://developer.mozilla.org/en-US/docs/Web/API/AudioWorklet](https://developer.mozilla.org/en-US/docs/Web/API/AudioWorklet)
- Tone.js — [https://tonejs.github.io/](https://tonejs.github.io/)
- Howler.js — [https://howlerjs.com/](https://howlerjs.com/)
- Pizzicato.js — [https://alemangui.github.io/pizzicato/](https://alemangui.github.io/pizzicato/)
- WaveSurfer.js — [https://wavesurfer-js.org/](https://wavesurfer-js.org/)
- Peaks.js (BBC) — [https://github.com/bbc/peaks.js](https://github.com/bbc/peaks.js)
- Meyda — [https://meyda.js.org/](https://meyda.js.org/)
- Faust — [https://faust.grame.fr/](https://faust.grame.fr/)
- Csound on Web — [https://csound.com/web.html](https://csound.com/web.html)
- WebRTC — [https://webrtc.org/](https://webrtc.org/)
- WebTransport — [https://developer.mozilla.org/en-US/docs/Web/API/WebTransport_API](https://developer.mozilla.org/en-US/docs/Web/API/WebTransport_API)
- Web Speech API — [https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Speech_API)
- Coqui TTS — [https://github.com/coqui-ai/TTS](https://github.com/coqui-ai/TTS)
- ElevenLabs — [https://elevenlabs.io/](https://elevenlabs.io/)
- Suno — [https://suno.com/](https://suno.com/)
- 네이버 클로바 Voice — [https://www.ncloud.com/product/aiService/css](https://www.ncloud.com/product/aiService/css)
- Kakao i Open Builder — [https://i.kakao.com/](https://i.kakao.com/)
- VOICEVOX — [https://voicevox.hiroshiba.jp/](https://voicevox.hiroshiba.jp/)
- Coeiroink — [https://coeiroink.com/](https://coeiroink.com/)
현재 단락 (1/400)
2026년 5월 현재, "브라우저에서 오디오"라는 말의 무게는 5년 전과 완전히 다르다.