feat: 쿠키 파일 기반 설정(YOUTUBE_COOKIE_PATH)+리졸버 URL 설정화, 다음곡 프리페치로 재생지연 단축, ytresolver 리포 포함, 쿠키 재발급 스크립트, README 상세화
This commit is contained in:
146
README.md
146
README.md
@@ -1,13 +1,137 @@
|
||||
# music bot v2
|
||||
## 디스코드 음악봇 v2
|
||||
# music_bot_v2
|
||||
|
||||
### 마지막으로 만들었던 내용
|
||||
- 검색하고 재생 누르면 재생됨
|
||||
- 플레이리스트 재생 기능(주소 전달해서 재생하는 방식)
|
||||
- 아래 재생바 연동
|
||||
- 오른쪽 재생목록 연동
|
||||
디스코드 음악봇 v2. 검색·재생·대기열·자동재생·성인인증(연령제한) 영상 재생을 지원한다.
|
||||
`discord.js` + `shoukaku`(Lavalink 클라이언트) 기반이며, 유튜브 재생은 Lavalink `youtube-plugin`을
|
||||
쓰되 **연령제한/SABR로 막히는 영상은 yt-dlp 리졸버로 직접 오디오 URL을 뽑아 Lavalink `http` 소스로 우회 재생**한다.
|
||||
|
||||
### 이제 만들어야되는 내용
|
||||
- 왼쪽 플레이리스트 가져오기 제작
|
||||
- 플레이리스트 재생 추가
|
||||
- claude code 사용해서 개발중
|
||||
---
|
||||
|
||||
## 1. 아키텍처
|
||||
|
||||
```
|
||||
[Discord] ──▶ 봇 컨테이너(music1/2/3) ── shoukaku ──▶ Lavalink (.6:2333)
|
||||
(.5 호스트, docker) │ └ youtube-plugin (일반 영상)
|
||||
│
|
||||
재생 직전 리졸브 요청
|
||||
▼
|
||||
ytresolver (.5:8779, systemd)
|
||||
└ yt-dlp (+쿠키) → 직접 오디오 URL
|
||||
│
|
||||
그 URL을 Lavalink http 소스로 재생
|
||||
```
|
||||
|
||||
- **봇**: `.5` 호스트에서 docker compose 로 `music1/2/3` 3개 인스턴스 구동. 소스는 `bot/`.
|
||||
- **Lavalink**: `.6` 호스트(`192.168.10.6:2333`). 일반 유튜브/스포티파이 미러 재생 담당.
|
||||
- **ytresolver**: `.5` 호스트에서 systemd 로 구동(`:8779`). 연령제한/SABR 우회용 오디오 URL 리졸버.
|
||||
- **Redis**(선택): `.7`. 대시보드(`page/`) 상태 연동.
|
||||
- `.5`와 `.6`은 **같은 공인 IP**를 쓰므로, `.5`에서 뽑은 googlevideo URL을 `.6` Lavalink가 그대로 재생할 수 있다.
|
||||
|
||||
### 왜 리졸버가 필요한가
|
||||
Lavalink `youtube-plugin`은 OAuth 로그인만 지원하는데, 유튜브는 **한국 19금(본인인증 연령제한)** 스트림을
|
||||
OAuth 세션엔 안 열어준다(“This video requires login”). 반면 **웹 쿠키 세션**엔 열어준다. 그래서 쿠키를 쓸 수 있는
|
||||
`yt-dlp`로 직접 오디오 URL을 뽑아 Lavalink `http` 소스로 재생하는 우회 경로를 둔다. 일반 영상은 계정을 태우지
|
||||
않도록 **익명 먼저 시도 → 실패 시에만 쿠키 재시도** 한다.
|
||||
|
||||
---
|
||||
|
||||
## 2. 설치 / 배포 (.5 호스트)
|
||||
|
||||
전제: `.5`에 Docker, `/root/bot/music_bot_v2-compose.yml`(3개 인스턴스 정의), `/root/bot/db`(sqlite + 쿠키) 존재.
|
||||
|
||||
```bash
|
||||
# 1) 소스 최신화
|
||||
cd /root/bot/music_bot_v2 && git pull
|
||||
|
||||
# 2) 봇 3개 빌드 + 재기동
|
||||
cd /root/bot && docker compose -f music_bot_v2-compose.yml up -d --build
|
||||
|
||||
# 3) ytresolver(리졸버) 설치/갱신 (최초 1회 또는 리졸버 코드 변경 시)
|
||||
cp /root/bot/music_bot_v2/resolver/ytresolver.py /opt/ytresolver.py
|
||||
cp /root/bot/music_bot_v2/resolver/ytresolver.service /etc/systemd/system/ytresolver.service
|
||||
systemctl daemon-reload && systemctl enable --now ytresolver
|
||||
systemctl restart ytresolver # 코드 갱신 시
|
||||
```
|
||||
|
||||
빌드는 `bot/Dockerfile`(node:20-alpine, `npm run build`=tsc)로 이루어진다.
|
||||
|
||||
### 인스턴스 정의(`/root/bot/music_bot_v2-compose.yml`)
|
||||
`music1/2/3` 세 서비스가 각자 다른 `TOKEN/APPID/PREFIX/DBPATH`로 뜬다. `/root/bot/db:/db` 볼륨을 공유하므로
|
||||
sqlite DB(`music1.db` 등)와 쿠키(`ytcookie.txt`)가 컨테이너에서 `/db/...`로 보인다.
|
||||
|
||||
---
|
||||
|
||||
## 3. 환경변수 (`bot/.env`)
|
||||
|
||||
전체 목록/설명은 [`bot/.env.example`](bot/.env.example) 참고. 핵심만:
|
||||
|
||||
| 변수 | 설명 |
|
||||
|------|------|
|
||||
| `TOKEN` / `APPID` | 디스코드 봇 토큰 / 앱 ID |
|
||||
| `PREFIX` | 명령어 접두사(예: `m1;`) |
|
||||
| `DBPATH` | sqlite 경로(컨테이너 기준, 예 `/db/music1.db`) |
|
||||
| `LAVALINK_HOST/PORT/PW` | Lavalink(.6:2333) 접속 정보 |
|
||||
| `SPOTIFY_CLIENTID/SECRET` | 스포티파이 검색/미러 |
|
||||
| `YOUTUBE_COOKIE_PATH` | **Netscape 쿠키 파일 경로**(기본 `/db/ytcookie.txt`). 리졸버·검색 공용 쿠키 소스 |
|
||||
| `YOUTUBE_COOKIE` | (선택·하위호환) 쿠키 헤더 문자열 인라인. 설정 시 이 값이 우선 |
|
||||
| `YTRESOLVER_URL` | 리졸버 주소(기본 `http://192.168.10.5:8779`) |
|
||||
| `REDIS/REDIS_HOST/REDIS_PORT` | 대시보드 상태 연동(선택) |
|
||||
|
||||
> `bot/.gitignore`가 `*.env`, `*.db`를 제외하므로 실제 `.env`와 DB는 커밋되지 않는다.
|
||||
|
||||
---
|
||||
|
||||
## 4. 유튜브 쿠키 (`ytcookie.txt`) — 성인인증/연령제한 재생의 핵심
|
||||
|
||||
- **무엇**: 유튜브에 로그인된 계정의 세션 쿠키(Netscape `cookies.txt` 형식). yt-dlp가 연령제한 영상의
|
||||
스트림을 받으려면 이 쿠키가 필요하다. 봇의 유튜브뮤직 검색도 이 쿠키를 헤더 문자열로 변환해 쓴다.
|
||||
- **위치**: `.5` 호스트 `/root/bot/db/ytcookie.txt` (= 컨테이너 `/db/ytcookie.txt`, 리졸버도 같은 파일을 읽음).
|
||||
- **계정**: 전용(버리는) 구글 계정을 쓰고 성인인증(본인확인)을 해둔 것. 본계정 사용 금지(밴 리스크).
|
||||
- **형식(Netscape)** 예:
|
||||
```
|
||||
# Netscape HTTP Cookie File
|
||||
.youtube.com TRUE / TRUE 2000000000 SID g.a000...
|
||||
.youtube.com TRUE / TRUE 2000000000 LOGIN_INFO AFm...
|
||||
```
|
||||
최소한 `SID`, `LOGIN_INFO`, `__Secure-1PSID/3PSID`, `SAPISID` 등 로그인 쿠키가 있어야 한다.
|
||||
|
||||
### 쿠키 만료 시 재발급 (증상: 19금만 안 되고 일반 영상은 정상)
|
||||
방법 1 — 스크립트(Chromium 자동/수동 로그인):
|
||||
```bash
|
||||
cd /root/bot/music_bot_v2
|
||||
npm i -D playwright && npx playwright install chromium # 최초 1회
|
||||
GOOGLE_EMAIL=<계정> GOOGLE_PASSWORD=<비번> \
|
||||
OUT=/root/bot/db/ytcookie.txt node scripts/refresh-cookies.mjs
|
||||
# 구글이 자동 로그인을 막으면 뜬 창에서 직접 로그인 → 자동 저장됨(디스플레이 있는 환경에서 실행)
|
||||
```
|
||||
방법 2 — 브라우저 확장(수동): PC 크롬에 `Get cookies.txt LOCALLY` 설치 → 전용 계정으로 youtube 로그인 →
|
||||
Export → 받은 `cookies.txt`를 `/root/bot/db/ytcookie.txt`로 복사.
|
||||
|
||||
재발급 후: `systemctl restart ytresolver` 하면 즉시 반영(봇 재시작 불필요, 리졸버는 매 요청마다 파일을 읽음).
|
||||
계정/비밀번호는 별도 안전한 곳(비밀번호 관리자/서버 secrets)에 보관한다.
|
||||
|
||||
---
|
||||
|
||||
## 5. 사용법 (디스코드)
|
||||
|
||||
- 지정 채널에 `PREFIX + 검색어/URL` → 검색 후 재생, 대기열 추가.
|
||||
- 임베드의 버튼으로 일시정지/스킵/셔플/볼륨/자동재생 토글.
|
||||
- 지원 소스: 유튜브(검색/URL), 유튜브뮤직, 스포티파이(미러), 플레이리스트.
|
||||
- 자동재생: 마지막 곡 기준 추천(스포티파이 rec → 실패 시 유튜브 RD 믹스 폴백).
|
||||
|
||||
---
|
||||
|
||||
## 6. 성능(재생 시작 지연) 메모
|
||||
|
||||
- 봇은 **다음 곡을 미리 리졸브(prefetch)** 해 곡 전환 시 대기시간을 없앤다(`GuildPlayer` 참조).
|
||||
- 리졸버는 리졸브된 URL을 30분 캐시한다(같은 곡 재생/재시도 시 즉시).
|
||||
- 첫 곡 지연의 대부분은 `yt-dlp` 호출 비용이다. 익명 성공 시 1회, 연령제한이면 익명 실패 후 쿠키 재시도로 2회가 든다.
|
||||
|
||||
---
|
||||
|
||||
## 7. 트러블슈팅
|
||||
|
||||
- **19금만 재생 안 됨**: 쿠키 만료 → 4장 참고해 `ytcookie.txt` 재발급 후 `systemctl restart ytresolver`.
|
||||
- **전부 재생 안 됨**: Lavalink(.6) 또는 ytresolver(.5) 다운 확인. `systemctl status ytresolver`,
|
||||
`curl http://192.168.10.5:8779/health`, Lavalink `:2333`.
|
||||
- **유튜브뮤직 검색 0건**: 현재 알려진 이슈(`YoutubeMusic.getSearchFull`). 재생 자체는 `ytsearch` 폴백으로 동작.
|
||||
- **yt-dlp EJS(시그니처) 오류**: 리졸버는 연령제한 영상에 `--js-runtimes node`가 필요하다(node 설치 필수).
|
||||
|
||||
Reference in New Issue
Block a user