SamelCamel
SamelCamel

Reputation: 77

discord.py and youtube_dl, "Read error" and "The session has been invalidated for some reason"

I have been running into this issue with discord.py and youtube_dl where playing YouTube links in a queue gives me an error that seems to "snowball" into the other songs in the queue. The first song usually plays just fine, but then the rest of the songs give this error after a very short period of time. This is the error:

[tls @ 000001e5618bc200] Error in the pull function.
[matroska,webm @ 000001e5613f9740] Read error
[tls @ 000001e5618bc200] The specified session has been invalidated for some reason.
Last message repeated 1 times
[really long link] I/O error

And this is my code for the YTDL source and the queue function:

class YTDLSource(discord.PCMVolumeTransformer):
    def __init__(self, source, *, data, volume=0.5):
        super().__init__(source, volume)

        self.data = data

        self.title = data.get('title')
        self.url = data.get('url')

    @classmethod
    async def from_url(cls, url, *, loop=None, stream=False):
        loop = loop or asyncio.get_event_loop()
        data = await loop.run_in_executor(None, lambda: ytdl.extract_info(url, download=not stream))

        if 'entries' in data:
            # take first item from a playlist
            data = data['entries'][0]

        filename = data['url'] if stream else ytdl.prepare_filename(data)
        return cls(discord.FFmpegPCMAudio(filename, **ffmpeg_options), data=data)



queues = {}

class Music(commands.Cog):
    def __init__(self, bot):
        self.bot = bot

    @commands.command()
    async def q(self, ctx, *, url):
        channel = discord.utils.get(ctx.guild.voice_channels, name="Melodies of Arts")

        if ctx.voice_client is None:
            await channel.connect()


        def check_queue(error):
            if(queues[ctx.guild.id] != []):
                player = queues[ctx.guild.id].pop(0)
                ctx.voice_client.play(player, after=check_queue)     

        async with ctx.typing():
            player = await YTDLSource.from_url(url, loop=self.bot.loop, stream=True)

            if ctx.guild.id in queues:
                queues[ctx.guild.id].append(player)
            else:
                queues[ctx.guild.id] = [player]

            await ctx.send("Video __" + str(player.title) + "__" + " queued at **Position #" + str(len(queues[ctx.guild.id])) + "**", delete_after=15)

            if(not ctx.voice_client.is_playing()):
                ctx.voice_client.play(player, after=check_queue)
                await ctx.send('***Now playing:*** __{}__'.format(player.title), delete_after=10)

A Github issue page recommended to "redownload the url", but I am streaming the the link using youtube_dl, and I would like to avoid downloading the video if possible. A lot of the Github issues seem to be too outdated anyway, so any solutions relating to code do not work anymore. If I need to provide more code/information let me know!

Upvotes: 2

Views: 4238

Answers (2)

Lemon
Lemon

Reputation: 11

To ensure this doesn't happen add this in the ffmpeg options :

'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5'

This will make it reconnect and the music won't stop.

Upvotes: 1

Charles Merriam
Charles Merriam

Reputation: 20510

As people like to say, "It's really not your fault". This usually happens from the YouTube side.

Take a look at: Python Youtube ffmpeg Session Has Been Invalidated

Also, check that you called using https. YouTube no longer accepts http connections.

Upvotes: 3

Related Questions