TokyoAJ

도쿄아재

PYTHON 2025.04.08

Python으로 나만의 디스코드 음악 봇 만들기 – 로컬 오디오 재생 편

디스코드는 게이머뿐만 아니라 소셜 커뮤니티에서도 활발하게 사용되는 플랫폼입니다. 그중에서도 음성 채널에서 음악을 함께 들을 수 있는 봇은 매우 유용한 기능이죠.


이번 글에서는 Python과 discord.py 라이브러리를 사용해, 간단한 음악 재생 디스코드 봇을 만들어보겠습니다.

로컬에 저장된 .mp3 파일을 음성 채널에서 재생할 수 있으며, 명령어도 간단하게 구성되어 있어 초보자도 쉽게 구현 가능합니다.


사용 기술 및 설치 준비

사용 기술

항목설명
discord.py디스코드 API를 파이썬에서 사용할 수 있게 해주는 라이브러리
FFmpeg오디오/비디오 처리 도구. 디스코드 봇에서 오디오를 디코딩해주는 역할
Python 3.8+파이썬 개발 환경


설치 방법

파이썬 설치 후, 필요한 패키지 설치:

pip install -U discord.py


FFmpeg 설치

  1. FFmpeg 다운로드 페이지에서 OS에 맞는 버전 다운로드
  2. 설치 후 시스템 환경 변수(Path)에 FFmpeg가 등록되어 있어야 함 (터미널에서 ffmpeg 입력 시 작동 확인 가능)



파일 구조 예시

my-music-bot/
├── bot.py # 메인 파이썬 코드
├── audio.mp3 # 재생할 오디오 파일
└── requirements.txt # (선택) 패키지 목록



코드 설명 – 어떻게 동작하나요?

1. 라이브러리 및 기본 설정

import discord
from discord.ext import commands
import os

discord와 commands는 디스코드 API를 제어하기 위한 핵심 모듈입니다.

os는 파일 존재 여부를 확인하기 위해 사용됩니다.


TOKEN = '발급받은 토큰'
AUDIO_FILE = 'audio.mp3'

디스코드 개발자 포털에서 발급받은 봇 토큰을 입력합니다.

로컬에서 재생할 오디오 파일 이름 지정.


intents = discord.Intents.default()
intents.message_content = True
bot = commands.Bot(command_prefix='!', intents=intents)

intents는 디스코드 API가 어떤 정보에 접근할 수 있는지 설정합니다.

message_content = True 설정은 사용자의 메시지 내용을 받아 명령어를 처리하기 위해 필요합니다.


2. 봇 로그인 이벤트

@bot.event
async def on_ready():
print(f'로그인 성공: {bot.user.name}')

봇이 서버에 성공적으로 연결되었을 때 실행되는 이벤트입니다.

콘솔에 로그인 성공 메시지가 출력됩니다.


3. !play 명령어 – 오디오 재생

@bot.command(name='play')
async def play(ctx):

디스코드 채팅에서 !play 명령어를 입력하면 실행됩니다.

ctx는 명령어가 호출된 컨텍스트(서버, 채널, 유저 등)를 담고 있습니다.


if ctx.author.voice is None:
await ctx.send("음성 채널에 먼저 들어가주세요.")
return

명령어를 입력한 유저가 음성 채널에 접속하지 않았을 경우를 검사합니다.


voice_channel = ctx.author.voice.channel
voice_client = discord.utils.get(bot.voice_clients, guild=ctx.guild)

현재 유저가 접속 중인 음성 채널 객체를 가져옵니다.

이미 봇이 채널에 연결되어 있는지 확인합니다.


if voice_client is None:
voice_client = await voice_channel.connect()
elif voice_client.is_playing():
voice_client.stop()

봇이 음성 채널에 없으면 연결하고, 이미 음악을 재생 중이면 중지합니다.


if not os.path.exists(AUDIO_FILE):
await ctx.send(f"'{AUDIO_FILE}' 파일을 찾을 수 없습니다.")
return

지정된 오디오 파일이 로컬 디렉토리에 있는지 확인합니다


ffmpeg_options = {
'options': '-bufsize 512k -ab 128k -loglevel warning'
}
source = discord.FFmpegOpusAudio(AUDIO_FILE, **ffmpeg_options)
voice_client.play(source)
await ctx.send(f'{AUDIO_FILE} 재생 시작')

FFmpeg를 통해 .mp3 파일을 디코딩하여 Opus 형식으로 변환 후 재생합니다.

ffmpeg_options는 재생 품질을 조절하는 옵션입니다.


4. !stop 명령어 – 재생 중지

@bot.command(name='stop')
async def stop(ctx):

!stop 명령어 입력 시, 현재 봇이 재생 중이라면 중단하고 채널에서 나갑니다.


voice_client = discord.utils.get(bot.voice_clients, guild=ctx.guild)
if voice_client and voice_client.is_playing():
voice_client.stop()
await voice_client.disconnect()
await ctx.send('음악 재생이 중지되었습니다.')



실행 방법 요약

  1. audio.mp3 파일을 준비하고 같은 폴더에 저장
  2. bot.py 파일에 봇 토큰을 입력
  3. 콘솔에서 다음 명령어로 실행
  4. 디스코드에서 봇을 초대한 뒤, 음성 채널에 접속한 후 !play 명령어 입력
python bot.py



자주 발생하는 오류 해결

문제원인
ffmpeg 관련 오류FFmpeg가 설치되지 않았거나 경로 설정이 안 됨
봇이 음성 채널에 연결되지 않음유저가 음성 채널에 들어가 있지 않음
파일을 찾을 수 없다는 메시지audio.mp3 파일 경로가 잘못됨



보안 팁

  1. TOKEN은 외부에 절대 노출되지 않게 주의하세요!
  2. .env 파일을 사용하여 토큰을 안전하게 관리하는 것을 추천합니다:
from dotenv import load_dotenv
load_dotenv()
TOKEN = os.getenv('DISCORD_TOKEN')


마무리

지금까지 Python과 discord.py를 활용해 로컬 오디오 파일을 재생하는 간단한 디스코드 음악 봇을 만들어보았습니다.

기초적인 기능을 직접 구현해보면, 나중에 더 복잡한 봇도 쉽게 만들 수 있는 기반이 됩니다.



전체소스

# Discord 봇을 위한 필수 라이브러리 임포트
import discord
from discord.ext import commands
import os

# 봇 토큰 및 오디오 파일 설정
TOKEN = '발행한토큰'
AUDIO_FILE = 'audio.mp3' # 로컬 오디오 파일

# 봇의 기본 설정
intents = discord.Intents.default()
intents.message_content = True # 메시지 내용 접근 권한 활성화
bot = commands.Bot(command_prefix='!', intents=intents) # 명령어 접두사 '!' 설정

# 봇이 성공적으로 로그인했을 때 실행되는 이벤트 핸들러
@bot.event
async def on_ready():
print(f'로그인 성공: {bot.user.name}')

# 음악 재생 명령어 - !play
@bot.command(name='play')
async def play(ctx):
# 사용자가 음성 채널에 없으면 메시지 출력 후 종료
if ctx.author.voice is None:
await ctx.send("음성 채널에 먼저 들어가주세요.")
return

# 사용자가 참여한 음성 채널 가져오기
voice_channel = ctx.author.voice.channel
# 현재 봇이 연결된 음성 클라이언트 확인
voice_client = discord.utils.get(bot.voice_clients, guild=ctx.guild)

# 음성 채널에 연결 또는 이미 재생 중이면 중지 후 재연결
if voice_client is None:
voice_client = await voice_channel.connect()
elif voice_client.is_playing():
voice_client.stop()

# 로컬 오디오 파일 재생 시도
try:
# 파일이 존재하는지 확인
if not os.path.exists(AUDIO_FILE):
await ctx.send(f"'{AUDIO_FILE}' 파일을 찾을 수 없습니다.")
return
# FFmpeg 옵션 설정 - 버퍼 크기와 비트레이트 지정
ffmpeg_options = {
'options': '-bufsize 512k -ab 128k -loglevel warning'
}
# Opus 형식으로 오디오 소스 생성
source = discord.FFmpegOpusAudio(
AUDIO_FILE,
**ffmpeg_options
)
# 오디오 재생 시작
voice_client.play(source)
await ctx.send(f'{AUDIO_FILE} 재생 시작')
except Exception as e:
# 오류 발생 시 메시지 출력
await ctx.send(f'오디오 재생 실패: {e}')

# 음악 중지 명령어 - !stop
@bot.command(name='stop')
async def stop(ctx):
# 현재 봇이 연결된 음성 클라이언트 확인
voice_client = discord.utils.get(bot.voice_clients, guild=ctx.guild)
# 재생 중이면 중지하고 연결 해제
if voice_client and voice_client.is_playing():
voice_client.stop()
await voice_client.disconnect()
await ctx.send('음악 재생이 중지되었습니다.')
else:
# 재생 중이 아니면 메시지 출력
await ctx.send('재생중인 음악이 없습니다.')

# 봇 실행
bot.run(TOKEN)


디스코드 봇 권한설정

OAuth2 URL Generator


Bot Permissions

맨아래있는 Generated URL 봇 추가 URL


Generated URL로 브라우저에서 접속


디스코드 오른쪽에 온라인으로 봇이 추가된것을 확인

댓글