Nextcord bot MusicCog shows playback message but fails to produce audio from Spotify

I’m developing a Discord bot using Nextcord, aiming to incorporate music playback via the Spotipy library. When I execute the command !play ..., the bot joins the voice channel correctly and displays the message “Now playing: …”, but there’s no sound coming from the audio.

I’ve ensured that the bot has all the necessary permissions, including the Administrator role, and my Spotify API credentials seem to be in order. The problem appears to be with the audio playback mechanism itself.

Here are the key pieces of my code:

main.py:

import nextcord, os, config
from nextcord.ext import commands

intents = nextcord.Intents.default()
intents.message_content = True

bot = commands.Bot(command_prefix='!', intents=intents)

@bot.event
async def on_ready():
    print(f'Logged in as {bot.user.name}')

for file in os.listdir('./cogs'):
    if file.endswith('.py'):
        bot.load_extension(f'cogs.{file[:-3]}')

bot.run(config.TOKEN)

music.py Cog:

import nextcord
from nextcord.ext import commands
import spotipy
from spotipy.oauth2 import SpotifyClientCredentials

class Music(commands.Cog):
    def __init__(self, bot):
        self.bot = bot
        self.voice = None
        self.sp = spotipy.Spotify(auth_manager=SpotifyClientCredentials(
            client_id='my_client_id',
            client_secret='my_client_secret'
        ))

    @commands.command()
    async def join(self, ctx):
        if ctx.author.voice:
            self.voice = await ctx.author.voice.channel.connect()
            await ctx.send(f'Joined {ctx.author.voice.channel.name}')
        else:
            await ctx.send('You must be in a voice channel.')

    @commands.command()
    async def play(self, ctx, *, query: str):
        if not self.voice or not self.voice.is_connected():
            await ctx.send('Bot needs to join a voice channel first. Use `!join`.')
            return

        try:
            track_info = self.sp.search(q=query, type='track', limit=1)

            if not track_info or not track_info['tracks']['items']:
                await ctx.send('Could not find any matching tracks.')
                return

            track = track_info['tracks']['items'][0]
            track_url = track['external_urls']['spotify']

            source = await nextcord.FFmpegOpusAudio.from_probe(track_url)
            self.voice.play(source)

            await ctx.send(f'Now playing: {track['name']} by {', '.join(artist['name'] for artist in track['artists'])}')
        except Exception as e:
            await ctx.send(f'Error during track playback: {e}')

def setup(bot):
    bot.add_cog(Music(bot))
    print('MusicCog loaded successfully')

I’ve also tried reaching out for assistance, but none of the suggestions have worked. Can anyone help resolve this issue?

spotify doesn’t allow direct streaming. u need youtube-dl or yt-dlp to get the actual audio files. most music bots use youtube for this. also check that ffmpeg is set up right on ur system.

The issue likely stems from the fact that Spotify’s API only provides metadata and short previews, rather than direct audio streams. When you attempt to use a Spotify URL with FFmpeg, it fails because that URL merely leads to their web player and not an actual audio file.

A common workaround among Discord bots is to search for the same track on YouTube. YouTube offers audio streams that FFmpeg can handle. Consider implementing a search functionality that retrieves the relevant YouTube video based on the Spotify track information, and then use a tool like yt-dlp to fetch the accessible audio URL for FFmpeg to use. Although this solution requires additional work and dependencies, it is a standard approach to overcome this limitation.