mirror of
https://github.com/NapNeko/NapCatQQ.git
synced 2025-07-19 12:03:37 +00:00
fix: #739
This commit is contained in:
151
src/common/ffmpeg-worker.ts
Normal file
151
src/common/ffmpeg-worker.ts
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
import { FFmpeg } from '@ffmpeg.wasm/main';
|
||||||
|
import { randomUUID } from 'crypto';
|
||||||
|
import { readFileSync, statSync, writeFileSync } from 'fs';
|
||||||
|
import type { LogWrapper } from './log';
|
||||||
|
import type { VideoInfo } from './video';
|
||||||
|
import { fileTypeFromFile } from 'file-type';
|
||||||
|
import imageSize from 'image-size';
|
||||||
|
class FFmpegService {
|
||||||
|
public static async extractThumbnail(videoPath: string, thumbnailPath: string): Promise<void> {
|
||||||
|
const ffmpegInstance = await FFmpeg.create({ core: '@ffmpeg.wasm/core-mt' });
|
||||||
|
const videoFileName = `${randomUUID()}.mp4`;
|
||||||
|
const outputFileName = `${randomUUID()}.jpg`;
|
||||||
|
try {
|
||||||
|
ffmpegInstance.fs.writeFile(videoFileName, readFileSync(videoPath));
|
||||||
|
let code = await ffmpegInstance.run('-i', videoFileName, '-ss', '00:00:01.000', '-vframes', '1', outputFileName);
|
||||||
|
if (code !== 0) {
|
||||||
|
throw new Error('Error extracting thumbnail: FFmpeg process exited with code ' + code);
|
||||||
|
}
|
||||||
|
const thumbnail = ffmpegInstance.fs.readFile(outputFileName);
|
||||||
|
writeFileSync(thumbnailPath, thumbnail);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error extracting thumbnail:', error);
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
ffmpegInstance.fs.unlink(outputFileName);
|
||||||
|
} catch (unlinkError) {
|
||||||
|
console.error('Error unlinking output file:', unlinkError);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
ffmpegInstance.fs.unlink(videoFileName);
|
||||||
|
} catch (unlinkError) {
|
||||||
|
console.error('Error unlinking video file:', unlinkError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async convertFile(inputFile: string, outputFile: string, format: string): Promise<void> {
|
||||||
|
const ffmpegInstance = await FFmpeg.create({ core: '@ffmpeg.wasm/core-mt' });
|
||||||
|
const inputFileName = `${randomUUID()}.pcm`;
|
||||||
|
const outputFileName = `${randomUUID()}.${format}`;
|
||||||
|
try {
|
||||||
|
ffmpegInstance.fs.writeFile(inputFileName, readFileSync(inputFile));
|
||||||
|
const params = format === 'amr'
|
||||||
|
? ['-f', 's16le', '-ar', '24000', '-ac', '1', '-i', inputFileName, '-ar', '8000', '-b:a', '12.2k', outputFileName]
|
||||||
|
: ['-f', 's16le', '-ar', '24000', '-ac', '1', '-i', inputFileName, outputFileName];
|
||||||
|
let code = await ffmpegInstance.run(...params);
|
||||||
|
if (code !== 0) {
|
||||||
|
throw new Error('Error extracting thumbnail: FFmpeg process exited with code ' + code);
|
||||||
|
}
|
||||||
|
const outputData = ffmpegInstance.fs.readFile(outputFileName);
|
||||||
|
writeFileSync(outputFile, outputData);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error converting file:', error);
|
||||||
|
throw error;
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
ffmpegInstance.fs.unlink(outputFileName);
|
||||||
|
} catch (unlinkError) {
|
||||||
|
console.error('Error unlinking output file:', unlinkError);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
ffmpegInstance.fs.unlink(inputFileName);
|
||||||
|
} catch (unlinkError) {
|
||||||
|
console.error('Error unlinking input file:', unlinkError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async convert(filePath: string, pcmPath: string, logger: LogWrapper): Promise<Buffer> {
|
||||||
|
const ffmpegInstance = await FFmpeg.create({ core: '@ffmpeg.wasm/core-mt' });
|
||||||
|
const inputFileName = `${randomUUID()}.input`;
|
||||||
|
const outputFileName = `${randomUUID()}.pcm`;
|
||||||
|
try {
|
||||||
|
ffmpegInstance.fs.writeFile(inputFileName, readFileSync(filePath));
|
||||||
|
const params = ['-y', '-i', inputFileName, '-ar', '24000', '-ac', '1', '-f', 's16le', outputFileName];
|
||||||
|
let code = await ffmpegInstance.run(...params);
|
||||||
|
if (code !== 0) {
|
||||||
|
throw new Error('FFmpeg process exited with code ' + code);
|
||||||
|
}
|
||||||
|
const outputData = ffmpegInstance.fs.readFile(outputFileName);
|
||||||
|
writeFileSync(pcmPath, outputData);
|
||||||
|
return Buffer.from(outputData);
|
||||||
|
} catch (error: any) {
|
||||||
|
throw new Error('FFmpeg处理转换出错: ' + error.message);
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
ffmpegInstance.fs.unlink(outputFileName);
|
||||||
|
} catch (unlinkError) {
|
||||||
|
logger.log('Error unlinking output file:', unlinkError);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
ffmpegInstance.fs.unlink(inputFileName);
|
||||||
|
} catch (unlinkError) {
|
||||||
|
logger.log('Error unlinking input file:', unlinkError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async getVideoInfo(videoPath: string, thumbnailPath: string): Promise<VideoInfo> {
|
||||||
|
await FFmpegService.extractThumbnail(videoPath, thumbnailPath);
|
||||||
|
let fileType = (await fileTypeFromFile(videoPath))?.ext ?? 'mp4';
|
||||||
|
const inputFileName = `${randomUUID()}.${fileType}`;
|
||||||
|
const ffmpegInstance = await FFmpeg.create({ core: '@ffmpeg.wasm/core-mt' });
|
||||||
|
ffmpegInstance.fs.writeFile(inputFileName, readFileSync(videoPath));
|
||||||
|
ffmpegInstance.setLogging(true);
|
||||||
|
let duration = 60;
|
||||||
|
ffmpegInstance.setLogger((level, ...msg) => {
|
||||||
|
const message = msg.join(' ');
|
||||||
|
const durationMatch = message.match(/Duration: (\d+):(\d+):(\d+\.\d+)/);
|
||||||
|
if (durationMatch) {
|
||||||
|
const hours = parseInt(durationMatch[1], 10);
|
||||||
|
const minutes = parseInt(durationMatch[2], 10);
|
||||||
|
const seconds = parseFloat(durationMatch[3]);
|
||||||
|
duration = hours * 3600 + minutes * 60 + seconds;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
await ffmpegInstance.run('-i', inputFileName);
|
||||||
|
let image = imageSize(thumbnailPath);
|
||||||
|
ffmpegInstance.fs.unlink(inputFileName);
|
||||||
|
const fileSize = statSync(videoPath).size;
|
||||||
|
return {
|
||||||
|
width: image.width ?? 100,
|
||||||
|
height: image.height ?? 100,
|
||||||
|
time: duration,
|
||||||
|
format: fileType,
|
||||||
|
size: fileSize,
|
||||||
|
filePath: videoPath
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type FFmpegMethod = 'extractThumbnail' | 'convertFile' | 'convert' | 'getVideoInfo';
|
||||||
|
|
||||||
|
interface FFmpegTask {
|
||||||
|
method: FFmpegMethod;
|
||||||
|
args: any[];
|
||||||
|
}
|
||||||
|
export default async function handleFFmpegTask({ method, args }: FFmpegTask): Promise<any> {
|
||||||
|
switch (method) {
|
||||||
|
case 'extractThumbnail':
|
||||||
|
return await FFmpegService.extractThumbnail(...args as [string, string]);
|
||||||
|
case 'convertFile':
|
||||||
|
return await FFmpegService.convertFile(...args as [string, string, string]);
|
||||||
|
case 'convert':
|
||||||
|
return await FFmpegService.convert(...args as [string, string, LogWrapper]);
|
||||||
|
case 'getVideoInfo':
|
||||||
|
return await FFmpegService.getVideoInfo(...args as [string, string]);
|
||||||
|
default:
|
||||||
|
throw new Error(`Unknown method: ${method}`);
|
||||||
|
}
|
||||||
|
}
|
@@ -1,131 +1,50 @@
|
|||||||
import { FFmpeg } from '@ffmpeg.wasm/main';
|
import Piscina from "piscina";
|
||||||
import { randomUUID } from 'crypto';
|
import { VideoInfo } from "./video";
|
||||||
import { readFileSync, statSync, writeFileSync } from 'fs';
|
import type { LogWrapper } from "./log";
|
||||||
import { LogWrapper } from './log';
|
|
||||||
import { VideoInfo } from './video';
|
type EncodeArgs = {
|
||||||
import { fileTypeFromFile } from 'file-type';
|
method: 'extractThumbnail' | 'convertFile' | 'convert' | 'getVideoInfo';
|
||||||
import imageSize from 'image-size';
|
args: any[];
|
||||||
|
};
|
||||||
|
|
||||||
|
type EncodeResult = any;
|
||||||
|
|
||||||
|
async function getWorkerPath() {
|
||||||
|
return new URL(/* @vite-ignore */ './ffmpeg-worker.mjs', import.meta.url).href;
|
||||||
|
}
|
||||||
|
|
||||||
export class FFmpegService {
|
export class FFmpegService {
|
||||||
public static async extractThumbnail(videoPath: string, thumbnailPath: string): Promise<void> {
|
public static async extractThumbnail(videoPath: string, thumbnailPath: string): Promise<void> {
|
||||||
const ffmpegInstance = await FFmpeg.create({ core: '@ffmpeg.wasm/core-mt' });
|
const piscina = new Piscina<EncodeArgs, EncodeResult>({
|
||||||
const videoFileName = `${randomUUID()}.mp4`;
|
filename: await getWorkerPath(),
|
||||||
const outputFileName = `${randomUUID()}.jpg`;
|
});
|
||||||
try {
|
await piscina.run({ method: 'extractThumbnail', args: [videoPath, thumbnailPath] });
|
||||||
ffmpegInstance.fs.writeFile(videoFileName, readFileSync(videoPath));
|
await piscina.destroy();
|
||||||
let code = await ffmpegInstance.run('-i', videoFileName, '-ss', '00:00:01.000', '-vframes', '1', outputFileName);
|
|
||||||
if (code !== 0) {
|
|
||||||
throw new Error('Error extracting thumbnail: FFmpeg process exited with code ' + code);
|
|
||||||
}
|
|
||||||
const thumbnail = ffmpegInstance.fs.readFile(outputFileName);
|
|
||||||
writeFileSync(thumbnailPath, thumbnail);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error extracting thumbnail:', error);
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
ffmpegInstance.fs.unlink(outputFileName);
|
|
||||||
} catch (unlinkError) {
|
|
||||||
console.error('Error unlinking output file:', unlinkError);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
ffmpegInstance.fs.unlink(videoFileName);
|
|
||||||
} catch (unlinkError) {
|
|
||||||
console.error('Error unlinking video file:', unlinkError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async convertFile(inputFile: string, outputFile: string, format: string): Promise<void> {
|
public static async convertFile(inputFile: string, outputFile: string, format: string): Promise<void> {
|
||||||
const ffmpegInstance = await FFmpeg.create({ core: '@ffmpeg.wasm/core-mt' });
|
const piscina = new Piscina<EncodeArgs, EncodeResult>({
|
||||||
const inputFileName = `${randomUUID()}.pcm`;
|
filename: await getWorkerPath(),
|
||||||
const outputFileName = `${randomUUID()}.${format}`;
|
});
|
||||||
try {
|
await piscina.run({ method: 'convertFile', args: [inputFile, outputFile, format] });
|
||||||
ffmpegInstance.fs.writeFile(inputFileName, readFileSync(inputFile));
|
await piscina.destroy();
|
||||||
const params = format === 'amr'
|
|
||||||
? ['-f', 's16le', '-ar', '24000', '-ac', '1', '-i', inputFileName, '-ar', '8000', '-b:a', '12.2k', outputFileName]
|
|
||||||
: ['-f', 's16le', '-ar', '24000', '-ac', '1', '-i', inputFileName, outputFileName];
|
|
||||||
let code = await ffmpegInstance.run(...params);
|
|
||||||
if (code !== 0) {
|
|
||||||
throw new Error('Error extracting thumbnail: FFmpeg process exited with code ' + code);
|
|
||||||
}
|
|
||||||
const outputData = ffmpegInstance.fs.readFile(outputFileName);
|
|
||||||
writeFileSync(outputFile, outputData);
|
|
||||||
} catch (error) {
|
|
||||||
console.error('Error converting file:', error);
|
|
||||||
throw error;
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
ffmpegInstance.fs.unlink(outputFileName);
|
|
||||||
} catch (unlinkError) {
|
|
||||||
console.error('Error unlinking output file:', unlinkError);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
ffmpegInstance.fs.unlink(inputFileName);
|
|
||||||
} catch (unlinkError) {
|
|
||||||
console.error('Error unlinking input file:', unlinkError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async convert(filePath: string, pcmPath: string, logger: LogWrapper): Promise<Buffer> {
|
public static async convert(filePath: string, pcmPath: string, logger: LogWrapper): Promise<Buffer> {
|
||||||
const ffmpegInstance = await FFmpeg.create({ core: '@ffmpeg.wasm/core-mt' });
|
const piscina = new Piscina<EncodeArgs, EncodeResult>({
|
||||||
const inputFileName = `${randomUUID()}.input`;
|
filename: await getWorkerPath(),
|
||||||
const outputFileName = `${randomUUID()}.pcm`;
|
});
|
||||||
try {
|
const result = await piscina.run({ method: 'convert', args: [filePath, pcmPath, logger] });
|
||||||
ffmpegInstance.fs.writeFile(inputFileName, readFileSync(filePath));
|
await piscina.destroy();
|
||||||
const params = ['-y', '-i', inputFileName, '-ar', '24000', '-ac', '1', '-f', 's16le', outputFileName];
|
return result;
|
||||||
let code = await ffmpegInstance.run(...params);
|
|
||||||
if (code !== 0) {
|
|
||||||
throw new Error('FFmpeg process exited with code ' + code);
|
|
||||||
}
|
|
||||||
const outputData = ffmpegInstance.fs.readFile(outputFileName);
|
|
||||||
writeFileSync(pcmPath, outputData);
|
|
||||||
return Buffer.from(outputData);
|
|
||||||
} catch (error: any) {
|
|
||||||
throw new Error('FFmpeg处理转换出错: ' + error.message);
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
ffmpegInstance.fs.unlink(outputFileName);
|
|
||||||
} catch (unlinkError) {
|
|
||||||
logger.log('Error unlinking output file:', unlinkError);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
ffmpegInstance.fs.unlink(inputFileName);
|
|
||||||
} catch (unlinkError) {
|
|
||||||
logger.log('Error unlinking input file:', unlinkError);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async getVideoInfo(videoPath: string, thumbnailPath: string): Promise<VideoInfo> {
|
public static async getVideoInfo(videoPath: string, thumbnailPath: string): Promise<VideoInfo> {
|
||||||
await FFmpegService.extractThumbnail(videoPath, thumbnailPath);
|
const piscina = new Piscina<EncodeArgs, EncodeResult>({
|
||||||
let fileType = (await fileTypeFromFile(videoPath))?.ext ?? 'mp4';
|
filename: await getWorkerPath(),
|
||||||
const inputFileName = `${randomUUID()}.${fileType}`;
|
|
||||||
const ffmpegInstance = await FFmpeg.create({ core: '@ffmpeg.wasm/core-mt' });
|
|
||||||
ffmpegInstance.fs.writeFile(inputFileName, readFileSync(videoPath));
|
|
||||||
ffmpegInstance.setLogging(true);
|
|
||||||
let duration = 60;
|
|
||||||
ffmpegInstance.setLogger((level, ...msg) => {
|
|
||||||
const message = msg.join(' ');
|
|
||||||
const durationMatch = message.match(/Duration: (\d+):(\d+):(\d+\.\d+)/);
|
|
||||||
if (durationMatch) {
|
|
||||||
const hours = parseInt(durationMatch[1], 10);
|
|
||||||
const minutes = parseInt(durationMatch[2], 10);
|
|
||||||
const seconds = parseFloat(durationMatch[3]);
|
|
||||||
duration = hours * 3600 + minutes * 60 + seconds;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
await ffmpegInstance.run('-i', inputFileName);
|
const result = await piscina.run({ method: 'getVideoInfo', args: [videoPath, thumbnailPath] });
|
||||||
let image = imageSize(thumbnailPath);
|
await piscina.destroy();
|
||||||
ffmpegInstance.fs.unlink(inputFileName);
|
return result;
|
||||||
const fileSize = statSync(videoPath).size;
|
|
||||||
return {
|
|
||||||
width: image.width ?? 100,
|
|
||||||
height: image.height ?? 100,
|
|
||||||
time: duration,
|
|
||||||
format: fileType,
|
|
||||||
size: fileSize,
|
|
||||||
filePath: videoPath
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -7,6 +7,7 @@ import { RequestUtil } from '@/common/request';
|
|||||||
import { HttpClientConfig } from '@/onebot/config/config';
|
import { HttpClientConfig } from '@/onebot/config/config';
|
||||||
import { ActionMap } from '@/onebot/action';
|
import { ActionMap } from '@/onebot/action';
|
||||||
import { IOB11NetworkAdapter } from "@/onebot/network/adapter";
|
import { IOB11NetworkAdapter } from "@/onebot/network/adapter";
|
||||||
|
import json5 from 'json5';
|
||||||
|
|
||||||
export class OB11HttpClientAdapter extends IOB11NetworkAdapter<HttpClientConfig> {
|
export class OB11HttpClientAdapter extends IOB11NetworkAdapter<HttpClientConfig> {
|
||||||
constructor(
|
constructor(
|
||||||
@@ -34,7 +35,7 @@ export class OB11HttpClientAdapter extends IOB11NetworkAdapter<HttpClientConfig>
|
|||||||
}
|
}
|
||||||
|
|
||||||
const data = await RequestUtil.HttpGetText(this.config.url, 'POST', msgStr, headers);
|
const data = await RequestUtil.HttpGetText(this.config.url, 'POST', msgStr, headers);
|
||||||
const resJson: QuickAction = data ? JSON.parse(data) : {};
|
const resJson: QuickAction = data ? json5.parse(data) : {};
|
||||||
|
|
||||||
await this.obContext.apis.QuickActionApi.handleQuickOperation(event as QuickActionEvent, resJson);
|
await this.obContext.apis.QuickActionApi.handleQuickOperation(event as QuickActionEvent, resJson);
|
||||||
}
|
}
|
||||||
|
@@ -9,6 +9,7 @@ import { LifeCycleSubType, OB11LifeCycleEvent } from '@/onebot/event/meta/OB11Li
|
|||||||
import { WebsocketClientConfig } from '@/onebot/config/config';
|
import { WebsocketClientConfig } from '@/onebot/config/config';
|
||||||
import { NapCatOneBot11Adapter } from "@/onebot";
|
import { NapCatOneBot11Adapter } from "@/onebot";
|
||||||
import { IOB11NetworkAdapter } from "@/onebot/network/adapter";
|
import { IOB11NetworkAdapter } from "@/onebot/network/adapter";
|
||||||
|
import json5 from 'json5';
|
||||||
|
|
||||||
export class OB11WebSocketClientAdapter extends IOB11NetworkAdapter<WebsocketClientConfig> {
|
export class OB11WebSocketClientAdapter extends IOB11NetworkAdapter<WebsocketClientConfig> {
|
||||||
private connection: WebSocket | null = null;
|
private connection: WebSocket | null = null;
|
||||||
@@ -129,7 +130,7 @@ export class OB11WebSocketClientAdapter extends IOB11NetworkAdapter<WebsocketCli
|
|||||||
let echo = undefined;
|
let echo = undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
receiveData = JSON.parse(message.toString());
|
receiveData = json5.parse(message.toString());
|
||||||
echo = receiveData.echo;
|
echo = receiveData.echo;
|
||||||
this.logger.logDebug('[OneBot] [WebSocket Client] 收到正向Websocket消息', receiveData);
|
this.logger.logDebug('[OneBot] [WebSocket Client] 收到正向Websocket消息', receiveData);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@@ -12,6 +12,7 @@ import { LifeCycleSubType, OB11LifeCycleEvent } from '@/onebot/event/meta/OB11Li
|
|||||||
import { WebsocketServerConfig } from '@/onebot/config/config';
|
import { WebsocketServerConfig } from '@/onebot/config/config';
|
||||||
import { NapCatOneBot11Adapter } from "@/onebot";
|
import { NapCatOneBot11Adapter } from "@/onebot";
|
||||||
import { IOB11NetworkAdapter } from "@/onebot/network/adapter";
|
import { IOB11NetworkAdapter } from "@/onebot/network/adapter";
|
||||||
|
import json5 from 'json5';
|
||||||
|
|
||||||
export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketServerConfig> {
|
export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketServerConfig> {
|
||||||
wsServer: WebSocketServer;
|
wsServer: WebSocketServer;
|
||||||
@@ -162,7 +163,7 @@ export class OB11WebSocketServerAdapter extends IOB11NetworkAdapter<WebsocketSer
|
|||||||
let receiveData: { action: typeof ActionName[keyof typeof ActionName], params?: any, echo?: any } = { action: ActionName.Unknown, params: {} };
|
let receiveData: { action: typeof ActionName[keyof typeof ActionName], params?: any, echo?: any } = { action: ActionName.Unknown, params: {} };
|
||||||
let echo = undefined;
|
let echo = undefined;
|
||||||
try {
|
try {
|
||||||
receiveData = JSON.parse(message.toString());
|
receiveData = json5.parse(message.toString());
|
||||||
echo = receiveData.echo;
|
echo = receiveData.echo;
|
||||||
//this.logger.logDebug('收到正向Websocket消息', receiveData);
|
//this.logger.logDebug('收到正向Websocket消息', receiveData);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@@ -90,6 +90,7 @@ const UniversalBaseConfig = () =>
|
|||||||
entry: {
|
entry: {
|
||||||
napcat: 'src/universal/napcat.ts',
|
napcat: 'src/universal/napcat.ts',
|
||||||
'audio-worker': 'src/common/audio-worker.ts',
|
'audio-worker': 'src/common/audio-worker.ts',
|
||||||
|
'ffmpeg-worker': 'src/common/ffmpeg-worker.ts',
|
||||||
},
|
},
|
||||||
formats: ['es'],
|
formats: ['es'],
|
||||||
fileName: (_, entryName) => `${entryName}.mjs`,
|
fileName: (_, entryName) => `${entryName}.mjs`,
|
||||||
@@ -119,6 +120,7 @@ const ShellBaseConfig = () =>
|
|||||||
entry: {
|
entry: {
|
||||||
napcat: 'src/shell/napcat.ts',
|
napcat: 'src/shell/napcat.ts',
|
||||||
'audio-worker': 'src/common/audio-worker.ts',
|
'audio-worker': 'src/common/audio-worker.ts',
|
||||||
|
'ffmpeg-worker': 'src/common/ffmpeg-worker.ts',
|
||||||
},
|
},
|
||||||
formats: ['es'],
|
formats: ['es'],
|
||||||
fileName: (_, entryName) => `${entryName}.mjs`,
|
fileName: (_, entryName) => `${entryName}.mjs`,
|
||||||
@@ -147,6 +149,7 @@ const FrameworkBaseConfig = () =>
|
|||||||
entry: {
|
entry: {
|
||||||
napcat: 'src/framework/napcat.ts',
|
napcat: 'src/framework/napcat.ts',
|
||||||
'audio-worker': 'src/common/audio-worker.ts',
|
'audio-worker': 'src/common/audio-worker.ts',
|
||||||
|
'ffmpeg-worker': 'src/common/ffmpeg-worker.ts',
|
||||||
},
|
},
|
||||||
formats: ['es'],
|
formats: ['es'],
|
||||||
fileName: (_, entryName) => `${entryName}.mjs`,
|
fileName: (_, entryName) => `${entryName}.mjs`,
|
||||||
|
Reference in New Issue
Block a user