dsplayer


Namedsplayer JSON
Version 2.2.0 PyPI version JSON
download
home_pagehttps://github.com/FlacSy/dsplayer
SummaryMusic player for Discord
upload_time2024-10-15 16:49:57
maintainerNone
docs_urlNone
authorFlacSy
requires_python>=3.10.0
licenseNone
keywords
VCS
bugtrack_url
requirements requests bs4 colorama selenium webdriver_manager yt-dlp PyNaCl
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # DSPlayer

## Описание

`dsplayer` — это библиотека для создания Discord-ботов, которая позволяет подключаться к голосовым каналам, воспроизводить музыкальные треки и управлять очередями воспроизведения. Библиотека также поддерживает плагины, что позволяет расширять количество доступных платформ для воспроизведения.

**Совместимость:** `dsplayer` работает с библиотеками `disnake`, `discord.py` и `nextcord`.

## Установка

Установите библиотеку с помощью `pip` из PyPI:

```bash
pip install dsplayer
```

Или установите последнюю версию с GitHub:

```bash
pip install git+https://github.com/FlacSy/dsplayer
```

> **Примечание:** Установка через PyPI гарантирует стабильную версию, тогда как установка с GitHub предоставляет последние изменения и улучшения.

---

---

## Список изменений

Ниже представлен список изменений для библиотеки, начиная с версии **2.0.0**.

- **2.0.0** | Глобальное обновление:
  - Обновлены компоненты: плеер, очередь, система плагинов.
  - Оптимизирован код для лучшей производительности.

- **2.0.1** | Исправления и улучшения:
  - Исправлены ошибки при инициализации некоторых классов.
  - Удалены ненужные части кода.
  - Добавлен новый метод в очередь: `get_current_track`.

- **2.1.0** | Новая система плагинов:
  - Добавлена поддержка двух типов плагинов: `addon` и `extractor`.
  - Частичная обратная совместимость с плагинами старых версий. Для работы старых плагинов необходимо реализовать метод `get_plugin_type`.

- **2.2.0** | Исправления и улучшения:
  - Удалены лишние фрагменты кода.
  - Обновлен стандарт возвращаемых данных плагинов. В этой версии плагины типа `extractor` совместимы только с версиями выше **1.4.0**!

## Плагины

В `dsplayer` предусмотрены следующие плагины:

- **[Query](dsplayer/plugins/query_plugin.py)** - Плагин для поиска музыки по названию (включен по умолчанию).
- **[Spotify](https://github.com/FlacSy/dsplayer-spotify)** - Плагин для поиска треков, плейлистов и авторов из Spotify.
    ```bash
    pip install dsplayer-spotify
    ```
- **[YouTube](https://github.com/FlacSy/dsplayer-youtube)** - Плагин для поиска треков из YouTube, YouTube Music и YouTube Shorts.
    ```bash
    pip install dsplayer-youtube
    ```
- **[SoundCloud](https://github.com/FlacSy/dsplayer-soundcloud)** - Плагин для поиска треков, плейлистов и авторов из SoundCloud.
    ```bash
    pip install dsplayer-soundcloud
    ```
- **[Apple Music](https://github.com/FlacSy/dsplayer-applemusic)** - Плагин для поиска треков из Apple Music.
    ```bash
    pip install dsplayer-applemusic
    ```

## Поисковые движки

В `dsplayer` предусмотрены следующие поисковые движки:

- **[YouTube Music](dsplayer/engines_system/ytmusic.py)** - Более быстрая, но менее точная поисковая система.
- **[SoundCloud](dsplayer/engines_system/soundcloud.py)** - Более точный поиск, но время отклика 2-3+ секунды.
- **[Bandcamp](dsplayer/engines_system/bandcamp.py)** - Высокая точность с хорошей производительностью.

> ⚠️ **Важно:** SoundCloud работает на Selenium! Для его использования необходимо установить Chrome и соответствующий Chrome Driver.

## Примеры использования

### Использование `Player` и `Queue`

#### Пример 1: Подключение и воспроизведение трека

```python
import disnake
from disnake.ext import commands
from dsplayer import Player, PluginLoader, YTMusicSearchEngine

intents = disnake.Intents.all()
bot = commands.Bot(command_prefix='!', intents=intents)
players = {}

@bot.command()
async def play(ctx, url):
    """Добавить трек в очередь и воспроизвести его."""
    if ctx.guild.id in players:
        player = players[ctx.guild.id]
    else:
        if ctx.author.voice:
            voice_channel = ctx.author.voice.channel
            player = Player(
                voice_channel=voice_channel,
                bot=bot,
                plugin_loader=PluginLoader(),
                engine=YTMusicSearchEngine,
                debug=True
            )
            players[ctx.guild.id] = player
            await player.connect()
        else:
            await ctx.send('Вы не подключены к голосовому каналу.')
            return

    await player.play(url)
    await ctx.send(f'Трек добавлен в очередь: {url}')

bot.run('YOUR_BOT_TOKEN')
```

#### Пример 2: Управление очередью треков

```python
@bot.command()
async def skip(ctx):
    """Пропустить текущий трек."""
    if ctx.guild.id in players:
        player = players[ctx.guild.id]
        await player.skip()
        await ctx.send('Играет следующий трек.')
    else:
        await ctx.send("Нет активного плеера для этого сервера.")

@bot.command()
async def previous(ctx):
    """Вернуться к предыдущему треку."""
    if ctx.guild.id in players:
        player = players[ctx.guild.id]
        await player.previous()
        await ctx.send('Играет предыдущий трек.')
    else:
        await ctx.send("Нет активного плеера для этого сервера.")

@bot.command()
async def queue(ctx):
    """Показать текущую очередь треков."""
    if ctx.guild.id in players:
        player = players[ctx.guild.id]
        queue = player.queue.get_queue()
        if queue:
            queue_list = "\n".join([f"{idx + 1}. {track['url']}" for idx, track in enumerate(queue)])
            await ctx.send(f"Очередь:\n{queue_list}")
        else:
            await ctx.send("Очередь пуста.")
    else:
        await ctx.send("Нет активного плеера для этого сервера.")

bot.run('YOUR_BOT_TOKEN')
```

#### Пример 3: Обработка событий

```python
from dsplayer import event

@event("on_play_track")
async def on_play_track(event_data: dict):
    """Отправляет сообщение, когда начинается воспроизведение трека."""
    track = event_data['track']
    channel_id = event_data['text_id']
    channel = bot.get_channel(channel_id)
    await channel.send(f"Начинается воспроизведение трека: {track['title']}")
```

## `PluginLoader`

### 1. Загрузка плагинов из директории

```python
from dsplayer import PluginLoader

plugins_list = ["custom_plugins.plugins"]
loader = PluginLoader(plugins_list)
```

### 2. Загрузка плагинов используя класс 

```python
from dsplayer import PluginLoader, PluginInterface

loader = PluginLoader()
loader.load_plugins_from_classes(plugins_list)

class MyCustomPlugin1(PluginInterface):
    # Реализация плагина
    ...

class MyCustomPlugin2(PluginInterface):
    # Реализация плагина
    ...

plugins_list = [MyCustomPlugin1, MyCustomPlugin2]
```

> **Пример бота можно найти в [examples/example_bot.py](examples/example_bot.py)**

## Обработка исключений

`dsplayer` предоставляет систему обработки исключений, позволяющую гибко реагировать на ошибки. Для этого рекомендуется использовать исключения из модуля `dsplayer.utils.exceptions.lib_exceptions`.

### Основные исключения

- **VoiceChaneNotConnected**  
  Возникает, если бот пытается воспроизвести трек, не подключившись к голосовому каналу.

- **TrackNotFound**  
  Возникает, если указанный трек не найден.

- **TrackError**  
  Общая ошибка, связанная с воспроизведением трека.

### Пример обработки исключений

```python
from dsplayer.utils.exceptions.lib_exceptions import VoiceChaneNotConnected, TrackNotFound, TrackError

try:
    # Ваш код
except VoiceChaneNotConnected as e:
    print(f"Ошибка подключения: {e}")
except TrackNotFound as e:
    print(f"Трек не найден: {e}")
except TrackError as e:
    print(f"Ошибка воспроизведения трека: {e}")
```

### Список доступных исключений

- **VoiceChaneError**  
  - **VoiceChaneNotConnected**: Бот не подключен к голосовому каналу.
  - **VoiceChaneNotFound**: Указанный голосовой канал не найден.
  - **VoiceChaneNotPlaying**: Бот не воспроизводит трек.

- **ConnectionError**  
  - Проблемы с подключением к голосовому каналу.

- **TrackError**  
  - **TrackNotFound**: Трек не найден.
  - **TrackError**: Ошибка воспроизведения трека.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/FlacSy/dsplayer",
    "name": "dsplayer",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10.0",
    "maintainer_email": null,
    "keywords": null,
    "author": "FlacSy",
    "author_email": "flacsy.x@gmail.com",
    "download_url": "https://files.pythonhosted.org/packages/3d/17/18234a29a607f76e35809cf0cb91932429d0dc2a3480cad3fbabc4fe74b9/dsplayer-2.2.0.tar.gz",
    "platform": null,
    "description": "# DSPlayer\r\n\r\n## \u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\r\n\r\n`dsplayer` \u2014 \u044d\u0442\u043e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f Discord-\u0431\u043e\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0442\u044c\u0441\u044f \u043a \u0433\u043e\u043b\u043e\u0441\u043e\u0432\u044b\u043c \u043a\u0430\u043d\u0430\u043b\u0430\u043c, \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u044c \u043c\u0443\u0437\u044b\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u0442\u0440\u0435\u043a\u0438 \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043e\u0447\u0435\u0440\u0435\u0434\u044f\u043c\u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f. \u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0438\u0432\u0430\u0435\u0442 \u043f\u043b\u0430\u0433\u0438\u043d\u044b, \u0447\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c \u0434\u043b\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f.\r\n\r\n**\u0421\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c:** `dsplayer` \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430\u043c\u0438 `disnake`, `discord.py` \u0438 `nextcord`.\r\n\r\n## \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430\r\n\r\n\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e `pip` \u0438\u0437 PyPI:\r\n\r\n```bash\r\npip install dsplayer\r\n```\r\n\r\n\u0418\u043b\u0438 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u044e\u044e \u0432\u0435\u0440\u0441\u0438\u044e \u0441 GitHub:\r\n\r\n```bash\r\npip install git+https://github.com/FlacSy/dsplayer\r\n```\r\n\r\n> **\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435:** \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0447\u0435\u0440\u0435\u0437 PyPI \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u0443\u044e \u0432\u0435\u0440\u0441\u0438\u044e, \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0441 GitHub \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f.\r\n\r\n---\r\n\r\n---\r\n\r\n## \u0421\u043f\u0438\u0441\u043e\u043a \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439\r\n\r\n\u041d\u0438\u0436\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0434\u043b\u044f \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u043d\u0430\u0447\u0438\u043d\u0430\u044f \u0441 \u0432\u0435\u0440\u0441\u0438\u0438 **2.0.0**.\r\n\r\n- **2.0.0** | \u0413\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435:\r\n  - \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u044b \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b: \u043f\u043b\u0435\u0435\u0440, \u043e\u0447\u0435\u0440\u0435\u0434\u044c, \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432.\r\n  - \u041e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d \u043a\u043e\u0434 \u0434\u043b\u044f \u043b\u0443\u0447\u0448\u0435\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438.\r\n\r\n- **2.0.1** | \u0418\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f:\r\n  - \u0418\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u044b \u043e\u0448\u0438\u0431\u043a\u0438 \u043f\u0440\u0438 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043a\u043b\u0430\u0441\u0441\u043e\u0432.\r\n  - \u0423\u0434\u0430\u043b\u0435\u043d\u044b \u043d\u0435\u043d\u0443\u0436\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 \u043a\u043e\u0434\u0430.\r\n  - \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c: `get_current_track`.\r\n\r\n- **2.1.0** | \u041d\u043e\u0432\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432:\r\n  - \u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0434\u0432\u0443\u0445 \u0442\u0438\u043f\u043e\u0432 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432: `addon` \u0438 `extractor`.\r\n  - \u0427\u0430\u0441\u0442\u0438\u0447\u043d\u0430\u044f \u043e\u0431\u0440\u0430\u0442\u043d\u0430\u044f \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u043e\u0441\u0442\u044c \u0441 \u043f\u043b\u0430\u0433\u0438\u043d\u0430\u043c\u0438 \u0441\u0442\u0430\u0440\u044b\u0445 \u0432\u0435\u0440\u0441\u0438\u0439. \u0414\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u0442\u0430\u0440\u044b\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u043c\u0435\u0442\u043e\u0434 `get_plugin_type`.\r\n\r\n- **2.2.0** | \u0418\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0443\u043b\u0443\u0447\u0448\u0435\u043d\u0438\u044f:\r\n  - \u0423\u0434\u0430\u043b\u0435\u043d\u044b \u043b\u0438\u0448\u043d\u0438\u0435 \u0444\u0440\u0430\u0433\u043c\u0435\u043d\u0442\u044b \u043a\u043e\u0434\u0430.\r\n  - \u041e\u0431\u043d\u043e\u0432\u043b\u0435\u043d \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432. \u0412 \u044d\u0442\u043e\u0439 \u0432\u0435\u0440\u0441\u0438\u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0442\u0438\u043f\u0430 `extractor` \u0441\u043e\u0432\u043c\u0435\u0441\u0442\u0438\u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0441 \u0432\u0435\u0440\u0441\u0438\u044f\u043c\u0438 \u0432\u044b\u0448\u0435 **1.4.0**!\r\n\r\n## \u041f\u043b\u0430\u0433\u0438\u043d\u044b\r\n\r\n\u0412 `dsplayer` \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u044b:\r\n\r\n- **[Query](dsplayer/plugins/query_plugin.py)** - \u041f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u043c\u0443\u0437\u044b\u043a\u0438 \u043f\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044e (\u0432\u043a\u043b\u044e\u0447\u0435\u043d \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e).\r\n- **[Spotify](https://github.com/FlacSy/dsplayer-spotify)** - \u041f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0442\u0440\u0435\u043a\u043e\u0432, \u043f\u043b\u0435\u0439\u043b\u0438\u0441\u0442\u043e\u0432 \u0438 \u0430\u0432\u0442\u043e\u0440\u043e\u0432 \u0438\u0437 Spotify.\r\n    ```bash\r\n    pip install dsplayer-spotify\r\n    ```\r\n- **[YouTube](https://github.com/FlacSy/dsplayer-youtube)** - \u041f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0442\u0440\u0435\u043a\u043e\u0432 \u0438\u0437 YouTube, YouTube Music \u0438 YouTube Shorts.\r\n    ```bash\r\n    pip install dsplayer-youtube\r\n    ```\r\n- **[SoundCloud](https://github.com/FlacSy/dsplayer-soundcloud)** - \u041f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0442\u0440\u0435\u043a\u043e\u0432, \u043f\u043b\u0435\u0439\u043b\u0438\u0441\u0442\u043e\u0432 \u0438 \u0430\u0432\u0442\u043e\u0440\u043e\u0432 \u0438\u0437 SoundCloud.\r\n    ```bash\r\n    pip install dsplayer-soundcloud\r\n    ```\r\n- **[Apple Music](https://github.com/FlacSy/dsplayer-applemusic)** - \u041f\u043b\u0430\u0433\u0438\u043d \u0434\u043b\u044f \u043f\u043e\u0438\u0441\u043a\u0430 \u0442\u0440\u0435\u043a\u043e\u0432 \u0438\u0437 Apple Music.\r\n    ```bash\r\n    pip install dsplayer-applemusic\r\n    ```\r\n\r\n## \u041f\u043e\u0438\u0441\u043a\u043e\u0432\u044b\u0435 \u0434\u0432\u0438\u0436\u043a\u0438\r\n\r\n\u0412 `dsplayer` \u043f\u0440\u0435\u0434\u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u044b \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u044b\u0435 \u0434\u0432\u0438\u0436\u043a\u0438:\r\n\r\n- **[YouTube Music](dsplayer/engines_system/ytmusic.py)** - \u0411\u043e\u043b\u0435\u0435 \u0431\u044b\u0441\u0442\u0440\u0430\u044f, \u043d\u043e \u043c\u0435\u043d\u0435\u0435 \u0442\u043e\u0447\u043d\u0430\u044f \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u0430\u044f \u0441\u0438\u0441\u0442\u0435\u043c\u0430.\r\n- **[SoundCloud](dsplayer/engines_system/soundcloud.py)** - \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0447\u043d\u044b\u0439 \u043f\u043e\u0438\u0441\u043a, \u043d\u043e \u0432\u0440\u0435\u043c\u044f \u043e\u0442\u043a\u043b\u0438\u043a\u0430 2-3+ \u0441\u0435\u043a\u0443\u043d\u0434\u044b.\r\n- **[Bandcamp](dsplayer/engines_system/bandcamp.py)** - \u0412\u044b\u0441\u043e\u043a\u0430\u044f \u0442\u043e\u0447\u043d\u043e\u0441\u0442\u044c \u0441 \u0445\u043e\u0440\u043e\u0448\u0435\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u044c\u044e.\r\n\r\n> \u26a0\ufe0f **\u0412\u0430\u0436\u043d\u043e:** SoundCloud \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430 Selenium! \u0414\u043b\u044f \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c Chrome \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0439 Chrome Driver.\r\n\r\n## \u041f\u0440\u0438\u043c\u0435\u0440\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f\r\n\r\n### \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 `Player` \u0438 `Queue`\r\n\r\n#### \u041f\u0440\u0438\u043c\u0435\u0440 1: \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0442\u0440\u0435\u043a\u0430\r\n\r\n```python\r\nimport disnake\r\nfrom disnake.ext import commands\r\nfrom dsplayer import Player, PluginLoader, YTMusicSearchEngine\r\n\r\nintents = disnake.Intents.all()\r\nbot = commands.Bot(command_prefix='!', intents=intents)\r\nplayers = {}\r\n\r\n@bot.command()\r\nasync def play(ctx, url):\r\n    \"\"\"\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u0442\u0440\u0435\u043a \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0438 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0435\u0433\u043e.\"\"\"\r\n    if ctx.guild.id in players:\r\n        player = players[ctx.guild.id]\r\n    else:\r\n        if ctx.author.voice:\r\n            voice_channel = ctx.author.voice.channel\r\n            player = Player(\r\n                voice_channel=voice_channel,\r\n                bot=bot,\r\n                plugin_loader=PluginLoader(),\r\n                engine=YTMusicSearchEngine,\r\n                debug=True\r\n            )\r\n            players[ctx.guild.id] = player\r\n            await player.connect()\r\n        else:\r\n            await ctx.send('\u0412\u044b \u043d\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u043a \u0433\u043e\u043b\u043e\u0441\u043e\u0432\u043e\u043c\u0443 \u043a\u0430\u043d\u0430\u043b\u0443.')\r\n            return\r\n\r\n    await player.play(url)\r\n    await ctx.send(f'\u0422\u0440\u0435\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0432 \u043e\u0447\u0435\u0440\u0435\u0434\u044c: {url}')\r\n\r\nbot.run('YOUR_BOT_TOKEN')\r\n```\r\n\r\n#### \u041f\u0440\u0438\u043c\u0435\u0440 2: \u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e\u0447\u0435\u0440\u0435\u0434\u044c\u044e \u0442\u0440\u0435\u043a\u043e\u0432\r\n\r\n```python\r\n@bot.command()\r\nasync def skip(ctx):\r\n    \"\"\"\u041f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0442\u0440\u0435\u043a.\"\"\"\r\n    if ctx.guild.id in players:\r\n        player = players[ctx.guild.id]\r\n        await player.skip()\r\n        await ctx.send('\u0418\u0433\u0440\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u0442\u0440\u0435\u043a.')\r\n    else:\r\n        await ctx.send(\"\u041d\u0435\u0442 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u043b\u0435\u0435\u0440\u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430.\")\r\n\r\n@bot.command()\r\nasync def previous(ctx):\r\n    \"\"\"\u0412\u0435\u0440\u043d\u0443\u0442\u044c\u0441\u044f \u043a \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0435\u043c\u0443 \u0442\u0440\u0435\u043a\u0443.\"\"\"\r\n    if ctx.guild.id in players:\r\n        player = players[ctx.guild.id]\r\n        await player.previous()\r\n        await ctx.send('\u0418\u0433\u0440\u0430\u0435\u0442 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u0442\u0440\u0435\u043a.')\r\n    else:\r\n        await ctx.send(\"\u041d\u0435\u0442 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u043b\u0435\u0435\u0440\u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430.\")\r\n\r\n@bot.command()\r\nasync def queue(ctx):\r\n    \"\"\"\u041f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0442\u0440\u0435\u043a\u043e\u0432.\"\"\"\r\n    if ctx.guild.id in players:\r\n        player = players[ctx.guild.id]\r\n        queue = player.queue.get_queue()\r\n        if queue:\r\n            queue_list = \"\\n\".join([f\"{idx + 1}. {track['url']}\" for idx, track in enumerate(queue)])\r\n            await ctx.send(f\"\u041e\u0447\u0435\u0440\u0435\u0434\u044c:\\n{queue_list}\")\r\n        else:\r\n            await ctx.send(\"\u041e\u0447\u0435\u0440\u0435\u0434\u044c \u043f\u0443\u0441\u0442\u0430.\")\r\n    else:\r\n        await ctx.send(\"\u041d\u0435\u0442 \u0430\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u043f\u043b\u0435\u0435\u0440\u0430 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u0430.\")\r\n\r\nbot.run('YOUR_BOT_TOKEN')\r\n```\r\n\r\n#### \u041f\u0440\u0438\u043c\u0435\u0440 3: \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439\r\n\r\n```python\r\nfrom dsplayer import event\r\n\r\n@event(\"on_play_track\")\r\nasync def on_play_track(event_data: dict):\r\n    \"\"\"\u041e\u0442\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0442\u0440\u0435\u043a\u0430.\"\"\"\r\n    track = event_data['track']\r\n    channel_id = event_data['text_id']\r\n    channel = bot.get_channel(channel_id)\r\n    await channel.send(f\"\u041d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0442\u0440\u0435\u043a\u0430: {track['title']}\")\r\n```\r\n\r\n## `PluginLoader`\r\n\r\n### 1. \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u0438\u0437 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u0438\r\n\r\n```python\r\nfrom dsplayer import PluginLoader\r\n\r\nplugins_list = [\"custom_plugins.plugins\"]\r\nloader = PluginLoader(plugins_list)\r\n```\r\n\r\n### 2. \u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043a\u043b\u0430\u0441\u0441 \r\n\r\n```python\r\nfrom dsplayer import PluginLoader, PluginInterface\r\n\r\nloader = PluginLoader()\r\nloader.load_plugins_from_classes(plugins_list)\r\n\r\nclass MyCustomPlugin1(PluginInterface):\r\n    # \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u0430\r\n    ...\r\n\r\nclass MyCustomPlugin2(PluginInterface):\r\n    # \u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u043f\u043b\u0430\u0433\u0438\u043d\u0430\r\n    ...\r\n\r\nplugins_list = [MyCustomPlugin1, MyCustomPlugin2]\r\n```\r\n\r\n> **\u041f\u0440\u0438\u043c\u0435\u0440 \u0431\u043e\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0432 [examples/example_bot.py](examples/example_bot.py)**\r\n\r\n## \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439\r\n\r\n`dsplayer` \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439, \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0449\u0443\u044e \u0433\u0438\u0431\u043a\u043e \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0438. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0438\u0437 \u043c\u043e\u0434\u0443\u043b\u044f `dsplayer.utils.exceptions.lib_exceptions`.\r\n\r\n### \u041e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f\r\n\r\n- **VoiceChaneNotConnected**  \r\n  \u0412\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442, \u0435\u0441\u043b\u0438 \u0431\u043e\u0442 \u043f\u044b\u0442\u0430\u0435\u0442\u0441\u044f \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0441\u0442\u0438 \u0442\u0440\u0435\u043a, \u043d\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0432\u0448\u0438\u0441\u044c \u043a \u0433\u043e\u043b\u043e\u0441\u043e\u0432\u043e\u043c\u0443 \u043a\u0430\u043d\u0430\u043b\u0443.\r\n\r\n- **TrackNotFound**  \r\n  \u0412\u043e\u0437\u043d\u0438\u043a\u0430\u0435\u0442, \u0435\u0441\u043b\u0438 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0442\u0440\u0435\u043a \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.\r\n\r\n- **TrackError**  \r\n  \u041e\u0431\u0449\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430, \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u0430\u044f \u0441 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u043c \u0442\u0440\u0435\u043a\u0430.\r\n\r\n### \u041f\u0440\u0438\u043c\u0435\u0440 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0438 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439\r\n\r\n```python\r\nfrom dsplayer.utils.exceptions.lib_exceptions import VoiceChaneNotConnected, TrackNotFound, TrackError\r\n\r\ntry:\r\n    # \u0412\u0430\u0448 \u043a\u043e\u0434\r\nexcept VoiceChaneNotConnected as e:\r\n    print(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f: {e}\")\r\nexcept TrackNotFound as e:\r\n    print(f\"\u0422\u0440\u0435\u043a \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d: {e}\")\r\nexcept TrackError as e:\r\n    print(f\"\u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u043a\u0430: {e}\")\r\n```\r\n\r\n### \u0421\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0439\r\n\r\n- **VoiceChaneError**  \r\n  - **VoiceChaneNotConnected**: \u0411\u043e\u0442 \u043d\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d \u043a \u0433\u043e\u043b\u043e\u0441\u043e\u0432\u043e\u043c\u0443 \u043a\u0430\u043d\u0430\u043b\u0443.\r\n  - **VoiceChaneNotFound**: \u0423\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0439 \u0433\u043e\u043b\u043e\u0441\u043e\u0432\u043e\u0439 \u043a\u0430\u043d\u0430\u043b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.\r\n  - **VoiceChaneNotPlaying**: \u0411\u043e\u0442 \u043d\u0435 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442 \u0442\u0440\u0435\u043a.\r\n\r\n- **ConnectionError**  \r\n  - \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435\u043c \u043a \u0433\u043e\u043b\u043e\u0441\u043e\u0432\u043e\u043c\u0443 \u043a\u0430\u043d\u0430\u043b\u0443.\r\n\r\n- **TrackError**  \r\n  - **TrackNotFound**: \u0422\u0440\u0435\u043a \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d.\r\n  - **TrackError**: \u041e\u0448\u0438\u0431\u043a\u0430 \u0432\u043e\u0441\u043f\u0440\u043e\u0438\u0437\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u0442\u0440\u0435\u043a\u0430.\r\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Music player for Discord",
    "version": "2.2.0",
    "project_urls": {
        "Homepage": "https://github.com/FlacSy/dsplayer"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "ccec05b96127957d9c26427c00e547725a811253208ff0ef0a0f9b69c898026f",
                "md5": "839b4383aad7fc59a9a7bcf6157fad3f",
                "sha256": "df70cf6bf05c4b579e244bb56115439f73ba30f9642d074feee8a68ea01c6d09"
            },
            "downloads": -1,
            "filename": "dsplayer-2.2.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "839b4383aad7fc59a9a7bcf6157fad3f",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10.0",
            "size": 55996,
            "upload_time": "2024-10-15T16:49:55",
            "upload_time_iso_8601": "2024-10-15T16:49:55.719268Z",
            "url": "https://files.pythonhosted.org/packages/cc/ec/05b96127957d9c26427c00e547725a811253208ff0ef0a0f9b69c898026f/dsplayer-2.2.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "3d1718234a29a607f76e35809cf0cb91932429d0dc2a3480cad3fbabc4fe74b9",
                "md5": "c8141a43e256b9ffd0e6c93b40452341",
                "sha256": "1239a4f3258e6b81cca0d8deab04f371fc7b9564f020e592cc0f23aa7e611933"
            },
            "downloads": -1,
            "filename": "dsplayer-2.2.0.tar.gz",
            "has_sig": false,
            "md5_digest": "c8141a43e256b9ffd0e6c93b40452341",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10.0",
            "size": 46662,
            "upload_time": "2024-10-15T16:49:57",
            "upload_time_iso_8601": "2024-10-15T16:49:57.386062Z",
            "url": "https://files.pythonhosted.org/packages/3d/17/18234a29a607f76e35809cf0cb91932429d0dc2a3480cad3fbabc4fe74b9/dsplayer-2.2.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-10-15 16:49:57",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "FlacSy",
    "github_project": "dsplayer",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": false,
    "requirements": [
        {
            "name": "requests",
            "specs": []
        },
        {
            "name": "bs4",
            "specs": []
        },
        {
            "name": "colorama",
            "specs": []
        },
        {
            "name": "selenium",
            "specs": []
        },
        {
            "name": "webdriver_manager",
            "specs": []
        },
        {
            "name": "yt-dlp",
            "specs": []
        },
        {
            "name": "PyNaCl",
            "specs": []
        }
    ],
    "lcname": "dsplayer"
}
        
Elapsed time: 0.33255s