Spaces:
Sleeping
Sleeping
| import { JobData, StatusResponse } from '../types'; | |
| const safeBase64Encode = (str: string): string => { | |
| return btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, (match, p1) => { | |
| return String.fromCharCode(parseInt('0x' + p1)); | |
| })); | |
| }; | |
| const uploadAudioToOrchestrator = async (file: Blob | File, runId: string, suffix: string): Promise<string> => { | |
| const formData = new FormData(); | |
| const ext = (file as File).name?.split('.').pop()?.toLowerCase() || 'wav'; | |
| formData.append('run_id', `${runId}_${suffix}`); | |
| formData.append('ext', ext); | |
| formData.append('file', file); | |
| const response = await fetch('https://opera8-action.hf.space/api/webhook/upload', { | |
| method: 'POST', | |
| body: formData | |
| }); | |
| if (!response.ok) throw new Error("خطا در آپلود فایل صوتی به سرور پشتیبان."); | |
| return ext; | |
| }; | |
| /** | |
| * Uploads a job to the FastAPI RVC Legacy backend via the load-balanced GitHub Actions orchestrator. | |
| */ | |
| export const uploadLegacyJob = async ( | |
| sourceFile: Blob | File, | |
| modelUrl: string, | |
| pitch: number, | |
| modelMetadata: { name?: string, image?: string }, | |
| algo: string = "rmvpe+", | |
| indexInf: number = 0.75 | |
| ): Promise<JobData> => { | |
| const currentRunId = "rvc" + Math.random().toString(36).substring(2, 14); | |
| // ۱. آپلود فایل صوتی ورودی به ارکستریتور ابری | |
| const audioExt = await uploadAudioToOrchestrator(sourceFile, currentRunId, 'rvc_audio'); | |
| // ۲. رمزگذاری آدرسها و آمادهسازی کلید پیکربندی آرویسی | |
| const b64ModelUrl = safeBase64Encode(modelUrl); | |
| const b64SpaceUrl = safeBase64Encode("https://r3gm-rvc-zero.hf.space"); | |
| const rvcPayload = `RVCCONFIG_userRunId_${currentRunId}_audioExt_${audioExt}_pitchAlgo_${algo}_pitchLvl_${pitch}_indexInf_${indexInf}_denoise_false_reverb_false_modelUrl_${b64ModelUrl}_spaceUrl_${b64SpaceUrl}`; | |
| // ۳. ارسال درخواست به بکاند ابری جهت توزیع در صف گیتهاب | |
| const response = await fetch('https://opera8-action.hf.space/api/generate', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ | |
| prompt: rvcPayload, | |
| action_name: 'rvc-voice' | |
| }) | |
| }); | |
| if (!response.ok) { | |
| const errData = await response.json().catch(() => ({})); | |
| throw new Error(errData.message || `خطا در تخصیص صف گیتهاب: ${response.status}`); | |
| } | |
| const data = await response.json(); | |
| const finalRunId = data.run_id || currentRunId; | |
| return { | |
| job_id: finalRunId, | |
| status: 'started', | |
| progress: 10, | |
| statusMessage: 'در صف انتظار سرورهای موازی ...', | |
| total_chunks: 1, | |
| chunks: [], | |
| date: new Date().toLocaleString('fa-IR'), | |
| timestamp: Date.now(), | |
| type: 'model', | |
| modelName: modelMetadata.name, | |
| modelImage: modelMetadata.image, | |
| retryCount: 0, | |
| backend: 'legacy' | |
| }; | |
| }; | |
| /** | |
| * Checks the status of a legacy job on the orchestrator. | |
| */ | |
| export const checkLegacyStatus = async (jobId: string): Promise<StatusResponse> => { | |
| try { | |
| const response = await fetch(`/api/status/${jobId}`); | |
| if (!response.ok) throw new Error(`بررسی وضعیت با خطا مواجه شد: ${response.status}`); | |
| const data = await response.json(); | |
| let status: 'processing' | 'completed' | 'failed' | 'error' = 'processing'; | |
| if (data.status === 'ready') status = 'completed'; | |
| else if (data.status === 'failed') status = 'failed'; | |
| else if (data.status === 'not_found' || data.status === 'error') status = 'error'; | |
| return { | |
| status, | |
| progress: data.status === 'ready' ? 100 : (data.status === 'processing' ? 50 : 10), | |
| filename: data.url ? data.url.split('/').pop() : undefined, | |
| detail: data.message || (data.status === 'ready' ? 'تکمیل شد' : 'در حال پردازش در سرور ابری...'), | |
| downloadUrl: data.url ? data.url : undefined | |
| }; | |
| } catch (e) { | |
| return { status: 'processing', progress: 10, detail: 'درحال تلاش برای برقراری ارتباط با سرور...' }; | |
| } | |
| }; |