Closed w970028619 closed 1 year ago
请在阅读的朗读引擎设置中选择网络导入此链接。
你当成书源导入了吧?
对,本程序作用就是简化请求方式,方便阅读调用。
没有当成书源导入。按照你的说明 在引擎设置里网络导入了 但是没有显示
那不知道了,是你自己的问题。
好吧 我用了两部手机测试 一个是安卓系统一个ios系统。都是在语音设置里网络导入。把edge接口的连接复制进去。然后确定就没反应了 不过还是感谢作者。这个软件能支持爱阅书香吗? http的连接方式就是自定义tts
既然是安卓系统推荐用TTS Server Android,直接通过系统TTS播放,还可设置旁白对话朗读。
嗯嗯 安卓已经下载了。就是想在ios上用 感谢作者白忙之中回复我。不折腾了 还是弄不了 感谢
你说的软件,只要能支持POST请求就可以
支持post请求 但是我该如何找到网址啊 按f12是元素里面找吗?
支持post求情 但是我该如何找到网址 按f12打开开发者工具后 再元素栏里面吗
有具体文档么?我帮你看看
let token = localStorage.getItem("token")
document.getElementsByName('token')[0].value = token
let voices = [];
fetch('https://speech.platform.bing.com/consumer/speech/synthesize/readaloud/voices/list?trustedclienttoken=6A5AA1D4EAFF4E9FB37E23D68491D6F4')
.then(response => {
if (response.status === 200) {
return response.json();
} else {
return response.text().then(text => Promise.reject(text));
}
}).then(data => {
voices = data;
refreshVoice();
}).catch(reason => {
alert(reason);
});
function refreshVoice() {
let langElement = document.getElementsByName('language')[0]
langElement.innerHTML = ''
let localeList = new Map()
voices.forEach(item => {
let friendlyName = item['FriendlyName']
let locale = item['Locale']
if (!localeList.has(locale)) {
localeList.set(locale, cnLocalLanguage[locale] || friendlyName.split('- ')[1])
}
});
//排序语言列表
const sortMap = new Map([...localeList.entries()].sort((a, b) => a[1].localeCompare(b[1])));
sortMap.forEach((value, key) => {
let option = document.createElement('option');
option.value = key
option.innerText = value
if (key === "zh-CN") option.selected = true
langElement.appendChild(option)
})
updateLanguageConfig()
}
function updateLanguageConfig() {
let voiceElement = document.getElementsByName('voiceName')[0];
let language = document.getElementsByName('language')[0].value
voiceElement.innerHTML = ''
let voiceMap = new Map()
voices.forEach(function (value, key) {
if (value['locale'] === language) {
let pro = value['properties']
voiceMap.set(value['shortName'], (pro['LocalName'] ?? pro['ShortName']) + '-' + pro['LocaleDescription'])
}
})
updateVoiceConfig()
}
function updateVoiceConfig() {
let voiceElement = document.getElementsByName('voiceName')[0];
let language = document.getElementsByName('language')[0].value;
voiceElement.innerHTMl = '';
voices.forEach(value => {
if (value['Locale'] === language) {
let option = document.createElement('option');
let shortName = value['ShortName']
option.value = shortName
option.innerText = cnLocalVoice[shortName] + "(" + shortName + ")" || shortName;
voiceElement.append(option)
}
})
updateConfigName()
}
function updateConfigName() {
let voice = document.getElementsByName('voiceName')[0].value;
document.getElementsByName('name')[0].value = '大声朗读1233(' + voice + ')';
}
function createSSML(text, voiceName) {
return '\
<speak xmlns="http://www.w3.org/2001/10/synthesis" xmlns:mstts="http://www.w3.org/2001/mstts" xmlns:emo="http://www.w3.org/2009/10/emotionml" version="1.0" xml:lang="en-US">\
<voice name="' + voiceName + '">\
<prosody rate="0%" pitch="0%">\
' + text + '\
</prosody >\
</voice >\
</speak > ';
}
function preview() {
let headers = {'Content-Type': 'text/plain'};
let voiceName = document.getElementsByName('voiceName')[0].value;
let previewText = document.getElementsByName('previewText')[0].value;
let ssml = createSSML(previewText, voiceName)
let voiceFormat = document.getElementsByName('voiceFormat')[0].value;
let token = document.getElementsByName('token')[0].value;
headers['Format'] = voiceFormat
localStorage.setItem("token", token)
if (token) headers['Token'] = token
let button = document.getElementById('previewButton')
let textInfo = document.getElementById('audioInfoLabel')
button.disabled = true
textInfo.innerText = "大小: 0kb | 耗时: 0ms"
let startTime = Date.now()
let ctx = new AudioContext();
fetch('/api/ra', {
method: 'post',
headers: headers,
body: ssml
}).then(response => {
if (response.status === 200) {
let audioSize = response.headers.get("Content-Length")
let elapsedTme = Date.now() - startTime
textInfo.innerText =
`大小: ${unitConversion(audioSize)} | 耗时: ${elapsedTme}ms`
return response.arrayBuffer()
} else {
return response.text().then(text => Promise.reject(text));
}
}).then(arrayBuffer => ctx.decodeAudioData(arrayBuffer))
.then(audio => {
let player = ctx.createBufferSource();
player.buffer = audio;
player.connect(ctx.destination);
player.start(ctx.currentTime);
})
.catch(reason => {
alert(reason);
})
.finally(() => {
button.disabled = false
});
}
function createLegadoUrl() {
let name = document.getElementsByName('name')[0].value;
let voiceName = document.getElementsByName('voiceName')[0].value;
let voiceFormat = document.getElementsByName('voiceFormat')[0].value;
let token = document.getElementsByName('token')[0].value;
let interval = localStorage.getItem('interval') || 5000
let url = window.location.protocol + '//' + window.location.host + '/api/legado?api=' + encodeURI(window.location.protocol + '//' + window.location.host + '/api/ra')
+ '&name=' + encodeURI(name)
+ '&voiceName=' + voiceName
+ '&voiceFormat=' + voiceFormat
+ '&token=' + token
+ '&concurrentRate=' + interval
let modal = new bootstrap.Modal(document.getElementById('legadoUrlModal'))
document.getElementById('legadoUrlQRCode').innerHTML = ''
/* 折叠二维码 */
let bsCollapse = new bootstrap.Collapse(document.getElementById('qrCodeCollapse'), {
toggle: false
})
bsCollapse.hide()
document.getElementById('legadoUrl').value = url;
modal.show();
localStorage.setItem("token", token)
}
额?你发网页源码干嘛
那应该去哪里找呀
这我就不知道了,软件总会提供使用文档给用户吧?
此功能需要一定的专业知识,你需要从某个平台申请语音合成的API接口,或者是从某个地方得到合成接口。一般情况下,是一个HTTP请求后,得到一段语音数据。
特殊字段名:playData表示最终取得的语音数据 特殊响应名称:ResponseData来表示整个响应结果 前置步骤的意思是:第一次请求请问合成时才需要用到,之后再次请求合成时,是不会再调用的。如先同登陆,认证后才可以调用语音合成接口一样。 图片
可以使用ResponseData来表示整个响应结果,比如请求后得到的数据全部是语音,则可以添加解析字段:playData=ResponseData
情形1 调用http://aa.xx.com/tts?text=要合成的数据&volume=100 得到了一段语音数据
则在爱阅书香可以这样设置: 1地址输入:http://aa.xx.com/tts?text=%@&volume=100 2解析字段输入:playData=ResponseData 测试发音效果
情形2 调用http://aa.xx.com/tts?text=要合成的数据&volume=100 得到了一个数据,数据中包括了一个语音合成的地址。再次访问得到的语音合成地址后,才能得到最终的语音数据
则在爱阅书香可以这样设置: 1地址输入:http://aa.xx.com/tts?text=%@&volume=100 2解析字段输入:audioUrl=@json:xxx, 其中audioUrl表示一个变量,方便后面使用,@json:则与书源教程中一致,表示如何解析出数据 3添加一个TTS语音步骤 4在第二个步骤中的地址输入:@json:audioUrl 表示从上一个结果中取得地址 5在第二步骤的解析字段输入:playData=ResponseData 6测试发音效果
情形3 需要先认证时,请在第一个步骤中输入认证的HTTP及参数,之前根据情况,与情形1或情形2类似
更多情形请自行多多研究哦,有问题请加群一起谈论。群号在公众号iosRead或是打开爱阅书香-设置-关于爱阅书香
不成,貌似不支持POST。 IOS好像有个 源阅读APP,这个我从酷安得知可以导入阅读APP的TTS链接
源阅读 我通过自签安装了 但是在语音设置里导入大声朗读接口没有反应 语音设置 右上角菜单 然后通过网络导入 和通过二维码导入, 导入后没有任何显示 在安卓系统的阅读app也是一样的 没有引擎出来 貌似问题又回到了开始
这……我没设备也无法,你可以去酷安阅读APP话题下问问
非常感谢您 一直在帮助我,非常感激 谢谢
不知道为什么安卓阅读app 二维码导入和网络导入方式都没有tts出来,点击导入之后直接就消失了,什么都没出现,然后这个功能就是电脑当作转发服务器,然后手机请求电脑 电脑在发送到微软来请求语音是吗? ios有个爱阅书香,不知道怎么导入,请求作者帮帮我,很困扰