Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9abf6da5f1 |
@@ -94,6 +94,7 @@
|
|||||||
"musicTrackDone": "{{idx}}번 노래 완료: {{name}}",
|
"musicTrackDone": "{{idx}}번 노래 완료: {{name}}",
|
||||||
"musicTrackSkip": "{{idx}}번 노래는 이전에 받아둠 → 건너뜀(이어받기)",
|
"musicTrackSkip": "{{idx}}번 노래는 이전에 받아둠 → 건너뜀(이어받기)",
|
||||||
"musicRefreshRetry": "{{count}}곡 다운로드 실패 → yt-dlp/ffmpeg 최신 버전으로 재설치 후 실패한 곡만 재시도",
|
"musicRefreshRetry": "{{count}}곡 다운로드 실패 → yt-dlp/ffmpeg 최신 버전으로 재설치 후 실패한 곡만 재시도",
|
||||||
|
"musicTrackRetryWait": "{{idx}}번 노래 재시도 {{attempt}}회차 — 유튜브 속도제한(403) 회피로 {{secs}}초 대기 후 다시 시도",
|
||||||
"ytdlpReinstall": "yt-dlp.exe 최신 버전으로 강제 재설치 중…",
|
"ytdlpReinstall": "yt-dlp.exe 최신 버전으로 강제 재설치 중…",
|
||||||
"ffmpegReinstall": "ffmpeg.exe 최신 버전으로 강제 재설치 중…",
|
"ffmpegReinstall": "ffmpeg.exe 최신 버전으로 강제 재설치 중…",
|
||||||
"imageStart": "사진 다운로드 시작 ({{total}}장)",
|
"imageStart": "사진 다운로드 시작 ({{total}}장)",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "minecraft-music-quiz-installer",
|
"name": "minecraft-music-quiz-installer",
|
||||||
"version": "0.4.13",
|
"version": "0.4.14",
|
||||||
"description": "마인크래프트 음악퀴즈 간편설치기 + 관리 사이트",
|
"description": "마인크래프트 음악퀴즈 간편설치기 + 관리 사이트",
|
||||||
"main": "dist/installer/main.js",
|
"main": "dist/installer/main.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -493,11 +493,25 @@ ipcMain.handle('rp:install:start', async (): Promise<{ resourcepackPath: string
|
|||||||
await refreshBinariesOnce()
|
await refreshBinariesOnce()
|
||||||
throwIfCancelled()
|
throwIfCancelled()
|
||||||
nextMusicStartAt = Date.now()
|
nextMusicStartAt = Date.now()
|
||||||
|
// 403(Forbidden)은 대개 유튜브의 일시적 rate-limit 이라, 곡마다 점점 더 오래
|
||||||
|
// 쉬면서 여러 번 다시 시도한다(마지막 시도에서만 에러 진행률 표시).
|
||||||
|
const MAX_TRACK_RETRIES = 3
|
||||||
for (const i of failed) {
|
for (const i of failed) {
|
||||||
throwIfCancelled()
|
throwIfCancelled()
|
||||||
|
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()
|
await acquireMusicStartSlot()
|
||||||
throwIfCancelled()
|
throwIfCancelled()
|
||||||
const ok = await tryDownloadTrack(i, true)
|
ok = await tryDownloadTrack(i, attempt === MAX_TRACK_RETRIES)
|
||||||
|
if (ok) break
|
||||||
|
}
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
throwIfCancelled()
|
throwIfCancelled()
|
||||||
const idx = i + 1
|
const idx = i + 1
|
||||||
|
|||||||
@@ -46,6 +46,9 @@ export function downloadMusicTrack(opts: DownloadMusicOptions): Promise<string>
|
|||||||
'--extractor-retries', '3',
|
'--extractor-retries', '3',
|
||||||
'--retry-sleep', 'http:exp=1:30',
|
'--retry-sleep', 'http:exp=1:30',
|
||||||
'--socket-timeout', '30',
|
'--socket-timeout', '30',
|
||||||
|
// 특정 플레이어 클라이언트(예: android_vr)의 스트림 URL 이 403 되는 경우가 있어
|
||||||
|
// 여러 클라이언트를 함께 시도한다. 하나가 막혀도 다른 클라이언트 포맷으로 받는다.
|
||||||
|
'--extractor-args', 'youtube:player_client=default,web_safari,tv,ios',
|
||||||
// 진행률 표시 안정화 (yt-dlp 가 \r 대신 새 줄로 출력).
|
// 진행률 표시 안정화 (yt-dlp 가 \r 대신 새 줄로 출력).
|
||||||
'--newline',
|
'--newline',
|
||||||
'--extract-audio',
|
'--extract-audio',
|
||||||
|
|||||||
Reference in New Issue
Block a user