Skip to content
This repository has been archived by the owner on Nov 2, 2023. It is now read-only.

feat: 调整接口参数,调整语音编码方式为silk #484

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 24 additions & 22 deletions lib/internal/contactable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import path from "path"
import querystring from "querystring"
import axios from "axios"
import { Readable } from "stream"
import { pcm2slk } from 'node-silk';
import { randomBytes } from "crypto"
import { exec } from "child_process"
import { tea, pb, ApiRejection } from "../core"
Expand Down Expand Up @@ -120,7 +121,7 @@ export abstract class Contactable {
const res1 = await Promise.allSettled(tasks) as PromiseRejectedResult[]
for (let i = 0; i < res1.length; i++) {
if (res1[i].status === "rejected")
this.c.logger.warn(`图片${i+1}失败, reason: ` + res1[i].reason?.message)
this.c.logger.warn(`图片${i + 1}失败, reason: ` + res1[i].reason?.message)
}
let n = 0
while (imgs.length > n) {
Expand All @@ -129,13 +130,13 @@ export abstract class Contactable {
const tasks: Promise<any>[] = []
for (let i = n; i < imgs.length; ++i) {
if (i >= n + 20) break
tasks.push(this._uploadImage(imgs[i] as Image, rsp[i%20]))
tasks.push(this._uploadImage(imgs[i] as Image, rsp[i % 20]))
}
const res2 = await Promise.allSettled(tasks) as PromiseRejectedResult[]
for (let i = 0; i < res2.length; i++) {
if (res2[i].status === "rejected") {
res1[n+i] = res2[i]
this.c.logger.warn(`图片${n+i+1}上传失败, reason: ` + res2[i].reason?.message)
res1[n + i] = res2[i]
this.c.logger.warn(`图片${n + i + 1}上传失败, reason: ` + res2[i].reason?.message)
}
}
n += 20
Expand All @@ -146,27 +147,27 @@ export abstract class Contactable {

private async _uploadImage(img: Image, rsp: pb.Proto) {
const j = this.dm ? 1 : 0
if (rsp[2+j] !== 0)
throw new Error(String(rsp[3+j]))
img.fid = rsp[9+j].toBuffer?.() || rsp[9+j]
if (rsp[4+j]) {
if (rsp[2 + j] !== 0)
throw new Error(String(rsp[3 + j]))
img.fid = rsp[9 + j].toBuffer?.() || rsp[9 + j]
if (rsp[4 + j]) {
img.deleteTmpFile()
return
}
if (!img.readable) {
img.deleteCacheFile()
return
}
const ip = rsp[6+j]?.[0] || rsp[6+j]
const port = rsp[7+j]?.[0] || rsp[7+j]
const ip = rsp[6 + j]?.[0] || rsp[6 + j]
const port = rsp[7 + j]?.[0] || rsp[7 + j]
return highwayUpload.call(
this.c,
img.readable,
{
cmdid: j ? CmdID.DmImage : CmdID.GroupImage,
md5: img.md5,
size: img.size,
ticket: rsp[8+j].toBuffer()
ticket: rsp[8 + j].toBuffer()
},
ip, port
).finally(img.deleteTmpFile.bind(img))
Expand Down Expand Up @@ -329,7 +330,7 @@ export abstract class Contactable {
10: this.c.apk.version,
12: 1,
13: 1,
14: codec,
14: 0,
15: 1,
},
})
Expand Down Expand Up @@ -464,7 +465,7 @@ export abstract class Contactable {
})
}
for (const maker of makers)
imgs = [ ...imgs, ...maker.imgs ]
imgs = [...imgs, ...maker.imgs]
if (imgs.length)
await this.uploadImages(imgs)
const compressed = await gzip(pb.encode({
Expand Down Expand Up @@ -530,12 +531,14 @@ export abstract class Contactable {
const port = rsp[5]?.[0] || rsp[5]
let url = port == 443 ? "https://ssl.htdata.qq.com" : `http://${ip}:${port}`
url += rsp[2]
let { data, headers } = await axios.get(url, { headers: {
"User-Agent": `QQ/${this.c.apk.version} CFNetwork/1126`,
"Net-Type": "Wifi"
}, responseType: "arraybuffer"})
let { data, headers } = await axios.get(url, {
headers: {
"User-Agent": `QQ/${this.c.apk.version} CFNetwork/1126`,
"Net-Type": "Wifi"
}, responseType: "arraybuffer"
})
data = Buffer.from(data as ArrayBuffer)
let buf = headers["accept-encoding"]?.includes("gzip") ? await unzip(data as Buffer) : data as Buffer
let buf = headers["accept-encoding"]?.includes("gzip") ? await unzip(data as Buffer) : data as Buffer
const head_len = buf.readUInt32BE(1)
const body_len = buf.readUInt32BE(5)
buf = tea.decrypt(buf.slice(head_len + 9, head_len + 9 + body_len), rsp[3].toBuffer())
Expand Down Expand Up @@ -628,12 +631,11 @@ async function getPttBuffer(file: string | Buffer, ffmpeg = "ffmpeg"): Promise<B
function audioTrans(file: string, ffmpeg = "ffmpeg"): Promise<Buffer> {
return new Promise((resolve, reject) => {
const tmpfile = path.join(TMP_DIR, uuid())
exec(`${ffmpeg} -y -i "${file}" -ac 1 -ar 8000 -f amr "${tmpfile}"`, async (error, stdout, stderr) => {
exec(`${ffmpeg} -i "${file}" -f s16le -ac 1 -ar 24000 "${tmpfile}"`, async (error, stdout, stderr) => {
try {
const amr = await fs.promises.readFile(tmpfile)
resolve(amr)
resolve(pcm2slk(fs.readFileSync(tmpfile)))
} catch {
reject(new ApiRejection(ErrorCode.FFmpegPttTransError, "音频转码到amr失败,请确认你的ffmpeg可以处理此转换"))
reject(new ApiRejection(ErrorCode.FFmpegPttTransError, "音频转码到pcm失败,请确认你的ffmpeg可以处理此转换"))
} finally {
fs.unlink(tmpfile, NOOP)
}
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
"axios": "^1.1.2",
"log4js": "^6.3.0",
"long": "^4.0.0",
"node-silk": "^0.1.0",
"pngjs": "^6.0.0",
"probe-image-size": "^7.2.2"
},
Expand All @@ -45,4 +46,4 @@
"/lib/**/*.d.ts",
"/lib/**/LICENSE"
]
}
}
Loading