[2일차] yt-dlp로 유튜브 잠실경기 하이라이트 자동 다운로드하기

Luke·2025년 5월 15일
post-thumbnail

🗓️ 2025-05-13


📃 진행 상황 표시

✅ 영상 수집
✅ 영상 다운로드 ⏳ (yt-dlp)
⬜ 프레임 추출 ⏳ (OpenCV)
⬜ 얼굴 등록 ⏳ (face_recognition)
⬜ 얼굴 비교 및 탐지 ⏳
⬜ 결과 리포트 ⏳


✅ 오늘의 목표

  • 문서 정리 간단히
  • 영상 다운로드 테스트
  • 10개를 요청했는데 5개만 나오는 문제 해결

🛠️ 진행한 작업

  • nextPageToken 반복 호출로 5개 제한 해결
  • 쿼터 소모 절약용 test.json 저장 구조 설계
  • 잠실 경기 필터링 → jansil.json 저장

📌 주요 코드 / 결과 캡처

📂 GitHub Repository
👉 프로젝트 코드 보러가기

# test.json 캐싱 처리

if os.path.exists("test.json"):
    print("기존 test.json이 존재합니다.")
    with open("test.json", 'r', encoding='utf-8')as f:
        results = json.load(f)
else:
    print("Youtube API를 호출합니다.")
    results = []
    next_page_token = None

    while True:
        request = youtube.playlistItems().list(
            part="snippet",
            playlistId=PLAYLIST_ID,
            maxResults=MAX_RESULTS,
            pageToken=next_page_token
        )
        response = request.execute()
        results.extend(response["items"])
        next_page_token = response.get("nextPageToken")
        if not next_page_token:
            break

    with open('test.json', 'w', encoding='utf-8') as f:
        json.dump(results, f, ensure_ascii=False, indent=2)

    print("✅ test.json 저장 완료!")

    
# 잠실 경기 필터링
Jansil = [
    {
        "title": item["snippet"]["title"],
        "videoId": item["snippet"]["resourceId"]["videoId"],
        "publishedAt": item["snippet"]["publishedAt"]
    }
    for item in results
    if "vs 두산" in item["snippet"]["title"] or "vs LG" in item["snippet"]["title"]
]

with open("jansil.json", 'w', encoding="utf-8") as f:
    json.dump(Jansil, f, ensure_ascii=False, indent=2)

print(f"잠실 경기 저장 완료 {len(Jansil)}개")

실행 결과 : 잠실 경기 총 42개 (2025-05-13일 오전 기준)

  • " 3월 : 8개 "
  • " 4월 : 24게 " -> ( 계획은 26회, 우천 취소 2회로 실제 24회 )
  • " 5월 : 10개 "

💡 오늘 배운 점 / 핵심 요약

  • maxResults는 한 페이지당 최대 결과 수 (최대 50)
  • 전체 결과를 받으려면 nextPageToken 반복 호출이 필수
  • 일반 검색 API보다 playlistItems().list()가 더 안정적
  • 영상 다운로드는 yt-dlp로 진행하며, JSON 기반 자동화에 유리

❗ 어려웠던 점 & 해결 방법

  • 문제: 10개 요청했는데 실제 5개만 나옴
    해결: nextPageToken으로 페이징 처리하면서 해결
  • 문제: 일반 검색 API는 일부 영상 누락
    해결: playlistItems().list()로 전환

🤔 간단 회고

처음에는 다른 사람들의 저작물로 보호된 유튜브 영상을 굳이 다운로드까지 해야 할지 고민이 많았습니다.
가능하다면 유튜브 사이트 내에서 처리해 보고 싶었지만, CORS 정책이나 브라우저 보안 문제로 영상 스트림 자체에 접근하는 것이 거의 불가능 하다는 걸 알게 되었습니다.
결국 영상을 로컬에 저장하는 방식으로 진행했고, 그 과정에서 저작권 이슈에 대한 고민도 있었기 때문에 ReadMe에 관련 내용을 명확히 명시하며 윤리적으로 프로젝트를 진행하고자 노력했습니다.

또한, 반복적으로 API를 호출하면 유튜브 쿼터가 빠르게 소모되는 문제가 있었습니다.
1일 차에 받아온 응답 데이터를 test.json에 저장하고, 이를 재사용함으로써 API 호출 수를 최소화하려고 했습니다.
이후에는 1주일 또는 한 달 단위로 test.json을 갱신하는 방식으로 쿼터를 더 효율적으로 관리 할 수 있을 것 같다는 생각도 들었습니다.
이러한 캐싱 전략은 실제로 작업 속도도 빨라지고, 유튜브 API 사용량도 줄일 수 있어서 큰 도움이 되었습니다.

끝으로, yt-dlp에 대해 더 찾다 보니 단순한 명령어 실행이 아니라, import yt_dlp , import yt_dlp.options 방식으로 파이썬 내에서 모듈처럼 사용할 수 있다는 점을 알게 되었습니다. 작업이 어느 정도 마무리되면, 리팩토링해 보고 싶은 생각도 들었습니다.

profile
Data 0

0개의 댓글