wavelink

repository·main·Indexed 19 days ago

https://github.com/pythonistaguild/wavelink

A robust, fully asynchronous Lavalink wrapper for discord.py (v2.0.0+) and Lavalink v4+. It provides an object-oriented API for managing music playback in Discord bots, featuring support for AutoPlay, track recommendations, audio filters, and plugins like LavaSrc for Spotify and SponsorBlock. Requires Python 3.10+.

Tokens
16.2K
Snippets
59
Records
84
Agent score
61%

What's inside wavelink

  1. Overview of Wavelink

    main

    Wavelink is a fully asynchronous Python Lavalink wrapper designed specifically for use with discord.py. It provides an object-oriented interface for interacting with Lavalink nodes using stateful objects and payloads.

    Key Features:

    • Asynchronous Design: Built for high-concurrency environments.
    • Lavalink v4+ Support: Utilizes the Lavalink REST API.
    • discord.py v2.0.0+ Support: Compatible with modern discord.py versions.
    • Advanced Audio Features: Includes AutoPlay and track recommendations for continuous playback.
    • Type Safety: Fully annotated and complies with Pyright strict typing.
  2. Lavalink Requirements and Plugin Support

    main

    Wavelink 3 is designed to work with Lavalink v4+.

    Plugin Support

    Wavelink has built-in support for Lavalink plugins.

    • Spotify Support: To enable Spotify support, install and use the LavaSrc plugin with your wavelink.Playable objects.
    • SponsorBlock: Built-in support is available for the SponsorBlock plugin.
  3. Configure AutoPlay modes

    main

    Wavelink v3 features an optimized AutoPlay system. You can set the wavelink.Player.autoplay attribute to one of the following wavelink.AutoPlayMode values:

    • wavelink.AutoPlayMode.enabled: Fetches and recommends tracks based on listening history (supports Spotify, YouTube, and YouTube Music). It handles looping and prioritizes the Queue over the AutoQueue.
    • wavelink.AutoPlayMode.partial: Automatically plays the next track in the queue but does not fetch or recommend new tracks for the future. It handles looping.
    • wavelink.AutoPlayMode.disabled: Stops automatic playing. You must manually handle track transitions using the wavelink.on_wavelink_track_end event.
  4. Configure Queue modes in Wavelink v3

    main

    In version 3, wavelink.Queue introduced a mode attribute that determines how the queue behaves when tracks are exhausted. You can set the mode using wavelink.QueueMode.

    Available modes:

    • wavelink.QueueMode.normal: The queue will not loop.
    • wavelink.QueueMode.loop_all: Every song in the history will loop once the queue is exhausted.
    • wavelink.QueueMode.loop: The current track will loop continuously until it is turned off or skipped using wavelink.Player.skip(force=True).
    import wavelink
    
    # Example of setting a queue mode
    await queue.set_mode(wavelink.QueueMode.loop_all)
  5. Handle WaveLink Events with discord.py listeners

    main

    WaveLink events are dispatched via discord.py and must be implemented as coroutines. You can use the standard @commands.Cog.listener() syntax to respond to events.

    Common event patterns include:

    • Node Lifecycle: on_wavelink_node_ready (initial connection/reconnection), on_wavelink_node_disconnected (lost connection), and on_wavelink_node_closed (node cleaned up).
    • Playback Lifecycle: on_wavelink_track_start (preferred for feedback), on_wavelink_track_end (note: if using AutoPlay, use on_wavelink_track_start for logic instead), on_wavelink_track_exception, and on_wavelink_track_stuck.
    • Player/Voice Lifecycle: on_wavelink_player_update, on_wavelink_websocket_closed, and on_wavelink_inactive_player (triggered when Player.inactive_timeout expires).
    • System/Plugin Events: on_wavelink_stats_update and on_wavelink_extra_event (for custom Lavalink plugin data like SponsorBlock).
    @commands.Cog.listener()
    async def on_wavelink_node_ready(self, payload: wavelink.NodeReadyEventPayload) -> None:
        print(f"Node {payload.node!r} is ready!")
  6. Migrate from Wavelink v2 to v3

    main

    Wavelink version 3 introduces several breaking changes and improvements over version 2:

    Key Requirements & Changes

    • Lavalink Version: Version 3 requires Lavalink v4+.
    • Track Types: Specific track classes (e.g., YouTubeTrack, SoundCloudTrack) have been removed. All tracks now use the unified wavelink.Playable class.
    • Spotify Support: The standalone Spotify Extension is removed. Use native support via the LavaSrc plugin.
    • Naming Changes:
      • wavelink.Node.id $\rightarrow$ wavelink.Node.identifier
      • wavelink.NodePool $\rightarrow$ wavelink.Pool
      • wavelink.Player.current_node $\rightarrow$ wavelink.Player.node
      • wavelink.Player.is_connected() $\rightarrow$ wavelink.Player.connected (attribute)
      • wavelink.Player.is_paused() $\rightarrow$ wavelink.Player.paused (attribute)
      • wavelink.Player.is_playing() $\rightarrow$ wavelink.Player.playing (attribute)
      • wavelink.Player.stop() $\rightarrow$ wavelink.Player.skip() (alias exists)

    API Behavior Changes

    • Searching: Playlists can no longer be used as search queries. wavelink.Playable.search returns a wavelink.Search object (which is a list of Playable or a Playlist).
    • Pausing: Logic for resuming has moved to wavelink.Player.pause(bool). To toggle, use await player.pause(not player.paused).
    • Queue: wavelink.Queue.put_wait and put now return an int representing the number of tracks added.
  7. Connect to Lavalink nodes using wavelink.Pool

    main

    It is recommended to use the discord.py setup_hook to connect your nodes. Use wavelink.Pool.connect to establish the connection.

    Note on Experimental Cache: The cache_capacity parameter is experimental. To disable it, pass None.

    async def setup_hook(self) -> None:
        nodes = [wavelink.Node(uri="...", password="...")]
    
        # cache_capacity is EXPERIMENTAL. Turn it off by passing None
        await wavelink.Pool.connect(nodes=nodes, client=self, cache_capacity=100)
  8. Use and manipulate audio filters

    main

    Wavelink v3 uses the wavelink.Filters class to manage audio effects. You can apply filters to a player using player.set_filters(filters) or reset them using player.set_filters() with no arguments.

    Common Operations:

    • Create and apply new filters: Create a wavelink.Filters() instance and pass it to player.set_filters().
    • Retrieve current filter payload: Access player.filters and call it as a function to get the payload.
    • Modify specific filters: Use .set() on individual filter components (like timescale, rotation, or equalizer) and then call await player.set_filters(filters) to apply changes.
    • Reset individual filters: Use .reset() on a specific filter component.
    • Reset all filters: Use .reset() on the main Filters instance.
    • Quick reset: Call await player.set_filters() to clear all filters from the player.
    import wavelink
    
    # Create and apply brand new filters
    filters: wavelink.Filters = wavelink.Filters()
    await player.set_filters(filters)
    
    # Modify specific filters (e.g., timescale and rotation)
    filters: wavelink.Filters = player.filters
    filters.timescale.set(pitch=1.2, speed=1.1, rate=1)
    filters.rotation.set(rotation_hz=0.2)
    filters.equalizer.reset()
    await player.set_filters(filters)
    
    # Reset a single filter
    filters: wavelink.Filters = player.filters
    filters.timescale.reset()
    await player.set_filters(filters)
    
    # Reset all filters
    filters: wavelink.Filters = player.filters
    filters.reset()
    await player.set_filters(filters)
    
    # Quick method to reset and apply filters
    await player.set_filters()
  9. Install Wavelink

    main

    Wavelink 3 requires Python 3.10+. Use the following commands depending on your operating system and environment to install or upgrade the package.

    Windows

    py -3.10 -m pip install -U wavelink

    Linux

    python3.10 -m pip install -U wavelink

    Virtual Environments

    pip install -U wavelink
    pip install -U wavelink
  10. Understand the loaded track and looping

    main

    The loaded property represents the track that is currently being played or is ready to repeat when the queue is in QueueMode.loop.

    • Accessing: queue.loaded returns the current Playable or None.
    • Looping: If mode is set to QueueMode.loop, calling queue.get() will return this loaded track instead of the next item in the queue.
    • Updating: Setting queue.loaded = new_track replaces the current track without adding it to the queue or history. This is useful for manual track overrides.
    # Check what is currently loaded
    print(queue.loaded)
    
    # Manually set a loaded track
    queue.loaded = track
  11. Configure QueueMode

    main

    The mode property of the Queue determines how tracks are retrieved and how looping behaves. You can set this property using any value from the wavelink.QueueMode enum.

    • When mode is QueueMode.loop, get() returns the loaded track (the one currently playing) to facilitate repetition.
    • When mode is QueueMode.loop_all, the queue will pull from history when the main queue is empty.