Initial commit
This commit is contained in:
75
lib/config/audio-config.ts
Normal file
75
lib/config/audio-config.ts
Normal file
@ -0,0 +1,75 @@
|
||||
// 音频配置管理 - 简化版
|
||||
export interface AudioFormat {
|
||||
mimeType: string;
|
||||
extension: string;
|
||||
codec: string;
|
||||
quality: "low" | "medium" | "high" | "lossless";
|
||||
maxBitrate: number;
|
||||
}
|
||||
|
||||
// 支持的音频格式配置
|
||||
export const SUPPORTED_AUDIO_FORMATS: Record<string, AudioFormat> = {
|
||||
webm: {
|
||||
mimeType: "audio/webm;codecs=opus",
|
||||
extension: ".webm",
|
||||
codec: "opus",
|
||||
quality: "high",
|
||||
maxBitrate: 128000,
|
||||
},
|
||||
ogg: {
|
||||
mimeType: "audio/ogg;codecs=opus",
|
||||
extension: ".ogg",
|
||||
codec: "opus",
|
||||
quality: "high",
|
||||
maxBitrate: 192000,
|
||||
},
|
||||
aac: {
|
||||
mimeType: "audio/aac",
|
||||
extension: ".aac",
|
||||
codec: "aac",
|
||||
quality: "high",
|
||||
maxBitrate: 256000,
|
||||
},
|
||||
};
|
||||
|
||||
// 获取浏览器支持的音频格式
|
||||
export function getSupportedFormats(): AudioFormat[] {
|
||||
const supported: AudioFormat[] = [];
|
||||
|
||||
// 检查 WebM 支持
|
||||
if (MediaRecorder.isTypeSupported("audio/webm;codecs=opus")) {
|
||||
supported.push(SUPPORTED_AUDIO_FORMATS.webm);
|
||||
}
|
||||
|
||||
// 检查 OGG 支持
|
||||
if (MediaRecorder.isTypeSupported("audio/ogg;codecs=opus")) {
|
||||
supported.push(SUPPORTED_AUDIO_FORMATS.ogg);
|
||||
}
|
||||
|
||||
// 检查 AAC 支持
|
||||
if (MediaRecorder.isTypeSupported("audio/aac")) {
|
||||
supported.push(SUPPORTED_AUDIO_FORMATS.aac);
|
||||
}
|
||||
|
||||
// 如果没有支持的格式,至少返回 WebM
|
||||
if (supported.length === 0) {
|
||||
supported.push(SUPPORTED_AUDIO_FORMATS.webm);
|
||||
}
|
||||
|
||||
return supported;
|
||||
}
|
||||
|
||||
// 获取最佳录音格式
|
||||
export function getBestRecordingFormat(): AudioFormat {
|
||||
const supported = getSupportedFormats();
|
||||
return supported[0] || SUPPORTED_AUDIO_FORMATS.webm;
|
||||
}
|
||||
|
||||
// 格式化文件大小
|
||||
export function formatFileSize(bytes: number): string {
|
||||
if (bytes === 0) return "0 B";
|
||||
const k = 1024;
|
||||
const sizes = ["B", "KB", "MB", "GB"];
|
||||
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + " " + sizes[i];
|
||||
}
|
||||
60
lib/config/index.ts
Normal file
60
lib/config/index.ts
Normal file
@ -0,0 +1,60 @@
|
||||
// 环境变量验证
|
||||
const validateEnv = () => {
|
||||
const requiredEnvVars = ["DATABASE_URL", "NEXTAUTH_SECRET", "NEXTAUTH_URL"];
|
||||
|
||||
const missingVars = requiredEnvVars.filter(
|
||||
(varName) => !process.env[varName]
|
||||
);
|
||||
|
||||
if (missingVars.length > 0) {
|
||||
throw new Error(`缺少必需的环境变量: ${missingVars.join(", ")}`);
|
||||
}
|
||||
};
|
||||
|
||||
// 在开发环境中验证环境变量
|
||||
if (process.env.NODE_ENV === "development") {
|
||||
validateEnv();
|
||||
}
|
||||
|
||||
export const config = {
|
||||
app: {
|
||||
name: "录音应用",
|
||||
version: "1.0.0",
|
||||
environment: process.env.NODE_ENV || "development",
|
||||
},
|
||||
|
||||
database: {
|
||||
url: process.env.DATABASE_URL!,
|
||||
},
|
||||
|
||||
auth: {
|
||||
secret: process.env.NEXTAUTH_SECRET!,
|
||||
url: process.env.NEXTAUTH_URL!,
|
||||
google: {
|
||||
clientId: process.env.GOOGLE_CLIENT_ID,
|
||||
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
|
||||
},
|
||||
},
|
||||
|
||||
upload: {
|
||||
maxFileSize: 50 * 1024 * 1024, // 50MB
|
||||
allowedTypes: ["audio/webm", "audio/mp3", "audio/ogg", "audio/aac"],
|
||||
uploadDir: "public/recordings",
|
||||
},
|
||||
|
||||
api: {
|
||||
rateLimit: {
|
||||
windowMs: 15 * 60 * 1000, // 15 minutes
|
||||
max: 100, // limit each IP to 100 requests per windowMs
|
||||
},
|
||||
},
|
||||
|
||||
features: {
|
||||
audioVisualization: true,
|
||||
recordingPause: true,
|
||||
fileDownload: true,
|
||||
userSettings: true,
|
||||
},
|
||||
} as const;
|
||||
|
||||
export type Config = typeof config;
|
||||
Reference in New Issue
Block a user