song/status 수정 .
parent
b6ece9891a
commit
5b2450ed60
|
|
@ -1,6 +1,6 @@
|
||||||
|
|
||||||
import React, { useState, useRef, useEffect } from 'react';
|
import React, { useState, useRef, useEffect } from 'react';
|
||||||
import { generateLyric, waitForLyricComplete, generateSong, waitForSongComplete, getSongsList } from '../../utils/api';
|
import { generateLyric, waitForLyricComplete, generateSong, waitForSongComplete } from '../../utils/api';
|
||||||
import { LANGUAGE_MAP } from '../../types/api';
|
import { LANGUAGE_MAP } from '../../types/api';
|
||||||
|
|
||||||
interface BusinessInfo {
|
interface BusinessInfo {
|
||||||
|
|
@ -105,18 +105,9 @@ const SoundStudioContent: React.FC<SoundStudioContentProps> = ({
|
||||||
throw new Error(statusResponse.error_message || '음악 생성에 실패했습니다.');
|
throw new Error(statusResponse.error_message || '음악 생성에 실패했습니다.');
|
||||||
}
|
}
|
||||||
|
|
||||||
// 노래 생성 완료 후 songs 목록에서 최신 task_id와 song_result_url 가져오기
|
// song_result_url을 사용하여 재생
|
||||||
const songsResponse = await getSongsList(1, 1);
|
setSongTaskId(taskId);
|
||||||
if (songsResponse.items && songsResponse.items.length > 0) {
|
setAudioUrl(statusResponse.song_result_url);
|
||||||
const latestSong = songsResponse.items[0];
|
|
||||||
setSongTaskId(latestSong.task_id);
|
|
||||||
// song_result_url을 사용하여 재생
|
|
||||||
setAudioUrl(latestSong.song_result_url);
|
|
||||||
} else {
|
|
||||||
// fallback: 기존 데이터 사용
|
|
||||||
setSongTaskId(taskId);
|
|
||||||
setAudioUrl(statusResponse.song_url);
|
|
||||||
}
|
|
||||||
|
|
||||||
setStatus('complete');
|
setStatus('complete');
|
||||||
setStatusMessage('');
|
setStatusMessage('');
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ export interface SongStatusResponse {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
status: string;
|
status: string;
|
||||||
message: string;
|
message: string;
|
||||||
song_url: string | null;
|
song_result_url: string | null;
|
||||||
error_message: string | null;
|
error_message: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -214,23 +214,3 @@ export interface UserMeResponse {
|
||||||
created_at: string;
|
created_at: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 노래 목록 아이템
|
|
||||||
export interface SongListItem {
|
|
||||||
store_name: string;
|
|
||||||
region: string;
|
|
||||||
task_id: string;
|
|
||||||
language: string;
|
|
||||||
song_result_url: string;
|
|
||||||
created_at: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 노래 목록 응답
|
|
||||||
export interface SongsListResponse {
|
|
||||||
items: SongListItem[];
|
|
||||||
total: number;
|
|
||||||
page: number;
|
|
||||||
page_size: number;
|
|
||||||
total_pages: number;
|
|
||||||
has_next: boolean;
|
|
||||||
has_prev: boolean;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import {
|
||||||
SongGenerateResponse,
|
SongGenerateResponse,
|
||||||
SongStatusResponse,
|
SongStatusResponse,
|
||||||
SongDownloadResponse,
|
SongDownloadResponse,
|
||||||
SongsListResponse,
|
|
||||||
VideoGenerateResponse,
|
VideoGenerateResponse,
|
||||||
VideoStatusResponse,
|
VideoStatusResponse,
|
||||||
VideoDownloadResponse,
|
VideoDownloadResponse,
|
||||||
|
|
@ -181,23 +180,11 @@ export async function downloadSong(taskId: string): Promise<SongDownloadResponse
|
||||||
return response.json();
|
return response.json();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 노래 목록 조회 API
|
|
||||||
export async function getSongsList(page: number = 1, pageSize: number = 10): Promise<SongsListResponse> {
|
|
||||||
const response = await fetch(`${API_URL}/songs/?page=${page}&page_size=${pageSize}`, {
|
|
||||||
method: 'GET',
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!response.ok) {
|
|
||||||
throw new Error(`HTTP error! status: ${response.status}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.json();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 노래 생성 완료까지 폴링 (5분 타임아웃, 3초 간격)
|
// 노래 생성 완료까지 폴링 (5분 타임아웃, 3초 간격)
|
||||||
// Suno API 상태: PENDING, processing, SUCCESS, TEXT_SUCCESS, failed, error
|
// Suno API 상태: PENDING, processing, SUCCESS, failed, error
|
||||||
const SONG_POLL_TIMEOUT = 5 * 60 * 1000; // 5분
|
const SONG_POLL_TIMEOUT = 5 * 60 * 1000; // 5분
|
||||||
const SONG_POLL_INTERVAL = 3000; // 3초
|
const SONG_POLL_INTERVAL = 3000; // 3초
|
||||||
|
const SONG_URL_RETRY_DELAY = 4000; // SUCCESS인데 song_result_url 없을 때 재요청 대기 시간 (4초)
|
||||||
|
|
||||||
export async function waitForSongComplete(
|
export async function waitForSongComplete(
|
||||||
songId: string,
|
songId: string,
|
||||||
|
|
@ -215,9 +202,15 @@ export async function waitForSongComplete(
|
||||||
const response = await getSongStatus(songId);
|
const response = await getSongStatus(songId);
|
||||||
onStatusChange?.(response.status);
|
onStatusChange?.(response.status);
|
||||||
|
|
||||||
// SUCCESS 또는 TEXT_SUCCESS: Suno API 노래 생성 완료
|
// SUCCESS: Suno API 노래 생성 완료
|
||||||
if ((response.status === 'SUCCESS' || response.status === 'TEXT_SUCCESS') && response.success) {
|
if (response.status === 'SUCCESS' && response.success) {
|
||||||
return response;
|
// song_result_url이 있으면 완료
|
||||||
|
if (response.song_result_url) {
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
// song_result_url이 없으면 4초 후 재요청
|
||||||
|
await new Promise(resolve => setTimeout(resolve, SONG_URL_RETRY_DELAY));
|
||||||
|
return poll();
|
||||||
}
|
}
|
||||||
|
|
||||||
// failed 또는 error: Suno API 노래 생성 실패
|
// failed 또는 error: Suno API 노래 생성 실패
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue