커서 ai의 회신 ( 실행파일 눌렀을때) :: 현재 구글에서 제공하는 자동 자막이 존재하거든. 이거 확인하고생각해줘 아니요! 방금 **대본이 추출되지 않았습니다**! 😅 #




오케이—지금 상황은 연동은 됐는데, 확장에서 자막이 0줄로 넘어가서 서버가 202(ASR 큐) 또는 400(0자)를 주는 상태예요.

해결 포인트는 “확장에서 정말 자막을 뽑아왔는지” 확인 → 안 뽑혔다면 폴백으로 강제 추출payload.text까지 채워 전송입니다.

먼저, 어떤 쪽 소스인지 헷갈리지 않게 말할게요:

  • 아래 점검/패치는 전부 ‘크롬 확장프로그램’ 쪽입니다. (서버는 MIN_TEXT_LEN만 잠시 1로 낮추면 테스트가 편함)


1) 딱 1분 진단 (확장 쪽에서 지금 뭐가 오고 있는지)

유튜브 watch 페이지에서 F12 → 콘솔에 아래 순서대로 입력:

  1. 브릿지/추출 정상 여부

js
typeof __YCX__ // "object" 여야 정상 await __YCX__.getPlayerResponse().then(()=>console.log('PR OK'))
  1. 실제 자막 몇 줄?

js
const x = await __YCX__.extractAll(); console.log('lang=', x.language, 'chunks=', x.captions.length, x.captions.slice(0,3))
  • chunks > 0면 OK (확장→서버 전송은 될 것)

  • 0이면 추출이 안 된 것 → 2단계로


2) 자막 트랙 강제 폴백 (확장에 최신 패치 반영 여부)

제가 전에 드린 재시도 + timedtext(list) 폴백이 확장에 제대로 올라갔는지 확인해 주세요.

만약 아직 반영이 안 돼 있다면, 아래 강제 폴백을 임시로 content_script에서 호출해도 됩니다.

A) videoId 확인

js
const url = location.href.split("&list=")[0]; const videoId = new URL(url).searchParams.get('v'); console.log(videoId);

B) timedtext 목록 직접 조회 (브라우저 콘솔에서 바로 확인)

js
fetch(`https://www.youtube.com/api/timedtext?type=list&v=${videoId}`) .then(r=>r.text()).then(t=>console.log(t))
  • <track lang_code="ko" kind="asr" ...> 같은 항목이 보이면 자동자막 존재

C) 그 트랙으로 바로 다운로드 (json3)

js
const u = new URL("https://www.youtube.com/api/timedtext"); u.searchParams.set("v", videoId); u.searchParams.set("fmt", "json3"); u.searchParams.set("lang", "ko"); u.searchParams.set("kind", "asr"); // 자동자막이면 asr const j = await fetch(u.toString()).then(r=>r.json()); console.log('events=', j.events?.length);
  • events 길이가 크면 자막이 정상 존재 → 확장에서 지금 폴백 호출이 안 됐던 것

⇒ 해결: 확장에 제가 준 captions_extractor.js 최신본(재시도 + timedtext 폴백 + json3 파서)로 덮어쓰고 확장 재로드하세요.


3) 전송 직전 방어 코드(확장에서 꼭!):

자막이 비어도 서버가 바로 판단할 수 있게 합친 텍스트를 같이 보내세요.

js
// content_script.js (payload 만든 후) payload.text = (payload.captions || []).map(c => c.text || "") .join(" ").replace(/\s+/g," ").trim(); payload.text_length = payload.text.length;

그리고 커버리지 토스트로 “전체를 받아왔는지” 즉석 확인:

js
function getCoverage(caps, duration) { if (!caps?.length) return { coverage: 0 }; const last = caps[caps.length-1]; const end = (Number(last.start)||0) + (Number(last.duration)||0); return { coverage: duration ? Math.min(100, Math.round((end/duration)*100)) : 0 }; } const { coverage } = getCoverage(payload.captions, payload.duration_seconds); showToast(`자막 커버리지: ${coverage}%`, coverage >= 95);

4) 서버는 테스트 동안 이렇게(선택)

  • 환경변수 MIN_TEXT_LEN=1로 낮춰두면 0자만 아니면 통과됩니다.

  • 202 Accepted (asr_queued)가 계속 보이면, 확장에서 payload.captions가 비거나 payload.text가 빈 상태예요.


5) 흔한 원인 요약

  • **확장 최신본(1.0.3)**이 재로드 안 됨 → 예전 코드라 PR 지연/폴백 미적용

  • watch 페이지가 아닌 shorts/임베드에서 테스트

  • 언어 코드가 ko-KR/ko 혼용 → chooseCaptionTrack 우선순위에 둘 다 포함 필요(이미 반영)

  • 애드블록/필터 때문에 timedtext 요청이 막힘 → 잠시 끄고 테스트


결론

  • 이 소스들은 전부 “확장프로그램” 쪽 수정입니다.

  • 확장 쪽에서 extractAll()chunks>0로 나와야 “24분 전체 대본”이 한 번에 서버로 넘어갑니다.

  • 지금은 chunks=0이라 서버가 202/400을 주는 상태 → 위 패치/확인대로 진행하면 해결됩니다.

적용 후 CAP 클릭 → 커버리지% 토스트가 뜨는지, 그리고 Service Worker 콘솔에 [RESP] 200 ...가 찍히는지 알려주세요. 필요하면 제가 원격으로 문제 구간만 더 좁혀드릴게요!

댓글 남기기