imageio_ffmpeg 기본 출력이 moov atom을 파일 끝에 둠 → 브라우저가 전체를 받기 전엔 시킹 인덱스 생성 불가, preload="none"이라 duration조차 안 읽힘. (2) webui 서버의 starlette 0.38.6은 StaticFiles Range 지원이 없어(0.45+부터 지원) Range 요청에도 200 + 전체 파일 반환faststart 재먹싱(무손실) + preload="metadata" 109곳 + webui/server.py에 RangeStaticFiles 커스텀 클래스 추가(206 + content-range/accept-ranges)WM 실패 물리 finetune 프로젝트(H4 대조 실험 등)의 리포트에는 GT · base · FT-succ · FT-mix 4분할 비교 영상이 다수 임베드되어 있다. 사용자가 특정 구간(사건 전후)만 골라 보려고 재생 바를 드래그했으나 이동이 전혀 되지 않는다고 보고했다 — 리포트가 단순 텍스트/표가 아니라 영상 검토가 핵심인 프로젝트라 이 기능이 막히면 리뷰 자체가 어려워진다.
imageio_ffmpeg.write_frames의 기본 출력은 MP4 컨테이너의 메타데이터 블록(moov atom)을 파일 끝에 쓴다
(예: 파일 547,029 B 중 544,707 B 지점). 브라우저는 moov를 읽어야 시킹 인덱스를 만들 수 있는데, 파일 끝에 있으면 전체 다운로드
전엔 이동이 불가능하다. 여기에 HTML의 preload="none"이 겹쳐 duration조차 읽지 않은 상태였다.
서버(FastAPI StaticFiles)가 Range를 지원한다고 가정하고 이 시점에는 파일 문제로만 판단.
faststart 재먹싱만으로는 해결되지 않았다. curl로 직접 확인한 결과 Range: bytes=1000-2000 요청에도 서버가
200 + 전체 파일을 반환했다(accept-ranges 헤더 자체가 없음). 원인은 ~/repos/cowork webui가 쓰는
starlette 0.38.6 — StaticFiles의 HTTP Range 지원은 0.45부터 추가됐다. 즉 파일을 아무리 고쳐도
서버가 Range 요청을 처리 못 하면 브라우저는 시킹 인덱스를 만들 수 없다.
starlette를 업그레이드하지 않고 커스텀 클래스로 우회한 이유: 0.45로 올리면 FastAPI/다른 미들웨어와의 호환성 확인이
추가로 필요해 범위가 커진다 — /reports 마운트 하나만 좁게 고치는 쪽이 리스크가 작다고 판단(사용자 승인).
| Range 요청 | 기대 응답 | 실측 | 비고 |
|---|---|---|---|
bytes=1000-2000 | 206 + content-range | 206, 1000-2000/547029 | 슬라이스 스트리밍 정상 |
bytes=-500 | 206, 파일 끝 500B | 206, 546529-547028 | suffix range 정상 |
bytes=500000- | 206, 나머지 전체 | 206, 500000-547028 | open-ended range 정상 |
| Range 없음 | 200 + accept-ranges | 200, accept-ranges: bytes | 기존 경로 유지 |
| HTML/인덱스 페이지 | 200 정상 | 200 | 비디오 외 경로 영향 없음 |
이 프로젝트(WM finetune)는 결과 판정이 수치(LPIPS/beats_copy)뿐 아니라 영상 육안 비교에 크게 의존한다 (H4 카드에서만 비교 영상 31개, 지금까지 리포트 전체 166개). 시킹이 막히면 사건 전후 몇 초 구간을 반복 확인하는 리뷰 자체가 비효율적이 되므로, 겉보기엔 "리포트 UX" 문제지만 실질적으로는 실험 검증 워크플로우의 병목이었다.
증상 하나에 원인이 두 개 겹쳐 있을 수 있다는 점도 확인됐다 — 1차 조치(파일 재먹싱)가 "안 됐다"는 것 자체가
두 번째 원인(서버)을 찾아내는 단서가 됐다. curl -H "Range: ..."로 서버 응답을 직접 찍어본 것이 결정적이었다.
starlette는 여전히 0.38.6 — 이번 수정은 /reports 마운트에 한정된 우회이며, webui의 다른 정적 파일 라우트나
향후 신규 마운트에는 같은 문제가 재발할 수 있다(각각 RangeStaticFiles를 적용해야 함).
webui 의존성 전체를 starlette 0.45+로 올리는 것을 별도 작업으로 검토(FastAPI 호환성 확인 필요) — 되면
RangeStaticFiles 커스텀 클래스를 제거하고 표준 StaticFiles로 되돌릴 수 있다.
당장은 신규 리포트 영상이 wm_compare_video.py를 통해 생성되는 한 faststart는 자동 적용되므로 추가 조치 불요.