music.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. from __future__ import unicode_literals
  2. from urllib.parse import urlparse
  3. import youtube_dl
  4. import aiohttp
  5. import aiofiles
  6. import os
  7. from random import randint
  8. from pyrogram import filters
  9. from wbb import app, SUDOERS, arq, MAIN_CHATS
  10. from wbb.core.decorators.errors import capture_err
  11. from wbb.utils.pastebin import paste
  12. __MODULE__ = "Music"
  13. __HELP__ = """/ytmusic [link] To Download Music From Various Websites Including Youtube.
  14. /saavn [query] To Download Music From Saavn.
  15. /deezer [query] To Download Music From Deezer.
  16. /lyrics [query] To Get Lyrics Of A Song."""
  17. ydl_opts = {
  18. 'format': 'bestaudio/best',
  19. 'writethumbnail': True,
  20. 'postprocessors': [{
  21. 'key': 'FFmpegExtractAudio',
  22. 'preferredcodec': 'mp3',
  23. 'preferredquality': '192'
  24. }]
  25. }
  26. # Ytmusic
  27. @app.on_message(filters.command("ytmusic") & ~filters.edited & filters.user(SUDOERS))
  28. @capture_err
  29. async def music(_, message):
  30. if len(message.command) != 2:
  31. await message.reply_text("/ytmusic needs a link as argument")
  32. return
  33. link = message.text.split(None, 1)[1]
  34. m = await message.reply_text(f"Downloading {link}",
  35. disable_web_page_preview=True)
  36. try:
  37. with youtube_dl.YoutubeDL(ydl_opts) as ydl:
  38. info_dict = ydl.extract_info(link, download=False)
  39. audio_file = ydl.prepare_filename(info_dict)
  40. ydl.process_info(info_dict)
  41. # .webm -> .weba
  42. basename = audio_file.rsplit(".", 1)[-2]
  43. thumbnail_url = info_dict['thumbnail']
  44. thumbnail_file = basename + "." + \
  45. get_file_extension_from_url(thumbnail_url)
  46. audio_file = basename + ".mp3"
  47. except Exception as e:
  48. await m.edit(str(e))
  49. return
  50. # info
  51. title = info_dict['title']
  52. performer = info_dict['uploader']
  53. duration = int(float(info_dict['duration']))
  54. await m.delete()
  55. await message.reply_chat_action("upload_document")
  56. await message.reply_audio(audio_file, duration=duration, performer=performer,
  57. title=title, thumb=thumbnail_file)
  58. os.remove(audio_file)
  59. os.remove(thumbnail_file)
  60. def get_file_extension_from_url(url):
  61. url_path = urlparse(url).path
  62. basename = os.path.basename(url_path)
  63. return basename.split(".")[-1]
  64. # Funtion To Download Song
  65. async def download_song(url):
  66. song_name = f"{randint(6969, 6999)}.mp3"
  67. async with aiohttp.ClientSession() as session:
  68. async with session.get(url) as resp:
  69. if resp.status == 200:
  70. f = await aiofiles.open(song_name, mode='wb')
  71. await f.write(await resp.read())
  72. await f.close()
  73. return song_name
  74. is_downloading = False
  75. # Jiosaavn Music
  76. @app.on_message(filters.command("saavn") & ~filters.edited)
  77. @capture_err
  78. async def jssong(_, message):
  79. global is_downloading
  80. if len(message.command) < 2:
  81. await message.reply_text("/saavn requires an argument.")
  82. return
  83. if is_downloading:
  84. await message.reply_text("Another download is in progress, try again after sometime.")
  85. return
  86. is_downloading = True
  87. text = message.text.split(None, 1)[1]
  88. query = text.replace(" ", "%20")
  89. m = await message.reply_text("Searching...")
  90. try:
  91. songs = await arq.saavn(query)
  92. sname = songs[0].song
  93. slink = songs[0].media_url
  94. ssingers = songs[0].singers
  95. await m.edit("Downloading")
  96. song = await download_song(slink)
  97. await m.edit("Uploading")
  98. await message.reply_audio(audio=song, title=sname,
  99. performer=ssingers)
  100. os.remove(song)
  101. await m.delete()
  102. except Exception as e:
  103. is_downloading = False
  104. await m.edit(str(e))
  105. return
  106. is_downloading = False
  107. # Deezer Music
  108. @app.on_message(filters.command("deezer") & ~filters.edited)
  109. @capture_err
  110. async def deezsong(_, message):
  111. global is_downloading
  112. if len(message.command) < 2:
  113. await message.reply_text("/deezer requires an argument.")
  114. return
  115. if is_downloading:
  116. await message.reply_text("Another download is in progress, try again after sometime.")
  117. return
  118. is_downloading = True
  119. text = message.text.split(None, 1)[1]
  120. query = text.replace(" ", "%20")
  121. m = await message.reply_text("Searching...")
  122. try:
  123. songs = await arq.deezer(query, 1)
  124. title = songs[0].title
  125. url = songs[0].url
  126. artist = songs[0].artist
  127. await m.edit("Downloading")
  128. song = await download_song(url)
  129. await m.edit("Uploading")
  130. await message.reply_audio(audio=song, title=title,
  131. performer=artist)
  132. os.remove(song)
  133. await m.delete()
  134. except Exception as e:
  135. is_downloading = False
  136. await m.edit(str(e))
  137. return
  138. is_downloading = False
  139. # Lyrics
  140. @app.on_message(filters.command("lyrics"))
  141. async def lyrics_func(_, message):
  142. if len(message.command) < 2:
  143. await message.reply_text("**Usage:**\n/lyrics [QUERY]")
  144. return
  145. m = await message.reply_text("**Searching**")
  146. query = message.text.strip().split(None, 1)[1]
  147. song = await arq.lyrics(query)
  148. lyrics = song.lyrics
  149. if len(lyrics) < 4095:
  150. await m.edit(f"__{lyrics}__")
  151. return
  152. lyrics = await paste(lyrics)
  153. await m.edit(f"**LYRICS_TOO_LONG:** [URL]({lyrics})")