728x90
반응형

드디어 방치해두었던 음악 봇을 다시 만들어보자

사실 디코에서 굳이 음악을 듣지 않아서 좀 밀렸다

 

저번에는 유튜브에서 youtube_dl을 이용해 파일을 다운로드 받고 ffmpeg로 mp3로 바꾼 뒤 그걸 봇이 찾아서 재생했다

lektion-von-erfolglosigkeit.tistory.com/71

 

디스코드 봇 만들기#5 - 음악재생

⚠ 야매로 만든 것이니 따라하지 않는 것을 추천합니다 이제 봇이 음성채널에 입장하거나 퇴장할 수 있으니 본격적으로 음악을 재생시켜보자 FFmpeg www.ffmpeg.org/ FFmpeg Converting video and audio has neve..

lektion-von-erfolglosigkeit.tistory.com

괜히 어설프게 혼자 만들어서 저 사단이 났으니 이번엔 그냥 유튜브 영상보고 따라 만들예정이다

음악 기능은 디코 봇의 거의 기본기능이라 예제도 많다.

 


왜인지 유튜브 영상을 보고 따라하려다가 이해가 안되서 API reference만 주구장창 읽고 있다...

아무래도 분석하는 글을 따로 쓰고 와야할 것 같다


음성채널

자 이제 제대로 만들어보자

일단 봇이 음성채널에 들어가는 것부터 다시 해보자

@bot.command()
async def play(ctx):
    channel = ctx.author.voice.channel
    await channel.connect()

저번 글에서도 한번 했으니 크게 어렵지는 않다

다만 저번과 다르게 좀 더 깊게 이해한 것 뿐이다

 

 

다음은 음성채널에서 나가기

단순히 생각해서 channel.disconnect()를 하면 될 것 같지만

안타깝게도 disconnet 함수는 ctx.author.voice.channel에 존재하지 않는다

 

그래서 VoiceClient로 바꿔보기로 했다.

VoiceClient는 bot.voice_clients를 통해 List 형태로 불러올 수 있다

다만 이걸로 connect는 하기 힘든게 bot.voice_clients는 봇이 음성채널에 들어가 있지 않으면 []를 반환한다

 

그래서 저번과 같이 connect와 disconnect 방법을 다르게 해주었다

@bot.command()
async def leave(ctx):
	await bot.voice_clients[0].disconnect()

거의 똑같이 만들었지만 확실히 이해하고 코딩을 하니 달라보이는 것 같다

 

음악재생

드디어 이제 노래를 재생시켜보자

디코에서 굳이 음악을 듣지 않아서 좀 밀렸다

 

저번에는 유튜브에서 youtube_dl을 이용해 파일을 다운로드 받고 ffmpeg로 mp3로 바꾼 뒤 그걸 봇이 찾아서 재생했다

 

다행이 찾아보니 다운로드 받지 않고도 바로 재생할 수 있었다

stackoverflow.com/questions/57688808/playing-music-with-a-bot-from-youtube-without-downloading-the-file

 

Playing music with a bot from Youtube without downloading the file

How would i go about playing music using a discord bot from Youtube without downloading the song as a file? I've already had a look at the included music bot in the discord.py documentation but th...

stackoverflow.com

 

test.py라는 새로운 파일을 만들어서 실험해봤다

import discord
import youtube_dl
from discord.ext import commands

bot = commands.Bot(command_prefix = "!")

@bot.command()
async def play(ctx, url):
    channel = ctx.author.voice.channel
    if bot.voice_clients == []:
    	await channel.connect()
    	await ctx.send("connected to the voice channel, " + str(bot.voice_clients[0].channel))

    ydl_opts = {'format': 'bestaudio'}
    FFMPEG_OPTIONS = {'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 'options': '-vn'}
    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
        info = ydl.extract_info(url, download=False)
        URL = info['formats'][0]['url']
    voice = bot.voice_clients[0]
    voice.play(discord.FFmpegPCMAudio(URL, **FFMPEG_OPTIONS))

@bot.command()
async def leave(ctx):
    await bot.voice_clients[0].disconnect()


bot.run("your token here")

voice는 VoiceClient인 bot.voice_cliens[0]를 가져와서 VoiceClient.play()discord.FFmpegPCMAudio()를 사용해서

음악을 재생한다.

info는 url에 대한 모든 정보(제목, 업로더, 길이 등...)를 가져오고

그중 url format만 뽑아서 URL에 저장한다

그리고 URL를 discord.FFmpegPCMAudio의 source에 넣어주면 된다

더보기

위의 stackoverflow글을 보면 알겠지만 이방법이 조금 문제가 있다고 한다

그래서 **FFMPEG_OPTIONS를 추가했다고 하는데 이건 잘 모르겠다

일단 뭐... 재생은 되니까....

 

그리고 VoiceClient에 있는 pause와 resume, stop도 한번 시도해보기로 했다.

@bot.command()
async def pause(ctx):
    if not bot.voice_clients[0].is_paused():
        bot.voice_clients[0].pause()
    else:
        await ctx.send("already paused")

@bot.command()
async def resume(ctx):
    if bot.voice_clients[0].is_paused():
        bot.voice_clients[0].resume()
    else:
        await ctx.send("already playing")
        
@bot.command()
async def stop(ctx):
	if bot.voice_clients[0].is_playing():
    	bot.voice_clients[0].stop()
    else:
    	await ctx.send("not playing")

확실히 저번과 다르게 조금이라도 공부하고 하니 잘되는 것 같다

 

 

 

이로써 미뤄두었던 음악봇을 조금이나마 만들어봤다

url을 직접 입력해야하고 재생목록도 없고 pause,resume,stop이 미흡히지만 일단 완성!

 

다음 글은 디스코드 봇 프로젝트 마지막글

이제 자체 서버에서 봇을 돌려보자