음악 제작 랩 추가
This commit is contained in:
31
src/api.js
31
src/api.js
@@ -246,6 +246,37 @@ export function deleteSellHistory(id) {
|
|||||||
return apiDelete(`/api/portfolio/sell-history/${id}`);
|
return apiDelete(`/api/portfolio/sell-history/${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ── AI 음악 생성 API ──────────────────────────────────────────────────────────
|
||||||
|
// POST /api/music/generate body: { genre, moods, instruments, duration_sec, bpm, key, scale, prompt }
|
||||||
|
// → { task_id: string }
|
||||||
|
export function generateMusic(payload) {
|
||||||
|
return apiPost('/api/music/generate', payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET /api/music/status/:task_id
|
||||||
|
// → { status: "queued"|"processing"|"succeeded"|"failed", progress: 0~100, message, audio_url?, error? }
|
||||||
|
export function getMusicStatus(taskId) {
|
||||||
|
return apiGet(`/api/music/status/${encodeURIComponent(taskId)}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// GET /api/music/library
|
||||||
|
// → { tracks: [{ id, title, genre, moods, instruments, duration_id, bpm, key, scale, audio_url, created_at }] }
|
||||||
|
export function getMusicLibrary() {
|
||||||
|
return apiGet('/api/music/library');
|
||||||
|
}
|
||||||
|
|
||||||
|
// POST /api/music/library body: track object
|
||||||
|
// → saved track with id
|
||||||
|
export function saveMusicTrack(data) {
|
||||||
|
return apiPost('/api/music/library', data);
|
||||||
|
}
|
||||||
|
|
||||||
|
// DELETE /api/music/library/:id
|
||||||
|
// → { ok: true }
|
||||||
|
export function deleteMusicTrack(id) {
|
||||||
|
return apiDelete(`/api/music/library/${id}`);
|
||||||
|
}
|
||||||
|
|
||||||
// ── 로또 고도화 API ────────────────────────────────────────────────────────────
|
// ── 로또 고도화 API ────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
// GET /api/lotto/stats/performance
|
// GET /api/lotto/stats/performance
|
||||||
|
|||||||
@@ -25,6 +25,17 @@ const LAB_ITEMS = [
|
|||||||
icon: '📅',
|
icon: '📅',
|
||||||
status: 'live',
|
status: 'live',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: 'music',
|
||||||
|
path: '/lab/music',
|
||||||
|
title: 'Sonic Forge',
|
||||||
|
category: 'AI · 음악 제작',
|
||||||
|
desc: 'AI가 장르·분위기·악기를 조합해 완성된 트랙을 만들어줍니다. 유튜브 수익화를 위한 음악 제작 스튜디오.',
|
||||||
|
tags: ['AI 음악', '생성', 'YouTube'],
|
||||||
|
accent: '#f5a623',
|
||||||
|
icon: '🎵',
|
||||||
|
status: 'wip',
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const STATUS_LABEL = {
|
const STATUS_LABEL = {
|
||||||
|
|||||||
1714
src/pages/music/MusicStudio.css
Normal file
1714
src/pages/music/MusicStudio.css
Normal file
File diff suppressed because it is too large
Load Diff
1141
src/pages/music/MusicStudio.jsx
Normal file
1141
src/pages/music/MusicStudio.jsx
Normal file
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,7 @@ const EffectLab = lazy(() => import('./pages/effect-lab/EffectLab'));
|
|||||||
const SwordStream = lazy(() => import('./pages/effect-lab/SwordStream'));
|
const SwordStream = lazy(() => import('./pages/effect-lab/SwordStream'));
|
||||||
const DayCalc = lazy(() => import('./pages/effect-lab/DayCalc'));
|
const DayCalc = lazy(() => import('./pages/effect-lab/DayCalc'));
|
||||||
const Todo = lazy(() => import('./pages/todo/Todo'));
|
const Todo = lazy(() => import('./pages/todo/Todo'));
|
||||||
|
const MusicStudio = lazy(() => import('./pages/music/MusicStudio'));
|
||||||
|
|
||||||
export const navLinks = [
|
export const navLinks = [
|
||||||
{
|
{
|
||||||
@@ -143,6 +144,10 @@ export const appRoutes = [
|
|||||||
path: 'lab/day-calc',
|
path: 'lab/day-calc',
|
||||||
element: <DayCalc />,
|
element: <DayCalc />,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: 'lab/music',
|
||||||
|
element: <MusicStudio />,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'todo',
|
path: 'todo',
|
||||||
element: <Todo />,
|
element: <Todo />,
|
||||||
|
|||||||
Reference in New Issue
Block a user