티스토리 뷰
*이 글은 python 버전 3.6, discord.py 버전 0.16.12 기준으로 작성된 글입니다.*
디스코드 봇으로 유튜브 재생하기
디스코드 봇에는 다양한 기능이 존재합니다.
이번 시간에는 디스코드 봇의 기능 중 하나인 유튜브 재생 기능을 사용해 보도록 하겠습니다.
먼저 이 기능을 사용하기 전에는 설치해야 하는 프로그램들이 있습니다.
사용하는 라이브러리
discord
asyncio
youtube_dl
re
재생기능
제가 사용하고 있는 유튜브 재생 코드입니다.
위 사진을 클릭하면 소스코드가 있는 깃허브로 연결됩니다.
이렇게만 봐서는 알아보기가 힘들어서 부분을 나눠서 살펴보도록 하겠습니다.
if message.content.startswith("!음악"): #음성채널에 봇을 추가 및 음악 재생 msg = message.content.split(" ") try: url = msg[1] url1 = re.match('(https?://)?(www\.)?((youtube\.(com))/watch\?v=([-\w]+)|youtu\.be/([-\w]+))', url) #정규 표현식을 사용해 url 검사 if url1 == None: await client.send_message(message.channel, embed=discord.Embed(title=":no_entry_sign: url을 제대로 입력해주세요.",colour = 0x2EFEF7)) return except IndexError: await client.send_message(message.channel, embed=discord.Embed(title=":no_entry_sign: url을 입력해주세요.",colour = 0x2EFEF7)) return
메시지가 !음악으로 시작할 때 URL을 입력받고 저장하는 코드입니다.
split 함수를 사용해 문자열을 나누고 URL에 해당하는 부분을 정규 표현식을 사용해 유튜브 링크인지 검색합니다.
그 다음 URL이 유튜브 링크가 아니거나 URL 입력이 없을 때 오류 문구를 출력합니다.
channel = message.author.voice.voice_channel server = message.server voice_client = client.voice_client_in(server)
1번째 줄은 메시지를 보낸 사람이 접속해있는 음성채널을 받아오는 코드입니다.
2~3번째 줄은 조건문을 사용하기 위해 봇이 음성채널에 있으면 그 음성채널도 받아옵니다.
if client.is_voice_connected(server) and not playerlist[server.id].is_playing(): #봇이 음성채널에 접속해있으나 음악을 재생하지 않을 때 await voice_client.disconnect()
봇이 음성채널에 있는데 음악을 재생하지 않을 때 다시 재생하기 위해 봇이 음성채널에서 나가는 코드입니다.
elif client.is_voice_connected(server) and playerlist[server.id].is_playing(): #봇이 음성채널에 접속해있고 음악을 재생할 때 player = await voice_client.create_ytdl_player(url,after=lambda:queue(server.id),before_options="-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5") if server.id in que: #큐에 값이 들어있을 때 que[server.id].append(player) else: #큐에 값이 없을 때 que[server.id] = [player] await client.send_message(message.channel, embed=discord.Embed(title=":white_check_mark: 추가 완료!",colour = 0x2EFEF7)) playlist.append(player.title) #재생목록에 제목 추가 return
봇이 음성채널에 접속해있고 음악을 재생하고 있을 때 실행되는 코드입니다.
입력받은 URL을 youtube_dl로 다운로드 받고 큐에 데이터들을 저장합니다.
def queue(id): #음악 재생용 큐 if que[id] != []: player = que[id].pop(0) playerlist[id] = player del playlist[0] player.start()
만들어 둔 큐입니다. 노래제목과 다운로드 받은 데이터들을 저장하는 용도입니다.
try: voice_client = await client.join_voice_channel(channel) except discord.errors.InvalidArgument: #유저가 음성채널에 접속해있지 않을 때 await client.send_message(message.channel, embed=discord.Embed(title=":no_entry_sign: 음성채널에 접속하고 사용해주세요.",colour = 0x2EFEF7)) return
저장된 음성채널로 봇이 들어오는 코드입니다. 저장된 음성채널이 없을 경우 오류를 출력합니다.
try: player = await voice_client.create_ytdl_player(url,after=lambda:queue(server.id),before_options="-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5") playerlist[server.id] = player playlist.append(player.title) except youtube_dl.utils.DownloadError: #유저가 제대로 된 유튜브 경로를 입력하지 않았을 때 await client.send_message(message.channel, embed=discord.Embed(title=":no_entry_sign: 존재하지 않는 경로입니다.",colour = 0x2EFEF7)) await voice_client.disconnect() return player.start()
입력받은 url을 이용해 영상을 재생하는 코드입니다.
큐에 youtube_dl로 다운로드 받은 데이터와 동영상의 제목을 저장하고 노래를 재생합니다.
만약 URL이 정상적인 영상의 경로가 아닐 때 오류 메시지를 출력합니다.
종료, 스킵기능
if message.content == "!종료": #음성채널에서 봇을 나가게 하기 server = message.server voice_client = client.voice_client_in(server) if voice_client == None: #봇이 음성채널에 접속해있지 않았을 때 await client.send_message(message.channel, embed=discord.Embed(title=":no_entry_sign: 봇이 음성채널에 없어요.",colour = 0x2EFEF7)) return await client.send_message(message.channel, embed=discord.Embed(title=":mute: 채널에서 나갑니다.",colour = 0x2EFEF7)) #봇이 음성채널에 접속해있을 때 await voice_client.disconnect()
재생기능을 만들었으면 이제 종료기능도 만들어보겠습니다.
봇이 위치한 음성채널을 받아와 그 음성채널에서 나가게 하는 코드입니다.
봇이 음성채널에 접속해있지 않으면 오류 메시지를 출력합니다.
if message.content == "!스킵": id = message.server.id if not playerlist[id].is_playing(): #재생 중인 음악이 없을 때 await client.send_message(message.channel, embed=discord.Embed(title=":no_entry_sign: 스킵할 음악이 없어요.",colour = 0x2EFEF7)) return await client.send_message(message.channel, embed=discord.Embed(title=":mute: 스킵했어요.",colour = 0x2EFEF7)) playerlist[id].stop()
종료기능은 단순히 봇이 음성채널에서 나가는 기능입니다. 그렇기에 노래를 1개씩 건너뛰고 싶을 때는 사용할 수 없습니다.
그럴 때를 대비해 스킵기능도 만들겠습니다. 종료기능처럼 코드는 매우 간단합니다.
메시지가 작성된 서버의 ID를 받아 큐에 저장된 ID와 비교하고 음악이 재생 중일 때 그 음악을 종료합니다.
재생목록기능
if message.content == "!목록": if playlist == []: await client.send_message(message.channel, embed=discord.Embed(title=":no_entry_sign: 재생목록이 없습니다.",colour = 0x2EFEF7)) return playstr = "```css\n[재생목록]\n\n" for i in range(0, len(playlist)): playstr += str(i+1)+" : "+playlist[i]+"\n" await client.send_message(message.channel, playstr+"```")
재생 중인 노래의 제목과 대기 중인 노래의 목록을 확인하고 싶어 재생목록기능도 추가했습니다.
재생목록이 비어있지 않을 경우 재생목록을 출력합니다.
'프로그래밍 > python' 카테고리의 다른 글
[python3] pyinstaller를 이용해 .py 파일을 .exe 파일로 변환하기 (0) | 2019.03.02 |
---|---|
[python3] PyQt5 및 Qt Designer 설치 (0) | 2019.02.23 |
[python3] 디스코드 봇 명령어 제작 및 메세지 꾸미기 (0) | 2018.06.28 |
[python3] 디스코드 봇 생성 및 텍스트 출력하기 (2) | 2018.05.11 |