Read selected text with OpenAI's TTS API
目前為
// ==UserScript==
// @name OpenAI TTS Text Reader with Floating Button
// @namespace http://tampermonkey.net/
// @version 1.0
// @description Read selected text with OpenAI's TTS API
// @include *
// @grant GM_xmlhttpRequest
// @license MIT
// ==/UserScript==
(function() {
'use strict';
// 创建一个悬浮的朗读按钮并添加到页面上
// 创建一个悬浮的朗读按钮并添加到页面上
var readButton = document.createElement("button");
var textSpan = document.createElement("span");
textSpan.textContent = ">"; // 初始文本
readButton.appendChild(textSpan); // 将文本span添加到按钮中
// 设置按钮样式
readButton.style.position = "fixed";
readButton.style.bottom = "20px";
readButton.style.right = "20px";
readButton.style.zIndex = "1000";
readButton.style.width = "40px"; // 设置按钮宽度为40像素
readButton.style.height = "40px"; // 设置按钮高度为40像素
readButton.style.borderRadius = "50%"; // 设置按钮为圆形
readButton.style.backgroundColor = "#4CAF50";
readButton.style.border = "none";
readButton.style.cursor = "pointer";
// 设置文本span的样式
textSpan.style.color = "white"; // 设置文本颜色为白色
textSpan.style.fontSize = "20px"; // 设置字体大小
textSpan.style.textAlign = "center"; // 文本居中
textSpan.style.lineHeight = "40px"; // 设置行高以垂直居中文本
textSpan.style.transition = "opacity 0.4s ease"; // 设置文本的透明度过渡
// 添加按下动画的样式
readButton.style.transition = "transform 0.1s ease";
readButton.addEventListener('mousedown', function() {
this.style.transform = "scale(0.9)";
});
readButton.addEventListener('mouseup', function() {
this.style.transform = "scale(1)";
});
readButton.addEventListener('mouseleave', function() {
this.style.transform = "scale(1)";
});
// 将按钮添加到页面
document.body.appendChild(readButton);
/*
// 创建一个悬浮的朗读按钮并添加到页面上
var readButton = document.createElement("button");
readButton.textContent = "朗读选中文本";
readButton.style.position = "fixed";
readButton.style.bottom = "20px";
readButton.style.right = "20px";
readButton.style.zIndex = 1000;
readButton.style.padding = "10px";
readButton.style.borderRadius = "5px";
readButton.style.backgroundColor = "#4CAF50";
readButton.style.color = "white";
readButton.style.border = "none";
readButton.style.cursor = "pointer";
document.body.appendChild(readButton);
*/
// 按钮点击事件
readButton.addEventListener('click', function() {
var selectedText = window.getSelection().toString();
if (selectedText) {
TextToSpeech(selectedText);
} else {
alert("请先选择一些文本。");
}
});
function TextToSpeech(s) {
var sModelId = "tts-1";
var sVoiceId = "nova";
var API_KEY = "YOUR_API_KEY"; // 替换为你的 OpenAI API Key
ShowSpinner();
GM_xmlhttpRequest({
method: "POST",
url: "https://api.openai.com/v1/audio/speech",
headers: {
"Accept": "audio/mpeg",
"Content-Type": "application/json",
"Authorization": "Bearer " + API_KEY
},
data: JSON.stringify({
model: sModelId,
input: s,
voice: sVoiceId
}),
responseType: "arraybuffer",
onload: function (response) {
HideSpinner();
if (response.status === 200) {
var audioContext = new AudioContext();
audioContext.decodeAudioData(response.response, function(buffer) {
var source = audioContext.createBufferSource();
source.buffer = buffer;
source.connect(audioContext.destination);
source.start(0);
}, function(e) {
console.log("Audio error! ", e);
});
}
}
});
}
function ShowSpinner() {
// 淡出文本
textSpan.style.opacity = '0';
setTimeout(function() {
textSpan.textContent = "..."; // 更改文本
textSpan.style.opacity = '1';
}, 400); // 等待文本完全淡出后更改
readButton.disabled = true; // 禁用按钮以防止重复点击
}
function HideSpinner() {
// 淡出文本
textSpan.style.opacity = '0';
setTimeout(function() {
textSpan.textContent = ">"; // 恢复原始文本
textSpan.style.opacity = '1';
}, 400); // 等待文本完全淡出后更改
readButton.disabled = false; // 启用按钮
}
})();