-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathautomatic-voice-to-text-conversion.js
152 lines (138 loc) · 5.64 KB
/
automatic-voice-to-text-conversion.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// ==UserScript==
// @name Automatic voice to text conversion
// @description 语音自动转文字
// @run-at main, chat
// @version 0.1
// @author [email protected],PRO
// @license gpl-3.0
// ==/UserScript==
(function () {
// 获取当前脚本的路径
const self = document.currentScript?.getAttribute("data-scriptio-script");
let enabled = false; // 标识是否已启用脚本
const ipcRenderer = window.scriptio.ipcRenderer; // 获取Electron IPC Renderer对象
/** 来源:llapi **/
let { webContentsId } = ipcRenderer.sendSync("___!boot");
if (!webContentsId) {
webContentsId = "2"; // 设置默认的webContentsId
}
// 定义一个对象析构器类
class Destructor {
// 析构Peer对象
destructPeer(peer) {
return {
// 根据聊天类型返回不同的值:1表示好友,2表示群组,默认为1
chatType: peer.chatType == "friend" ? 1 : peer.chatType == "group" ? 2 : 1,
peerUid: peer.uid, // 对方的UID
guildId: "", // 公会ID,暂时为空字符串
};
}
}
const destructor = new Destructor(); // 创建析构器实例
/**
* 来源:llapi
* @description 语音转文字(实验性)
* @param {string} msgId 消息ID
* @param {object} peer 对象的Peer,包含uid和chatType
* @param {MessageElement[]} elements 消息元素数组
*/
async function Ptt2Text(msgId, peer, elements) {
const msgElement = JSON.parse(JSON.stringify(elements)); // 深拷贝消息元素
// 调用ntCall方法,发送语音转文字的请求
await ntCall("ns-ntApi", "nodeIKernelMsgService/translatePtt2Text", [
{
msgId: msgId,
peer: destructor.destructPeer(peer), // 析构Peer对象
msgElement: msgElement // 消息元素
},
null
]);
}
/** 来源:llapi */
// 发送NT调用的通用函数
function ntCall(eventName, cmdName, args, isRegister = false) {
return new Promise(async (resolve, reject) => {
const uuid = crypto.randomUUID(); // 生成随机UUID
// 发送IPC请求
ipcRenderer.send(
`IPC_UP_${webContentsId}`,
{
type: "request",
callbackId: uuid,
eventName: `${eventName}-${webContentsId}${isRegister ? "-register" : ""}`,
},
[cmdName, ...args]
);
resolve("data"); // 返回数据
});
}
// 延迟函数
const sleep = (delay) => new Promise((resolve) => setTimeout(resolve, delay));
// 处理函数,用于处理组件
async function process(component) {
const el = component?.vnode?.el; // 获取虚拟DOM元素
if (!el || !(el instanceof Element)) {
return; // 如果元素不存在或不是Element类型,直接返回
}
if (!el.querySelector(".ptt-element__bottom-area")) {
return; // 如果没有找到指定的类名元素,直接返回
}
const ptt_area = el.querySelector(".ptt-element__bottom-area"); // 获取语音消息区域元素
if (ptt_area) {
const msgId = component?.props?.msgRecord?.msgId; // 获取消息ID
if (msgId !== undefined) {
// 如果当前界面打开了语音输入框,并且是自己的消息,延迟处理
if (document.querySelector('.audio-msg-input') && ptt_area.closest(".message-container--self")) {
await sleep(500); // 延迟500毫秒
}
const msgRecord = component?.props?.msgRecord; // 获取消息记录
if (msgRecord) {
const elements = msgRecord.elements[0]; // 获取消息元素
const { chatType, peerUid } = msgRecord; // 获取聊天类型和对方UID
let chatTypeValue = '';
if (chatType === 1) {
chatTypeValue = 'friend'; // 好友聊天
} else if (chatType === 2) {
chatTypeValue = 'group'; // 群组聊天
}
// 执行语音转文字的方法
await Ptt2Text(msgId, { uid: peerUid, guildId: '', chatType: chatTypeValue }, elements);
}
ptt_area.style.display = "block"; // 显示语音消息区域
}
}
}
function enable() {
if (enabled) return;
if (!window.__VUE_MOUNT__) {
window.__VUE_MOUNT__ = [];
}
enabled = true;
console.log("语音自动转文字已开启");
window.__VUE_MOUNT__.push(process);
}
function disable() {
enabled = false;
console.log("语音自动转文字已关闭");
if (!enabled) return;
const index = window.__VUE_MOUNT__.indexOf(process);
if (index > -1) {
window.__VUE_MOUNT__.splice(index, 1);
}
}
if (window.__VUE_MOUNT__) {
enable();
} else {
window.addEventListener("vue-hooked", enable, { once: true });
}
window.addEventListener("scriptio-toggle", (event) => {
const path = event.detail.path;
if (path === self) {
if (event.detail.enabled) {
enable();
} else {
disable();
}
}
});
})();