Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f53e54493d | |||
| 9abf6da5f1 |
@@ -1067,6 +1067,9 @@ function renderStep5() {
|
||||
section.innerHTML =
|
||||
'<h2>' + tt('step5.heading') + '</h2>' +
|
||||
'<p>' + tt('step5.summary') + '</p>' +
|
||||
'<div style="margin:12px 0;padding:14px 16px;border:1px solid var(--warning, #d9a441);border-radius:10px;background:rgba(217,164,65,0.12);font-size:14px;font-weight:600;line-height:1.55;">' +
|
||||
'⚠ ' + escapeHtml(tt('step5.resourcepackWarning')) +
|
||||
'</div>' +
|
||||
(showServerActions ? '<div class="subStep">' +
|
||||
'<h3>' + tt('step5.serverHeading') + '</h3>' +
|
||||
'<button class="secondaryBtn" id="openFolder">' + tt('step5.openServerFolder') + '</button>' +
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
"musicTrackDone": "{{idx}}번 노래 완료: {{name}}",
|
||||
"musicTrackSkip": "{{idx}}번 노래는 이전에 받아둠 → 건너뜀(이어받기)",
|
||||
"musicRefreshRetry": "{{count}}곡 다운로드 실패 → yt-dlp/ffmpeg 최신 버전으로 재설치 후 실패한 곡만 재시도",
|
||||
"musicTrackRetryWait": "{{idx}}번 노래 재시도 {{attempt}}회차 — 유튜브 속도제한(403) 회피로 {{secs}}초 대기 후 다시 시도",
|
||||
"ytdlpReinstall": "yt-dlp.exe 최신 버전으로 강제 재설치 중…",
|
||||
"ffmpegReinstall": "ffmpeg.exe 최신 버전으로 강제 재설치 중…",
|
||||
"imageStart": "사진 다운로드 시작 ({{total}}장)",
|
||||
|
||||
@@ -163,6 +163,7 @@
|
||||
"step5": {
|
||||
"heading": "설치 완료",
|
||||
"summary": "",
|
||||
"resourcepackWarning": "리소스팩은 리소스팩 설치기로 설치해서 마인크래프트 내에서 직접 적용해야 합니다.",
|
||||
"serverHeading": "서버",
|
||||
"openServerFolder": "서버 폴더 열기",
|
||||
"shortcut": "바탕화면에 서버 실행 바로가기 만들기",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "minecraft-music-quiz-installer",
|
||||
"version": "0.4.13",
|
||||
"version": "0.4.15",
|
||||
"description": "마인크래프트 음악퀴즈 간편설치기 + 관리 사이트",
|
||||
"main": "dist/installer/main.js",
|
||||
"scripts": {
|
||||
|
||||
@@ -493,11 +493,25 @@ ipcMain.handle('rp:install:start', async (): Promise<{ resourcepackPath: string
|
||||
await refreshBinariesOnce()
|
||||
throwIfCancelled()
|
||||
nextMusicStartAt = Date.now()
|
||||
// 403(Forbidden)은 대개 유튜브의 일시적 rate-limit 이라, 곡마다 점점 더 오래
|
||||
// 쉬면서 여러 번 다시 시도한다(마지막 시도에서만 에러 진행률 표시).
|
||||
const MAX_TRACK_RETRIES = 3
|
||||
for (const i of failed) {
|
||||
throwIfCancelled()
|
||||
await acquireMusicStartSlot()
|
||||
throwIfCancelled()
|
||||
const ok = await tryDownloadTrack(i, true)
|
||||
let ok = false
|
||||
for (let attempt = 1; attempt <= MAX_TRACK_RETRIES; attempt++) {
|
||||
throwIfCancelled()
|
||||
if (attempt > 1) {
|
||||
const waitMs = Math.min(20000, 3000 * attempt)
|
||||
sendLog(t('log.musicTrackRetryWait', { idx: i + 1, attempt, secs: Math.round(waitMs / 1000) }))
|
||||
await sleep(waitMs)
|
||||
throwIfCancelled()
|
||||
}
|
||||
await acquireMusicStartSlot()
|
||||
throwIfCancelled()
|
||||
ok = await tryDownloadTrack(i, attempt === MAX_TRACK_RETRIES)
|
||||
if (ok) break
|
||||
}
|
||||
if (!ok) {
|
||||
throwIfCancelled()
|
||||
const idx = i + 1
|
||||
|
||||
@@ -46,6 +46,9 @@ export function downloadMusicTrack(opts: DownloadMusicOptions): Promise<string>
|
||||
'--extractor-retries', '3',
|
||||
'--retry-sleep', 'http:exp=1:30',
|
||||
'--socket-timeout', '30',
|
||||
// 특정 플레이어 클라이언트(예: android_vr)의 스트림 URL 이 403 되는 경우가 있어
|
||||
// 여러 클라이언트를 함께 시도한다. 하나가 막혀도 다른 클라이언트 포맷으로 받는다.
|
||||
'--extractor-args', 'youtube:player_client=default,web_safari,tv,ios',
|
||||
// 진행률 표시 안정화 (yt-dlp 가 \r 대신 새 줄로 출력).
|
||||
'--newline',
|
||||
'--extract-audio',
|
||||
|
||||
Reference in New Issue
Block a user