안녕하세요! 김코딩입니다
지난 글에서 이벤트 처리와 유용한 명령어로 봇을 업그레이드해 봤죠? 오늘은 디스코드 서버를 더 신나게 만들어줄 음악 재생 기능을 추가해보겠습니다. 유튜브 링크를 입력하면 음성 채널에서 음악을 틀어주는 봇을 만들어볼게요! 준비물부터 코드까지 차근차근 설명해 드릴 테니 함께 시작해볼까요?
1. 지난 글 복습: 어디까지 했나요?
이전 글에서는:
on_member_join/remove
이벤트로 입장/퇴장 메시지 구현!clear
,!server
같은 명령어 추가- 봇 상태를 “게임 중”으로 설정
이제 이 기능 위에 음악 재생 기능을 추가해 더 멋진 봇을 만들어보겠습니다!
2. 이번 글의 목표
우리가 만들 음악 봇은 다음과 같은 기능을 갖춥니다:
- 음성 채널 입장 →
!join
명령어로 봇을 음성 채널에 초대 - 유튜브 음악 재생 →
!play <유튜브 URL>
로 음악 재생 - 음성 채널 퇴장 →
!leave
명령어로 채널에서 나가기
3. 준비물: 추가 설치 및 설정
3-1. 필요한 패키지 설치
음악 재생을 위해 두 가지가 필요합니다:
youtube_dl
→ 유튜브에서 오디오를 다운로드ffmpeg
→ 오디오를 재생 가능하게 변환
터미널에서 다음 명령어를 실행하세요:
pip install youtube_dl
그리고 ffmpeg는 별도로 설치해야 합니다:
- Windows: FFmpeg 공식 사이트에서 다운로드 후 환경 변수에 추가
- Mac:
brew install ffmpeg
(Homebrew 필요) - Linux:
sudo apt install ffmpeg
(Ubuntu 기준)
3-2. 봇 권한 확인
개발자 포털에서 봇 초대 URL 생성 시:
- Scopes:
bot
체크 - Permissions:
Connect
,Speak
추가
4. 완성된 코드와 설명
import discord
from discord.ext import commands
import yt_dlp as youtube_dl
import asyncio
import os
from dotenv import load_dotenv
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')
if TOKEN is None:
TOKEN = "" # 여기에 봇 토큰 입력
bot = commands.Bot(command_prefix="!", intents=discord.Intents.all())
youtube_dl.utils.bug_reports_message = lambda: ''
ytdl_format_options = {
'format': 'bestaudio/best',
'outtmpl': '%(extractor)s-%(id)s-%(title)s.%(ext)s',
'noplaylist': True,
'nocheckcertificate': True,
'ignoreerrors': False,
'logtostderr': False,
'quiet': True,
'no_warnings': True,
'default_search': 'auto',
'source_address': '0.0.0.0',
}
ffmpeg_options = {
'options': '-vn'
}
ytdl = youtube_dl.YoutubeDL(ytdl_format_options)
class YTDLSource(discord.PCMVolumeTransformer):
def __init__(self, source, *, data, volume=0.5):
super().__init__(source, volume)
self.data = data
self.title = data.get('title')
self.url = data.get('url')
@classmethod
async def from_url(cls, url, *, loop=None):
loop = loop or asyncio.get_event_loop()
try:
data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=False))
if 'entries' in data:
data = data['entries'][0]
filename = data['url']
return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)
except Exception as e:
print(f"YouTube 정보 추출 오류: {e}")
raise Exception(f"YouTube 영상을 불러올 수 없습니다. 올바른 URL인지 확인해주세요.")
@bot.event
async def on_ready():
print(f"{bot.user}가 온라인이에요!")
await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name="음악"))
@bot.command()
async def join(ctx):
if not ctx.message.author.voice:
await ctx.send("먼저 음성 채널에 들어가 주세요!")
return
channel = ctx.message.author.voice.channel
await channel.connect()
await ctx.send(f"{channel.name}에 입장했어요!")
@bot.command()
async def leave(ctx):
if ctx.voice_client:
await ctx.voice_client.disconnect()
await ctx.send("음성 채널에서 나왔어요!")
else:
await ctx.send("저는 음성 채널에 없어요!")
@bot.command()
async def play(ctx, *, url=None):
if url is None:
await ctx.send("YouTube URL을 입력해주세요! 예: `!play https://www.youtube.com/watch?v=dQw4w9WgXcQ`")
return
if not ctx.message.author.voice:
await ctx.send("먼저 음성 채널에 들어가 주세요!")
return
if not ctx.voice_client:
channel = ctx.message.author.voice.channel
await channel.connect()
async with ctx.typing():
try:
player = await YTDLSource.from_url(url, loop=bot.loop)
ctx.voice_client.play(player, after=lambda e: print(f'재생 오류: {e}') if e else None)
await ctx.send(f"지금 재생 중: {player.title}")
except Exception as e:
await ctx.send(f"오류 발생: {str(e)}")
bot.run(TOKEN)

5. 실행하기
ffmpeg
가 설치되었는지 확인 (ffmpeg -version
실행)- 위 코드를
music_bot.py
로 저장 bot.run("토큰")
에 여러분의 봇 토큰을 입력- 실행:
python music_bot.py
6. 문제 해결 팁
- “FFmpeg not found” 오류 → ffmpeg 설치 후 시스템 PATH에 추가
- 음성이 안 들려요 → 봇과 사용자가 같은 음성 채널에 있는지, 볼륨이 켜져 있는지 확인
- “Forbidden” 오류 → 봇에
Connect
,Speak
권한이 있는지 확인
7. 더 해볼 수 있는 기능
- 🎵 큐 시스템 → 여러 곡을 대기열에 추가하고 순서대로 재생
- ⏸️ 일시정지/재개 →
!pause
,!resume
명령어 추가 - 🔍 검색 기능 → URL 대신 키워드로 검색 (예:
!play despacito
)
8. 마무리
이제 디스코드에서 친구들과 함께 음악을 들으며 즐겨보세요! 🎶 다음 글에서는 음악 큐 시스템이나 데이터 저장 (예: 사용자별 플레이리스트)을 다룰 예정이니 기대해주세요! 😃
[…] 지난 글에서는 유튜브 음악을 재생하는 디스코드 봇을 만들어봤죠. 하지만 한 곡씩만 재생할 수 있어서 아쉬웠을 텐데요. 오늘은 그 한계를 뛰어넘어 음악 큐 시스템과 사용자별 선호 곡 저장 기능을 추가해 더욱 강력한 음악 봇을 만들어보겠습니다! […]