썸네일·제목을 누르면 YouTube 새 탭으로 나가던 걸 레이어 팝업 재생으로 바꿨다.
쇼츠는 세로(9:16), 롱폼은 가로(16:9)로 비율을 맞추고, 팝업 안에 숏폼 큐 등록과
YouTube 열기를 함께 뒀다. Escape·배경 클릭으로 닫히고 닫을 때 재생이 멈춘다.
임베드를 막아둔 채널이 많다는 걸 실측했다 — 소재 원본 9건 중 4건이 차단이고
채널 단위로 갈린다(짠한형 전부 차단, 뜬뜬·스프 전부 가능). 그대로 두면 절반이
"동영상을 재생할 수 없음" 화면을 보게 되므로:
- 수집할 때 videos.list 에 status 파트를 붙여 embeddable 을 저장한다(쿼터 동일).
- 차단된 영상은 팝업 대신 바로 YouTube 새 탭으로 연다.
- 차단 영상 썸네일에 외부링크 아이콘을 띄워 눌렀을 때 나가는 걸 예고한다.
- embeddable 이 null(미수집)이면 일단 재생을 시도한다 — 팝업 안에 YouTube 링크가
있어 막혀도 빠져나갈 수 있다.
브라우저에서 확인: 재생 가능 영상은 팝업에서 실제 재생됐고(썸네일·제목 클릭 모두),
차단 채널 카드에만 외부링크 아이콘이 붙었다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
내 영상에 달린 댓글 중 내가 답 안 한 것만 모아, 영상 내용까지 근거로
답글 초안을 만든다. 조회는 나오는데 구독이 안 붙는 문제(59영상 36만 조회
구독 38)에 직접 닿는 지점이라 여기부터 손댔다.
- 미응답 판정은 totalReplyCount 가 아니라 답글 작성자에 내 채널이 있는지로 본다.
남이 대댓글만 단 댓글은 여전히 내가 답해야 하기 때문이다.
- 수집 중 내가 단 답글을 발견하면 말투 샘플로 모아둔다. 실측 17개가 학습됐고
초안이 그 톤을 따른다. 8자 미만("ㅋㅋㅋ")은 말투 정보가 없어 제외.
- 영상 맥락은 Gemini 에 유튜브 URL 을 직접 준다. 내 영상은 30초 쇼츠라 토큰이
적고 화면에 박힌 자막까지 읽힌다. 영상당 1회만 만들어 캐시한다.
- 실제 게시는 OAuth 가 없어 불가 — 초안 복사까지가 끝이다.
실측에서 잡은 결함 두 개를 고쳤다.
1) 요약 생성 때 제목을 안 넘겨서 Gemini 가 출연자 이름을 추측했다. "이채영"
영상을 "이채연"으로 요약했고 그 오류가 답글까지 전파됐다. 제목을 함께 주고
"제목 표기를 글자 그대로" 규칙을 넣어 해결. 캐시가 오염된 경우를 위해
refreshContext 옵션을 두고, '다시 생성'은 요약도 다시 읽게 했다.
2) 영상 요약이 없는데도 규칙에 "[영상 내용]을 근거로"가 남아 없는 섹션을
가리켰다. 요약 유무에 따라 규칙을 갈랐다(테스트가 잡음).
쿼터: 영상당 1 unit — 59개 수집에 59 units.
테스트 11건 추가(미응답 판정·말투 샘플·프롬프트 조립·응답 파싱) — 총 106건 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
인물은 프로그램을 옮겨 다녀서 채널 시드로는 못 잡는다. 실측으로 확인했다:
이미 모은 롱폼 200건에서 제목에 인물명이 잡히는 건 4%뿐이다. 예능 클립 제목은
인물명 대신 상황을 쓰기 때문("혹시 젤리 가격 아세요"). 그래서 인물명으로
유튜브를 검색해 등장분을 찾는다.
- TrackedPerson 엔티티. 1명당 검색 101 units 라 하루 1회만 돌고 활성 인물
상한(기본 10명)을 둔다. 10명이면 1,010 units/일.
- 인물 탭은 source 가 아니라 matchedPerson 으로 조회한다. 소스 채널에서 이미
수집한 영상이 인물 검색에도 걸리면 소스 탭에서 사라지면 안 되기 때문이다.
- 새로 발견한 영상은 source=PERSON — 수집함/발굴 화이트리스트 밖이라 자동 격리.
- 시간당 조회수 하한(기본 20)으로 노이즈를 거른다. 인물명 검색에는 팬채널·
커버곡·개인 브이로그가 대량으로 딸려 오는데(실측 30회 미만), 생 조회수로
자르면 방금 올라온 영상까지 걸리므로 속도로 잰다. 적용 후 노이즈 6건이
전부 빠지고 29건 모두 실질 소재만 남았다.
실측: 윤경호 → KBS 청룡시리즈어워즈 남우조연상(31.6만), KBS 한국방송(18.2만),
SBS 스브스 Drama. 전부 채널 시드에 없는 곳이라 인물 추적으로만 잡힌다.
테스트 3건 추가(속도 필터 경계·신선한 업로드 통과·값 없을 때 미배제) — 총 92건 통과.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
쇼츠 클립 채널의 소재를 최신순으로 발굴하는 /feed 화면과 수집 파이프라인.
- 소재 원본 탭: 웹예능 공식채널의 신규 롱폼(durationSec > 65)만 수집.
아직 아무도 안 자른 구간을 선점하는 용도라 공식계정 쇼츠는 제외한다.
- 경쟁 쇼츠 탭: 예능짤 채널의 신규 쇼츠. 제목·썸네일 벤치마킹용이라
재가공 대신 원본 열기 액션을 준다.
- Channel.role(MY/SOURCE/RIVAL) 컬럼 하나로 역할을 구분하고, 기존
uploads 플레이리스트 동기화를 그대로 재사용한다. 채널당 2 units라
search.list(100 units) 대비 쿼터가 거의 들지 않는다.
- 3시간 주기 수집(FeedCollectionService). 소재 선점은 업로드 직후가
승부라 기존 일 1회 채널 수집으로는 늦다.
- 수집함/발굴/떡상 후보 쿼리는 source 미지정 시 CHANNEL·SEARCH만 보도록
좁혀, 피드 영상이 기존 화면을 덮지 않게 격리했다.
- 시드는 자동 후보 → 수동 승인. 내 채널 해시태그를 역분석해(HashtagExtractor)
공식채널 후보를 추천 목록에 쌓고, 승인 시 SOURCE/RIVAL로 등록한다.
- 연속 3회 수집 실패한 시드는 자동 스킵해 쿼터 낭비를 막는다.
- role이 null인 기존 채널은 부팅 시 MY로 1회 백필(ddl-auto:update 특성).
UX: 기존 Editorial 디자인 시스템 유지. 골든타임(24h)·공식클립/풀에피·
떡상중·작업함 배지, 프로그램/길이/기간 필터, URL 상태 보존, 스켈레톤·
빈 상태·에러 복구 액션, 탭 키보드 이동, 이모지 대신 Lucide 아이콘.
테스트: HashtagExtractor·FeedBadges·ChannelRole 순수 로직 16건 추가(총 76건 통과).
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
느려짐의 유력 원인 두 가지를 정리한다.
1) p6spy가 모든 SQL을 파라미터값 포함해 매번 로깅하던 것을 기본 OFF로.
디버깅 시 P6SPY_LOGGING=true 로 켠다.
2) channel_videos에 인덱스가 하나도 없어 데이터가 늘면 풀스캔이었다.
리포지토리의 실제 필터/정렬 컬럼에 인덱스 추가(ddl-auto가 자동 생성):
video_id, channel_id, interest_status, source, category_id,
published_at, views_per_sub_ratio
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>