feat(installer-rp): auto-start install with progress card grid
2단계 페이지 진입 즉시 설치를 시작하고, 음악·사진을 1번부터 카드 그리드로 한눈에 볼 수 있게 만든다. 다운로드는 % 게이지로, 완료/실패는 색상으로 표시. - main: prep/item/package phase 의 ProgressEvent 를 renderer 로 송신 - music.ts: yt-dlp stdout 의 [download] X% 라인을 파싱해 onProgress 호출 - preload: onProgress 채널 구독 함수 노출 - renderer: 다음 버튼 제거, prep chip + music/image 카드 그리드 + 빌드 상태 - styles: progressCard / prepChip / progressGrid 스타일 추가 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -14,6 +14,8 @@ export interface DownloadMusicOptions {
|
||||
log?: (line: string) => void
|
||||
/** 현재 실행 중인 자식 프로세스를 외부에 알림 (취소용). */
|
||||
onChild?: (child: ChildProcess) => void
|
||||
/** yt-dlp 의 다운로드 퍼센트 (0~100). 변환 단계는 별도. */
|
||||
onProgress?: (percent: number) => void
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,9 +42,28 @@ export function downloadMusicTrack(opts: DownloadMusicOptions): Promise<string>
|
||||
const child = spawn(opts.ytdlpExe, args, { stdio: ['ignore', 'pipe', 'pipe'] })
|
||||
opts.onChild?.(child)
|
||||
let stderr = ''
|
||||
let stdoutBuf = ''
|
||||
let lastReportedPct = -1
|
||||
child.stdout?.on('data', (chunk: Buffer) => {
|
||||
const line = chunk.toString('utf8').trimEnd()
|
||||
if (line) opts.log?.(`yt-dlp> ${line}`)
|
||||
stdoutBuf += chunk.toString('utf8')
|
||||
// yt-dlp 는 `[download] 3.3% of 3.72MiB at ...` 형식으로
|
||||
// \r 로 같은 줄을 갱신한다. \r 과 \n 을 모두 split 해서 마지막 진행률을 뽑는다.
|
||||
const lines = stdoutBuf.split(/[\r\n]/)
|
||||
stdoutBuf = lines.pop() ?? ''
|
||||
for (const raw of lines) {
|
||||
const line = raw.trimEnd()
|
||||
if (!line) continue
|
||||
opts.log?.(`yt-dlp> ${line}`)
|
||||
const m = line.match(/\[download\]\s+([\d.]+)%/)
|
||||
if (m) {
|
||||
const pct = Math.min(100, Math.max(0, parseFloat(m[1])))
|
||||
// 너무 잦은 이벤트를 피하기 위해 1% 단위로만 전달.
|
||||
if (Math.floor(pct) !== lastReportedPct) {
|
||||
lastReportedPct = Math.floor(pct)
|
||||
opts.onProgress?.(pct)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
child.stderr?.on('data', (chunk: Buffer) => {
|
||||
stderr += chunk.toString('utf8')
|
||||
|
||||
Reference in New Issue
Block a user