⚠ 야매로 만든 것이니 따라하지 않는 것을 추천합니다
lektion-von-erfolglosigkeit.tistory.com/96 <-새로운 방법
이제 봇이 음성채널에 입장하거나 퇴장할 수 있으니 본격적으로 음악을 재생시켜보자
FFmpeg
FFmpeg은 디지털 음성 스트림과 영상 스트림에 대해서 다양한 종류의 형태로 기록하고 변환하는 컴퓨터 프로그램이다 (Wikipedia)
간단히 말해서 그냥 파일 인코더 겸 플레이어다
mp4 파일을 mp3로 바꾼다거나...
들어가자마자 있는 Download 버튼을 누르고 Window builds from gyan.dev를 클릭
아래로 스크롤하여 release를 찾고 full-shared 버전을 받아주자 쥰내 오래걸렸다. youtube_dl 먼저 설치하고 다시 오자
다운로드가 끝났다면 압축해제한 뒤 환경변수를 등록해야 한다
제어판 - 시스템 - 고급 시스템 설정 - 고급 - 환경 변수 - path - 새로 만들기 - 설치한 경로\bin로 등록
여기저기 찾기도 귀찮으니 그냥 디스코드 봇 파일이 있는 곳에 압축해제 했다. 이러면 사실 환경변수 등록 안해도...
마지막으로 cmd나 powershell 등에서 아래 명령어를 입력해 잘 설치되었는지 확인한다.
ffmpeg -version
youtube_dl
youtube-dl 은 YouTube 및 1000 개가 넘는 다른 비디오 호스팅 웹 사이트의 비디오 및 오디오 콘텐츠를위한 오픈 소스다운로드 관리자 입니다 (Wikipedia)
dl을 보고 감이 왔다면 대단하다. download의 약자다.
이름에서 알수 있듯이 유튜브 영상을 다운로드해주는 라이브러리다.
python3 -m pip install -U youtube_dl
저번과 마찬가지로 혹시나 wsl같이 리눅스를 사용하고 있다면 "youtube-dl"로 수정하여 사용한다.
코드 추가
역시나 메인 파일과 코드를 분리했다. 또한 run.py를 main.py로 이름을 바꿨다.
#ydl.py
import youtube_dl #youtube_dl
def ydl(url):
ydl_opts = { #다운로드 옵션
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
'outtmpl': 'song.mp3', #파일 이름
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([url]) #다운로드
ydl_opts는 다운로드 옵션을 설정하는 것으로 노래만 재생하기 때문에 mp3파일로 받아준다.
outtmpl는 파일 이름을 설정하는데 일단은 하기 쉽도록 song.mp3로 설정했다.
나중에 제목 그대로 받아서 재생목록을 만들 예정
#main.py 추가
...
from ydl import * #ydl.py import
...
@bot.command()
async def play(ctx, url):
ydl(url) #음원 다운로드
channel = ctx.message.voice.channel
voice = await channel.connect() #음성채널 접속
voice.play(discord.FFmpegPCMAudio(executable = './ffmpeg/bin/ffmpeg.exe', source='./song.mp3')) #다운받은 음원 재생
while voice.is_playing(): #노래 재생동안 딜레이
sleep(.1)
await voice.disconnect() #재생이 끝나면 나가기
수많은 시행착오를 겪으며 만들다 보니 저번에 만들었던 join명령어와 leave 명령어가 쓸모 없어졌다.
어차피 노래재생할 때 아니면 봇이 음성채널에 들어올 일도 없으니 기존에 있던 join과 leave는 삭제했다.
voice.play(discord.FFmpegPCMAudio(executable = './ffmpeg/bin/ffmpeg.exe', source='./song.mp3'))
이부분을 보면 executable(실행)과 source(파일)을 지정했는데 ./는 현재 위치를 뜻한다.
현재 디텍토리는 왼쪽 사진과 같이 되어 있다.
좀 아쉬운게 mp3파일이 실행파일(main.py)와 같은 폴더에 저장되는 건데 이건 좀 더 찾아봐야 할 것 같다.
어쨋든 실행하면 이제 봇이 노래를 틀어줄 것이다.
노래를 다운로드 후 인코딩하고 틀어야 해서 시간이 조금 걸리지만 성공
다른 곡 재생
그런데 다른 url을 넣어도 처음에 입력한 url의 노래만 재생된다.
이름을 죄다 song.mp3로 설정해놔서 생기는 문제인데 일단은 해결해보자
간단하게 다운로드 하기전에 song.mp3파일이 있다면 삭제하면 될 것 같다.
import youtube_dl
import os #os모듈
file = './song.mp3' #파일 경로 설정
def ydl(url):
if os.path.isfile(file): #song.mp3파일이 존재하면
os.remove(file) #파일 삭제
ydl_opts = {
'format': 'bestaudio/best',
'postprocessors': [{
'key': 'FFmpegExtractAudio',
'preferredcodec': 'mp3',
'preferredquality': '192',
}],
'outtmpl': 'song.mp3',
}
with youtube_dl.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
이제 다른 노래를 재생할 수 있다.
노래가 재생중일때 다른 곡 play 명령을 내리면 아무 일도 일어나지 않고 이미 파일이 존재해서 스킵했다는 말만 나온다.
노래 일시정지, 다시재생, 멈춤
이제 일시정지, 재생, 멈춤(스킵)을 만들어 보자
#main.py 추가
...
#일시정지
@bot.command()
async def pause(ctx):
voice = discord.utils.get(bot.voice_clients, guild = ctx.guild) #봇의 음성 관련 정보
if voice.is_playing(): #노래가 재생중이면
voice.pause() #일시정지
else:
await ctx.send("재생중인 곡 없음") #오류(?)
#다시 재생
@bot.command()
async def resume(ctx):
voice = discord.utils.get(bot.voice_clients, guild = ctx.guild) #봇의 음성 관련 정보
if voice.is_paused(): #일시정지 상태이면
voice.resume()
else:
await ctx.send("일시정지 아님") #오류(?)
#정지
@bot.command()
async def stop(ctx):
await bot.voice_clients[0].disconnect() #음성채널 나가기
...
discord.py는 봇의 음성에 대해서 일시정지와 다시재생을 제공하고 있다.
그리고 stop 명령어는 그냥 봇을 음성채널에서 퇴장시켰더니 문제 없이 잘 되었다...
다음에는 뭘 만들까 다음에는 유저 데이터를 작성해서 나 혼자 게임을 해볼예정이다
'프로젝트 > 디스코드 봇' 카테고리의 다른 글
디스코드 봇 만들기#7 - 회원가입 (12) | 2021.02.19 |
---|---|
디스코드 봇 만들기#6 - 게임봇 계획 (0) | 2021.02.12 |
디스코드 봇 만들기#4 - 음성채널 (7) | 2021.01.29 |
디스코드 봇 만들기#3 - 간단한 주사위 게임 (2) | 2021.01.22 |
디스코드 봇 만들기#2 - 간단한 명령어 (10) | 2021.01.15 |