init base app modules
This commit is contained in:
25
apps/aliyun-ai/bun.config.mjs
Normal file
25
apps/aliyun-ai/bun.config.mjs
Normal file
@@ -0,0 +1,25 @@
|
||||
// @ts-check
|
||||
import { resolvePath } from '@kevisual/use-config/env';
|
||||
import { execSync } from 'node:child_process';
|
||||
|
||||
const entry = 'src/index.ts';
|
||||
const naming = 'app';
|
||||
const external = ['sequelize', 'pg', 'sqlite3', 'minio', '@kevisual/router', 'pm2'];
|
||||
/**
|
||||
* @type {import('bun').BuildConfig}
|
||||
*/
|
||||
await Bun.build({
|
||||
target: 'node',
|
||||
format: 'esm',
|
||||
entrypoints: [resolvePath(entry, { meta: import.meta })],
|
||||
outdir: resolvePath('./dist', { meta: import.meta }),
|
||||
naming: {
|
||||
entry: `${naming}.js`,
|
||||
},
|
||||
external: external,
|
||||
env: 'KEVISUAL_*',
|
||||
});
|
||||
|
||||
// const cmd = `dts -i src/index.ts -o app.d.ts`;
|
||||
// const cmd = `dts -i ${entry} -o ${naming}.d.ts`;
|
||||
// execSync(cmd, { stdio: 'inherit' });
|
||||
27
apps/aliyun-ai/package.json
Normal file
27
apps/aliyun-ai/package.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"name": "aliyun-ai",
|
||||
"version": "0.0.1",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"basename": "/root/aliyun-ai",
|
||||
"app": {
|
||||
"key": "aliyun-ai",
|
||||
"entry": "dist/app.js",
|
||||
"type": "system-app"
|
||||
},
|
||||
"files": [
|
||||
"dist"
|
||||
],
|
||||
"scripts": {
|
||||
"dev": "cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 bun --watch src/dev.ts ",
|
||||
"build": "rimraf dist && bun run bun.config.mjs",
|
||||
"clean": "rm -rf dist",
|
||||
"pub": "npm run build && envision pack -p -u"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "abearxiong <xiongxiao@xiongxiao.me> (https://www.xiongxiao.me)",
|
||||
"license": "MIT",
|
||||
"packageManager": "pnpm@10.12.1",
|
||||
"type": "module",
|
||||
"devDependencies": {}
|
||||
}
|
||||
4
apps/aliyun-ai/src/app.ts
Normal file
4
apps/aliyun-ai/src/app.ts
Normal file
@@ -0,0 +1,4 @@
|
||||
import { app } from '@/modules/router.ts';
|
||||
import { oss } from '@/modules/minio.ts';
|
||||
import { config } from '@/modules/config.ts';
|
||||
export { app, config, oss };
|
||||
6
apps/aliyun-ai/src/dev.ts
Normal file
6
apps/aliyun-ai/src/dev.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { app } from './index.ts';
|
||||
|
||||
app.listen(4000, () => {
|
||||
console.log('Server is running on http://localhost:4000');
|
||||
console.log('Press Ctrl+C to stop the server');
|
||||
});
|
||||
5
apps/aliyun-ai/src/index.ts
Normal file
5
apps/aliyun-ai/src/index.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { app } from './app.ts';
|
||||
|
||||
import './routes/create-audio.ts';
|
||||
|
||||
export { app };
|
||||
75
apps/aliyun-ai/src/routes/create-audio.ts
Normal file
75
apps/aliyun-ai/src/routes/create-audio.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import { app, config, oss } from '../app.ts';
|
||||
import { dashscopeTTS } from '@/examples/dash-scope/tts.ts';
|
||||
import { randomLetter } from '@/utils/random.ts';
|
||||
import dayjs from 'dayjs';
|
||||
type DashScopeTTSResponse = {
|
||||
output?: {
|
||||
finish_reason?: string;
|
||||
audio?: {
|
||||
expires_at?: number;
|
||||
data?: string;
|
||||
id?: string;
|
||||
url?: string;
|
||||
};
|
||||
};
|
||||
usage?: {
|
||||
input_tokens_details?: {
|
||||
text_tokens?: number;
|
||||
};
|
||||
total_tokens?: number;
|
||||
output_tokens?: number;
|
||||
input_tokens?: number;
|
||||
output_tokens_details?: {
|
||||
audio_tokens?: number;
|
||||
text_tokens?: number;
|
||||
};
|
||||
};
|
||||
request_id?: string;
|
||||
};
|
||||
app
|
||||
.route({
|
||||
path: 'aliyun-ai',
|
||||
key: 'createVideos',
|
||||
})
|
||||
.define(async (ctx) => {
|
||||
const { text, model, save = 'none' } = ctx.query;
|
||||
if (!text) {
|
||||
ctx.throw(400, 'Text and model are required parameters');
|
||||
}
|
||||
const value: DashScopeTTSResponse = await dashscopeTTS({
|
||||
text,
|
||||
voice: model || 'Chelsie',
|
||||
token: config.BAILIAN_API_KEY,
|
||||
});
|
||||
const url = value?.output?.audio?.url;
|
||||
const fileName = `audio-${randomLetter(32)}.wav`;
|
||||
const username = 'share';
|
||||
const today = dayjs().format('YYYY-MM-DD');
|
||||
// 使用用户名和日期作为文件夹路径
|
||||
const filePath = `${username}/storage/aliyun-ai/audio/${today}/${fileName}`;
|
||||
if (url) {
|
||||
ctx.body = {
|
||||
audioUrl: url,
|
||||
};
|
||||
}
|
||||
if (save === 'minio' && url) {
|
||||
// 读取文件url地址的数据,并保存到 MinIO, 文件是 音频 wave 格式
|
||||
const audioData = await fetch(url).then((res) => res.arrayBuffer());
|
||||
|
||||
// 将音频数据转换为 Buffer 并上传到 MinIO
|
||||
const buffer = Buffer.from(audioData);
|
||||
await oss.client.putObject(oss.bucketName, filePath, buffer, null, {
|
||||
'Content-Type': 'audio/wav',
|
||||
'app-source': 'aliyun-ai',
|
||||
share: 'public',
|
||||
});
|
||||
console.log('Audio file uploaded to MinIO:', filePath);
|
||||
// @ts-ignore
|
||||
ctx.body.minio = filePath;
|
||||
}
|
||||
// 如果没有 url,抛出错误
|
||||
if (!url) {
|
||||
ctx.throw(500, 'Failed to create audio');
|
||||
}
|
||||
})
|
||||
.addTo(app);
|
||||
Reference in New Issue
Block a user