class YaMusic: cache_path = "ya_cache.json" def __init__(self): logger.level = logging.ERROR self.client = Client() self.cache = {} self.load_cache() self.i = 0 def load_cache(self): if not os.path.exists(self.cache_path): return with open(self.cache_path, "r") as file: d = json.load(file) for key, value in d.items(): self.cache[key] = Music.from_json(value) def save_cache(self): d = {} for key, value in self.cache.items(): d[key] = value.to_json() with open(self.cache_path, "w") as file: json.dump(d, file) def get_song(self, name, author): title = "{} - {}".format(author, name) song = self.cache.get(title, None) if song: return song self.i += 1 if self.i > 50: self.save_cache() self.i = 0 song = self.client.search(title).best if song is None or type(song.result) is not Track: music = Music() music.name = name music.author = [author] self.cache[title] = music return music song = song.result music = Music() music.duration = song.duration_ms music.name = song.title music.author = [a.name for a in song.artists] music.year = song.albums[0].year or song.albums[ 0].release_date if song.albums else None music.genres = [a.genre for a in song.albums if a.genre] for i in music.genres: if i not in all_genres: print(i) self.cache[title] = music return music
async def yaplay(self, ctx, arg: str = None): if arg == None: if await MusicBot.langueg(ctx) == "RUS": embed = discord.Embed( title=f"Вы должны указать название трэка", color=0xff7606) elif await MusicBot.langueg(ctx) == "ENG": embed = discord.Embed( title=f"You must indicate the name of the track.", color=0xff7606) await ctx.send(embed=embed) return vol = 50 self.vol = vol voice = get(self.bot.voice_clients, guild=ctx.guild) try: channel = ctx.author.voice.channel except: if await MusicBot.langueg(ctx) == "RUS": embed = discord.Embed( title=f"**{ctx.author.name} Вы не в голосовом канале**", color=0xff7606) elif await MusicBot.langueg(ctx) == "ENG": embed = discord.Embed( title= f"**{ctx.author.name} You are not in the voice channel**", color=0xff7606) await ctx.send(embed=embed) return if voice and voice.is_connected(): await voice.move_to(channel) else: voice = await channel.connect() #Логирование (отключение) logger = logging.getLogger() logger.setLevel(logging.CRITICAL) #Подключенеи к акку request = Request(proxy_url="https://*****:*****@217.29.62.232:6333") client = Client(token=MusicBot.YANDEX_TOKEN, request=request) #Делаем поисковой запрос search = client.search(arg) #Получаем треки tracks = search.tracks #Сортируем треки в list results = tracks.results #Получаем первый трек track = results[0] #Получаем всю инфу по загрузке info = track.get_download_info(get_direct_links=True) #get_direct_links=True - обязательно надо, а то х*йня получается!!!!!!!!! try: #Получаем полный путь к музыкальному файлу (поток) self.playurl = info[0].direct_link self.voice = voice self.voice.play(discord.FFmpegPCMAudio(self.playurl)) self.voice.source = discord.PCMVolumeTransformer(voice.source) self.voice.source.volume = self.vol except: if await MusicBot.langueg(ctx) == "RUS": embed = discord.Embed( title= f"**{ctx.author.name} На данный момент песня уже играет**", color=0xff7606) elif await MusicBot.langueg(ctx) == "ENG": embed = discord.Embed( title= f"**{ctx.author.name} At the moment the song is already playing**", color=0xff7606) await ctx.send(embed=embed) return #Вызываем плеер if await MusicBot.langueg(ctx) == "RUS": embed = discord.Embed( title=f"**{track.title}**", description= f":white_small_square: **ID: {track.id} :game_die:**\n\n" f":white_small_square: **Регион: {track.regions[0]} :globe_with_meridians:**\n\n" f":white_small_square: **[Поделится](https://music.yandex.ru/track/{track.id}) :trumpet:**\n\n", color=0xf2a20d) # ~ embed.set_thumbnail(url=f"{cover_uri}") # ~ embed.set_image(url=f'{track.og_image}') embed.set_thumbnail( url= f"https://cdn.dribbble.com/users/851627/screenshots/2270820/record-player.gif" ) embed.set_footer( text= f"•Длительность трека: {int((track.duration_ms)/1000/60)} минут\n•Исполнитель: {track.artists[0].name}" ) elif await MusicBot.langueg(ctx) == "ENG": embed = discord.Embed( title=f"**{track.title}**", description= f":white_small_square: **ID: {track.id} :game_die:**\n\n" f":white_small_square: **Region: {track.regions[0]} :globe_with_meridians:**\n\n" f":white_small_square: **[Share](https://music.yandex.ru/track/{track.id}) :trumpet:**\n\n", color=0xf2a20d) # ~ embed.set_thumbnail(url=f"{cover_uri}") # ~ embed.set_image(url=f'{track.og_image}') embed.set_thumbnail( url= f"https://cdn.dribbble.com/users/851627/screenshots/2270820/record-player.gif" ) msg = await ctx.send(embed=embed) await msg.add_reaction(str("▶")) await msg.add_reaction(str("⏸")) await msg.add_reaction(str("🔊")) await msg.add_reaction(str("🔉")) await msg.add_reaction(str("⏹")) await msg.add_reaction(str("❤️")) self.msg_play = msg
class MusicClient: def __init__(self): self.token = None self.client = None self.loggedIn = False self.online = False self.ui = None def init(self): if os.path.isfile('token.txt'): try: tokenFile = open('token.txt', 'r') self.token = tokenFile.read() tokenFile.close() self.client = Client(self.token) self.loggedIn = True self.online = True except: return False else: return False return True def auth(self, login, password): try: self.client = Client.from_credentials( login, password, captcha_callback=self.proc_captcha) tokenFile = open('token.txt', 'w') tokenFile.write(self.client.token) tokenFile.close() self.loggedIn = True return True except Exception as e: return False def proc_captcha(self, captcha): captcha.download('captcha.png') if os.system("./captcha.png") != 0: os.system("xdg-open ./captcha.png") return input('Число с картинки: ') def getFeedPlaylists(self): playlists = self.client.feed().generated_playlists return storage.savePlaylists(playlists, is_feed=1) def getPlaylistTracks(self, playlist): p = self.client.playlists_list([playlist.id]) if (len(p) == 0): return [] clientPlaylist = p[0] return storage.saveTracks(clientPlaylist.fetchTracks(), playlist=playlist) def getUri(self, track): if not self.online: return None if (track._directLink != None): return track._directLink try: trackInfo = self.client.tracks_download_info(track.id, True) for info in trackInfo: if info.codec == "mp3" and info.bitrate_in_kbps == 192: # info.get_direct_link() track._directLink = info.direct_link return track._directLink except Exception as e: raise e print("Cannot get track info. " + str(e)) return None def downloadTrack(self, track): if not self.online: return None trackInfo = self.client.tracks_download_info(track.id, True) for info in trackInfo: if info.codec == "mp3" and info.bitrate_in_kbps == 192: info.download(track.getDownloadsDirectory() + '/' + track.generateFilename()) track.is_downloaded = 1 track.filename = track.generateFilename() track.store() def getArtistTracks(self, artist, page=0, pageSize=20): data = self.client.artists_tracks(artist.id, page, pageSize) return storage.saveTracks(data.tracks) def getArtistAlbums(self, artist): albums = [] page = 0 pageSize = 20 maxPage = 1 while page < maxPage: data = self.client.artists_direct_albums(artist.id, page, pageSize) maxPage = (data.pager.total // pageSize) + 1 albums.extend(data.albums) page = page + 1 return storage.saveAlbums(albums) def getAlbumTracks(self, album): data = self.client.albums_with_tracks(album.id) tracks = [] for arr in data.volumes: tracks.extend(arr) return storage.saveTracks(tracks) def search(self, query): data = self.client.search(query) response = { "best": None, "best_type": None, "tracks": [], "albums": [], "artists": [], "playlists": [], } tracks = data.tracks.results albums = data.albums.results artists = data.artists.results playlists = data.playlists.results print(list(tracks), file=open('a1.log', 'w')) response['tracks'] = storage.saveTracks(tracks) response['albums'] = storage.saveAlbums(albums) response['artists'] = storage.saveArtists(artists) response['playlists'] = storage.savePlaylists(playlists) best = None if (data.best.type == 'track'): best = storage.saveTracks([data.best.result])[0] response['best_type'] = 'track' if (data.best.type == 'artist'): best = storage.saveArtists([data.best.result])[0] response['best_type'] = 'artist' if (data.best.type == 'playlist'): best = storage.savePlaylists([data.best.result])[0] response['best_type'] = 'playlist' if (data.best.type == 'album'): best = storage.saveAlbums([data.best.result])[0] response['best_type'] = 'album' response['best'] = best return response def likeTrack(self, track): if (track.is_liked == 1): self.client.users_likes_tracks_remove(track.id) track.is_liked = 0 else: self.client.users_likes_tracks_add(track.id) track.is_liked = 1 track.is_disliked = 0 track.store() def dislikeTrack(self, track): if (track.is_disliked == 1): self.client.users_dislikes_tracks_remove(track.id) track.is_disliked = 0 else: self.client.users_dislikes_tracks_add(track.id) track.is_disliked = 1 track.is_liked = 0 track.store() def getLikedTracks(self): tracks = self.client.users_likes_tracks().fetch_tracks() return storage.saveTracks(tracks, isLiked=True)
class Player: def __init__(self): self.token = None self.client = None self.loggedIn = False self.vlc = None self.vlcPlayer = None self.daemons = [] self.download_daemons = [] self.download_queue = Queue() def play_tracks(self, tracks): if self.vlc == None: self.vlc = vlc.Instance() self.vlcPlayer = self.vlc.media_list_player_new() media = [] media_list = self.vlc.media_list_new() has_track = False try: for daemon in self.daemons: daemon._stop() except: pass finally: self.daemons = [] queue = Queue() t = TrackInfo(queue) t.setDaemon(True) t.start() self.daemons.append(t) for track in tracks: path = "music/" + self.track_name(track) + '.mp3' if os.path.isfile(path): #media.append(path) media_list.lock() media_list.add_media(path) media_list.unlock() has_track = True else: if has_track == False: trackInfo = track.get_download_info() for info in trackInfo: if info.codec == "mp3" and info.bitrate_in_kbps == 192: info.get_direct_link() print(info) #media.append(info.direct_link) media_list.lock() media_list.add_media(info.direct_link) media_list.unlock() has_track = True break else: queue.put({'track': track, 'list': media_list}) print("Here!") self.vlcPlayer.set_media_list(media_list) print("Here!1") self.vlcPlayer.play() print("Here!2") should_exit = False while not should_exit: try: selection = self.get_input("[P]lay / P[a]use / [S]top / [N]ext / P[r]ev / Ba[c]k \n>> ", ["P", "a", "S", "N", "r", "c"]) if selection == "P": self.vlcPlayer.play() elif selection == "a": self.vlcPlayer.pause() elif selection == "S": self.vlcPlayer.stop() should_exit = True elif selection == "N": self.vlcPlayer.next() elif selection == "r": self.vlcPlayer.previous() elif selection == "c": should_exit = True except Exception as e: print(e) def player_controls(self): if (self.vlcPlayer == None): print("Player not initialized") return; should_exit = False while not should_exit: try: selection = self.get_input("[P]lay / P[a]use / [S]top / [N]ext / P[r]ev / Ba[c]k \n>> ", ["P", "a", "S", "N", "r", "c"]) if selection == "P": self.vlcPlayer.play() elif selection == "a": self.vlcPlayer.pause() elif selection == "S": self.vlcPlayer.stop() should_exit = True elif selection == "N": self.vlcPlayer.next() elif selection == "r": self.vlcPlayer.previous() elif selection == "c": should_exit = True except Exception as e: print(e) def init(self): if os.path.isfile('token.txt'): try: tokenFile = open('token.txt', 'r') self.token = tokenFile.read() tokenFile.close(); self.client = Client(self.token) self.loggedIn = True except: print("Failed to create client using saved token. Enter your login/password.") self.login() else: self.login() def login(self): self.loggedIn = False while not self.loggedIn: try: login = input("Login: "******"Password: "******"Login failed!") print(e) def proc_captcha(self, captcha): captcha.download('captcha.png') if os.system("./captcha.png") != 0: os.system("xdg-open ./captcha.png") return input('Число с картинки: ') def get_status(self): data = self.client.account_status() print("Login: "******"Name: " + data.account.first_name) print("Surname: " + data.account.second_name) def playlists(self): playlists = player.client.feed().generated_playlists should_exit = False while not should_exit: try: index = 1 for playlist in playlists: print(str(index) + ") " + playlist.data.title) index = index + 1 selection = self.get_input('Playlist number / [B]ack \n>> ', ["B"]) if (selection == "B"): should_exit = True else: self.playlist(playlists[int(selection) - 1]) except Exception as e: print(e) def track_name(self, track): artists = "" for artist in track.artists: artists = artists + artist.name + " " return track.title + " ( " + artists + " )" def playlist(self, playlist): tracksShort = [] if (hasattr(playlist, "data")): tracksShort = playlist.data.tracks else: p = self.client.playlists_list( playlist.playlist_id ) tracksShort = p[0].tracks track_ids = [] for trackShort in tracksShort: track_ids.append(trackShort.track_id) if (len(track_ids) == 0): print("Tracks list is empty") return tracks = self.client.tracks(track_ids) should_exit = False while not should_exit: try: index = 1 for track in tracks: print(str(index) + ") " + self.track_name(track)) index = index + 1 selection = self.get_input("Track number / [D]ownload / [P]lay / [L]ike / D[i]slike / [B]ack\n>> ", ["D", "P", "L", "i", "B"]) if selection == "D": self.download_tracks(tracks) elif (selection == "L"): playlist.like() elif (selection == "i"): playlist.dislike() elif selection == "B": should_exit = True elif selection == "P": self.play_tracks(tracks) else: self.track(tracks[selection - 1]) except Exception as e: print(e) def get_input(self, prompt, allowed = [], numbers = True): valid = False while not valid: selection = input(prompt) if selection in allowed: return selection if (numbers == True): try: number = int(selection) if (number > 0): return number except: pass def download_tracks(self, tracks): if (len(self.download_daemons) == 0): for i in range(2): t = TrackDownloader(self.download_queue) t.setDaemon(True) t.start() self.download_daemons.append(t) print("Downloading " + str(len(tracks)) + " tracks") for track in tracks: self.download_queue.put(track.track_id) def track(self, track): print(self.track_name(track)) should_exit = False while not should_exit: try: selection = self.get_input("[D]ownload / [P]lay / [L]ike / D[i]slike / [B]ack\n>> ", ["D", "P", "L", "i", "B"], False) if selection == "D": self.download_tracks([track]) elif (selection == "L"): track.like() elif (selection == "i"): track.dislike() elif selection == "P": self.play_tracks([track]) else: should_exit = True except Exception as e: print(e) def search(self): query = input("Search: ") data = self.client.search(text=query) print(data) results = [] for track in data.tracks.results: results.append(track) for album in data.albums.results: results.append(album) for artist in data.artists.results: results.append(artist) for playlist in data.playlists.results: results.append(playlist) best = data.best.result if (best != None): print("B) " + self.entity_name(best)) index = 1 for result in results: print(str(index) + ") " + self.entity_name(result)) index = index + 1 should_exit = False while not should_exit: try: selection = self.get_input("Number / [B]est choice / [E]xit \n>> ", ["B", "E"]) if selection == "B": self.open_entity(best) elif selection == "E": should_exit = True else: self.open_entity(results[selection - 1]) except Exception as e: print(e) def open_entity(self, entity): if (type(entity) is Track): self.track(entity) elif (type(entity) is Playlist): self.playlist(entity) elif (type(entity) is Artist): self.artist(entity) elif (type(entity) is Album): self.album(entity) def entity_name(self, result): if (type(result) is Artist): return ("(Artist) " + result.name) elif type(result) is Track: return ("(Track) " + self.track_name(result)) elif type(result) is Album: artists = "" for artist in result.artists: artists = artists + " " + artist.name return ("(Album) " + result.title + " (" + artists + " )") elif type(result) is Playlist: return "(Playlist) " + result.title + " by " + result.owner.name else: return (str(type(result))) def artist(self, artist): print(artist.name) print(artist.description) page = 0 tracks = artist.get_tracks(page=page).tracks albums = artist.get_albums(page=page).albums entities = [] for track in tracks: entities.append(track) for album in albums: entities.append(album) should_exit = False while not should_exit: try: index = 1 for e in entities: print(str(index) + ") " + self.entity_name(e)) index = index + 1 selection = self.get_input("Number / [D]ownload / [P]lay / [L]ike / D[i]slike / [B]ack / [M]ore / [A]ll\n>> ", ["D", "P", "L", "i", "B", "M", "A"]) if selection == "D": t = [] for e in entities: if (type(e) is Track): t.append(e) self.download_tracks(t) elif (selection == "L"): artist.like() elif (selection == "i"): artist.dislike() elif selection == "P": t = [] for e in entities: if (type(e) is Track): t.append(e) self.play_tracks(t) elif selection == "B": should_exit = True elif selection == "M": page = page + 1 tracks = artist.get_tracks(page=page).tracks albums = artist.get_albums(page=page).albums for track in tracks: entities.append(track) for album in albums: entities.append(album) elif selection == "A": tPage = page aPage = page while True: tPage = tPage + 1 tracks = artist.get_tracks(page=tPage).tracks for track in tracks: entities.append(track) sys.stdout.write('.') if (len(tracks) == 0): break print('') while True: aPage = aPage + 1 albums = artist.get_albums(page=aPage).albums for a in albums: entities.append(a) sys.stdout.write('.') if (len(albums) == 0): break else: self.open_entity(entities[selection - 1]) except Exception as e: print(e) def get_all(self, func, prop): page = 0 last_page = 1 data = [] while page < last_page: portion = func(page=page) for e in portion[prop]: data.append(e) last_page = portion.pager.total / portion.pager.per_page + 1 page = page + 1 print(page) return data def album(self, album): print(self.entity_name(album)) album_tracks = album.with_tracks() should_exit = False while not should_exit: try: index = 1 for track in album_tracks.volumes[0]: print(str(index) + ") " + self.track_name(track)) index = index + 1 selection = self.get_input("[A]rtist / [D]ownload / [P]lay / [L]ike / D[i]slike / [B]ack \n>> ", ["A", "D", "P", "L", "i", "B"]) if selection == "D": self.download_tracks(album_tracks.volumes[0]) elif selection == "A": self.artist(album_tracks.artists[0]) elif selection == "L": album_tracks.like() elif selection == "i": album_tracks.dislike() elif selection == "B": should_exit = True elif selection == "P": self.play_tracks(album_tracks.volumes[0]) else: self.track(album_tracks.volumes[0][selection - 1]) except Exception as e: print(e) def menu(self): should_exit = False while not should_exit: # try: selection = self.get_input("[P]laylists / [M]e / [S]earch / P[l]ayer / [E]xit \n>> ", ["P", "M", "S", "E", "l"], False) if (selection == "P"): self.playlists() elif selection == "M": self.get_status() elif selection == "S": self.search() elif selection == "E": should_exit = True elif selection == "l": self.player_controls()