Comments (5)
在index.html中找到 function preview()的内容替换为以下内容
let headers = { 'Content-Type': 'text/plain' }; let voiceName = document.getElementsByName('voiceName')[0].value; let voiceFormat = document.getElementsByName('voiceFormat')[0].value; let token = document.getElementsByName('token')[0].value; let previewText = document.getElementsByName('previewText')[0].value; let ssml = createSSML(previewText, voiceName) if (token) { headers['Authorization'] = 'Bearer ' + token; } headers['Format'] = voiceFormat; let button = document.getElementById('previewButton'); button.disabled = true; let ctx = new AudioContext(); let audioBuffer; fetch('/api/ra', { method: 'post', headers: headers, body: ssml }).then(response => { if (response.status == 200) { return response.arrayBuffer() } else if (response.status == 401) { throw '无效的密钥'; } else { return response.text().then(text => Promise.reject(text)); } }).then(arrayBuffer => ctx.decodeAudioData(arrayBuffer)) .then(audio => { audioBuffer = audio; let player = ctx.createBufferSource(); player.buffer = audio; player.connect(ctx.destination); player.start(ctx.currentTime); }) .catch(reason => { alert(reason); }) .finally(() => { button.disabled = false; }); // 在最后添加以下代码 let downloadButton = document.getElementById('downloadButton'); downloadButton.addEventListener('click', () => { if (audioBuffer) { const audioData = exportWav(audioBuffer); const blob = new Blob([audioData], { type: 'audio/wav' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'audio.wav'; document.body.appendChild(a); a.click(); document.body.removeChild(a); } else { alert('请先预览音频'); } }); function exportWav(buffer) { const numberOfChannels = buffer.numberOfChannels; const sampleRate = buffer.sampleRate; const length = buffer.length; const duration = length / sampleRate; const bufferData = []; for (let channel = 0; channel < numberOfChannels; channel++) { bufferData.push(buffer.getChannelData(channel)); } const interleaved = interleave(bufferData, numberOfChannels); const dataview = encodeWAV(interleaved, numberOfChannels, sampleRate); return dataview.buffer; } function interleave(input, numberOfChannels) { const length = input[0].length * numberOfChannels; const output = new Float32Array(length); let offset = 0; for (let i = 0; i < input[0].length; i++) { for (let channel = 0; channel < numberOfChannels; channel++) { output[offset] = input[channel][i]; offset++; } } return output; } function encodeWAV(samples, numberOfChannels, sampleRate) { const buffer = new ArrayBuffer(44 + samples.length * 2); const view = new DataView(buffer); writeString(view, 0, 'RIFF'); view.setUint32(4, 36 + samples.length * 2, true); writeString(view, 8, 'WAVE'); writeString(view, 12, 'fmt '); view.setUint32(16, 16, true); // Sub-chunk 1 size view.setUint16(20, 1, true); // Audio format (1 for PCM) view.setUint16(22, numberOfChannels, true); // Number of channels view.setUint32(24, sampleRate, true); // Sample rate view.setUint32(28, sampleRate * numberOfChannels * 2, true); // Byte rate view.setUint16(32, numberOfChannels * 2, true); // Block align view.setUint16(34, 16, true); // Bits per sample writeString(view, 36, 'data'); view.setUint32(40, samples.length * 2, true); floatTo16BitPCM(view, 44, samples); return view; } function writeString(view, offset, string) { for (let i = 0; i < string.length; i++) { view.setUint8(offset + i, string.charCodeAt(i)); } } function floatTo16BitPCM(output, offset, input) { for (let i = 0; i < input.length; i++, offset += 2) { const s = Math.max(-1, Math.min(1, input[i])); output.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true); } }
from ms-ra-forwarder.
经过测试可以使用
from ms-ra-forwarder.
Related Issues (20)
- 可以在ios上使用吗 HOT 4
- TTS好像挂掉了 HOT 24
- ios源阅读下加token无效 HOT 7
- 安卓阅读下返回错误 HOT 4
- 请问这个项目是不是只能运行在浏览器里面? HOT 1
- 能否出一个cloudflare Pages的教程
- 大佬们,你们的还能用吗? HOT 1
- 新的接口
- Android 阅读 APP导入注意事项 HOT 2
- 请问能否增加GET方式? HOT 1
- 端口报错。 HOT 1
- 如果想用离线的文本转语音可以试试LocalAI HOT 1
- BUG: 请求文本中不能包含SSML的预定义字符
- 音频格式报错
- 问下作者,这个api要怎么用啊 谢谢 HOT 2
- token 好像无效
- 推荐部署服务到本地的termux HOT 3
- 「Feature」Add API support HOT 1
- 请问如何修改默认的音频格式 HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ms-ra-forwarder.