feat(web-ui): CompileTab '영상 만들기' 버튼 + createPipeline payload 시그니처
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import {
|
||||
createCompileJob, getCompileJobs, deleteCompileJob, exportCompileJob,
|
||||
createPipeline, startPipeline,
|
||||
} from '../../../api';
|
||||
|
||||
const fmtDuration = (sec) => {
|
||||
@@ -10,7 +11,7 @@ const fmtDuration = (sec) => {
|
||||
return `${m}분 ${s}초`;
|
||||
};
|
||||
|
||||
export default function CompileTab({ library }) {
|
||||
export default function CompileTab({ library, onSwitchToPipeline }) {
|
||||
const [jobs, setJobs] = useState([]);
|
||||
const [selected, setSelected] = useState([]); // [{id, title, audio_url}] in order
|
||||
const [crossfade, setCrossfade] = useState(3);
|
||||
@@ -89,6 +90,19 @@ export default function CompileTab({ library }) {
|
||||
if (exportData && exportData.id === jobId) setExportData(null);
|
||||
};
|
||||
|
||||
const handleVideoFromCompile = async (jobId) => {
|
||||
if (!window.confirm('이 mix로 영상 파이프라인을 시작할까요?')) return;
|
||||
try {
|
||||
const p = await createPipeline({ compile_job_id: jobId });
|
||||
await startPipeline(p.id);
|
||||
if (onSwitchToPipeline) {
|
||||
onSwitchToPipeline(p.id);
|
||||
}
|
||||
} catch (e) {
|
||||
alert(`파이프라인 시작 실패: ${e.message || e}`);
|
||||
}
|
||||
};
|
||||
|
||||
const totalMin = selected.length > 0
|
||||
? Math.round(selected.reduce((acc, t) => {
|
||||
const match = library.find(l => l.id === t.id);
|
||||
@@ -215,6 +229,12 @@ export default function CompileTab({ library }) {
|
||||
>
|
||||
{exportingId === j.id ? '...' : '↓ 내보내기'}
|
||||
</button>
|
||||
<button type="button"
|
||||
className="cmp-btn-video"
|
||||
onClick={() => handleVideoFromCompile(j.id)}
|
||||
>
|
||||
🎬 영상 만들기
|
||||
</button>
|
||||
</>
|
||||
)}
|
||||
{j.status === 'failed' && (
|
||||
|
||||
Reference in New Issue
Block a user