비록 정책 문제와 맞물려 채택되지 못한 아이디어이지만 굉장히 참신한 아디어라 소개해본다.
라이브 변환기 가 켜져있는지 확인.대상 채널 코드을 youtube api에 주고, 켜져 있는 라이브 방송이 있는지 알아본다. (100 가스 소요.)라이브 방송 클립코드라이브 방송 클립코드가 live인지 체크한다. (1 가스 소요.)라이브 방송 채널 코드를 주고, yt-dlp로 돌린걸 ffmpeg으로 넘겨준다.yt-dlp로 hls 주소를 확인한다.ffmpeg으로 포장 -> response ffmpeg으로 넘겨준 master.m3u8 경로master.m3u8을 서빙gcp 콘솔에서 프로젝트를 하나 만들고 API 및 서비스에 접근한다.
사용자 인증 정보 탭에 들어가서 API 키를 생성한다.


이때, API키 수정을 누른 다음

YouTube Data API v3 만 선택하여 사용하도록 하자.
Search: list 를 사용해야한다. (관련 문서)

요청 req url 예시
https://www.googleapis.com/youtube/v3/search?part=snippet&q=@CHANNEL_HANDLE&eventType=live&type=video&key=YOUR_KEY
“라이트 리스팀” — YouTube Live → (내 서버) HLS 패스스루
유튜브의 라이브 HLS(m3u8)를 받아서, 내 도메인에서 HLS로 재공급하는 방식이다.
이 방식의 문제는 cookie, 정책 등의 문제로 아쉽게도 탈락 되었다.
일일이 수동으로 해야할 경우가 많고 문제를 일으킬 요소도 굉장히 많았기 때문이다.
장점은 Youtube Live Url 을 인코딩 없이 -c copy로 리패키징(패스스루) 하면 CPU 부담 거의 없고 Youtube Live Url은 만료 토큰이 있으므로 주기적으로 새 URL을 갱신하는 작은 스크립트만 추가하면 되기 때문에 굉장히 간단하다.
하지만 담점으로 약관/저작권 이슈를 스스로 관리해야 하고(특히 외부 공개 재배포 시), URL 만료 시 자동 재연결 로직이 필요하다.
pipx install yt-dlp
source ~/.bashrc
which yt-dlp
여기서 yt-dlp 가 잘 나오는 것을 확인.
유튜브에서 방송 중인 채널의 HLS 주소를 직접 얻기 위해 youtube download player 를 사용
yt-dlp --cookies 쿠키경로 -g "https://www.youtube.com/watch?v=스트리밍ID"
# ex)
yt-dlp --cookies /opt/yt-restream/cookies.txt -g "https://www.youtube.com/watch?v=스트리밍ID"
유튜브의 HLS 스트림을 ffmpeg가 받아서, 우리 서버에서 쓸 수 있는 HLS로 변환하는 작업이다.
ffmpeg \
-i "$(yt-dlp -g https://www.youtube.com/watch?v=스트리밍ID)" \
-c copy \
-f hls \
-hls_time 4 \
-hls_list_size 5 \
-hls_flags delete_segments \
/var/www/html/stream/index.m3u8
# ex)
ffmpeg -i "$(yt-dlp --cookies /opt/yt-restream/cookies.txt -g https://www.youtube.com/watch?v=스트리밍ID)" \
-c copy -f hls -hls_time 4 -hls_list_size 5 -hls_flags delete_segments \
/var/www/html/stream/index.m3u8
설명:
-c copy → 재인코딩 없이 원본 그대로 복사 (CPU 부담 ↓)
-hls_time 4 → 세그먼트 길이 4초
-hls_list_size 5 → m3u8에 최신 5개 세그먼트만 유지
-hls_flags delete_segments → 오래된 ts 파일 삭제
/var/www/html/stream/index.m3u8 → Nginx 같은 웹서버에서 접근 가능한 경로
sudo mkdir -p /opt/yt-restream
sudo nano /opt/yt-restream/restream.sh
sudo chmod +x /opt/yt-restream/restream.sh
이때, CORS 필요한 경우 nginx에 add_header Access-Control-Allow-Origin *; 등 옵션 추가
#!/usr/bin/env bash
set -Eeuo pipefail
VIDEO_URL="https://www.youtube.com/watch?v=NJUjU9ALj4A"
COOKIES="/opt/yt-restream/cookies.txt"
OUTPUT_DIR="/var/www/html/stream"
mkdir -p "$OUTPUT_DIR"
while true; do
echo "[$(date)] Fetching new m3u8 URL..."
M3U8_URL=$(/home/ubuntu/.local/bin/yt-dlp --cookies "$COOKIES" -g "$VIDEO_URL")
echo "[$(date)] Starting ffmpeg restream..."
ffmpeg \
-loglevel error \
-i "$M3U8_URL" \
-c copy \
-f hls \
-hls_time 4 \
-hls_list_size 5 \
-hls_flags delete_segments \
"$OUTPUT_DIR/index.m3u8"
echo "[$(date)] ffmpeg stopped. Restarting in 5 seconds..."
sleep 5
done
이때, ffmpeg 옵션으로 -hls_time 2, -hls_list_size 6 이면 보통 6~12초. 더 낮추면 끊김 위험이 높다.
systemd 서비스 파일 작성
[Unit]
Description=YouTube to HLS Restream Service
After=network.target
[Service]
Type=simple
User=ubuntu
ExecStart=/opt/yt-restream/restream.sh
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable 서비스이름
sudo systemctl start 서비스이름
로그 확인
journalctl -u 서비스이름 -f
트랜스코딩 없이 패스스루(-c copy)라 CPU는 가볍지만, 원본 코덱(보통 H.264/MP4 또는 VP9/WEBM)에 따라 일부 레거시 플레이어 호환성에 차이가 날 수 있다. 이때, 문제가 생기면 -c:v h264 -c:a aac 로 트랜스코딩을 고려하면 되는데 대신 CPU/GPU 코스트가 상승한다.
참고로 CDN을 앞단에 두면 대규모 시청자도 안정적으로 처리가 가능하다.
무튼 이 아이디어가 채택이 안 된 이유는 요청 빈도(yt-dlp & ffmpeg) 때문이다.
동작 과정이
1. yt-dlp
yt-dlp -g 명령을 실행하는 순간, 유튜브 페이지를 1~2번 요청해서 실제 m3u8 주소를 뽑습는다.
평상시에 1초마다 계속 호출하는 건 아니고, 명령 실행할 때만 요청한다.
m3u8 URL은 보통 몇 분~몇 시간 유효하지만, 유튜브 라이브는 1시간 이내 만료되는 경우가 많다.
→ 그래서 주기적으로 새로 받아와야 함 (예: 30분~1시간마다)
2. ffmpeg
그리고 사실 여기가 문제인데 ffmpeg는 yt-dlp가 뽑아준 m3u8 URL을 읽어오는데,
이건 내부적으로 유튜브의 세그먼트(ts) 파일을 받아오는 HTTP 요청을 세그먼트 길이(내 경우 12초)마다 보낸다.
그럼 youtube 측에서는 요청을 너무 많이 보내서 429 too many req 에러를 보낸다.