首页 > 解决方案 > 如何修复 RuntimeError:使用语音需要 PyNaCl 库?

问题描述

昨天我开始使用 discord.py 和 youtube_dl 库编写一个不和谐的机器人。

使用命令“>播放”控制台显示错误:

Ignoring exception in command play:
Traceback (most recent call last):
  File "C:\Users\goblin\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 167, in wrapped
    ret = await coro(*args, **kwargs)
  File "c:\ECHObot\TEST-1\ECHO.py", line 57, in play
    await voice_channel.connect()
  File "C:\Users\goblin\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\abc.py", line 1672, in connect
    voice = cls(client, self)
  File "C:\Users\goblin\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\voice_client.py", line 232, in __init__
    raise RuntimeError("PyNaCl library needed in order to use voice")
RuntimeError: PyNaCl library needed in order to use voice

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "C:\Users\goblin\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\bot.py", line 994, in invoke
    await ctx.command.invoke(ctx)
  File "C:\Users\goblin\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 894, in invoke
    await injected(*ctx.args, **ctx.kwargs)
  File "C:\Users\goblin\AppData\Local\Programs\Python\Python39\lib\site-packages\discord\ext\commands\core.py", line 176, in wrapped
    raise CommandInvokeError(exc) from exc
discord.ext.commands.errors.CommandInvokeError: Command raised an exception: RuntimeError: PyNaCl library needed in order to use voice

代码:

import discord
from discord.channel import VoiceChannel
from discord.ext import commands
import youtube_dl
import os
from config import token

bot = commands.Bot(command_prefix='>')

@bot.event
async def on_ready():
    print('ECHO READY')

server, server_id, name_channel = None, None, None

domains = ['https://www.youtube.com/', 'http://www.youtube.com/', 'https://youtu.be/', 'http://youtu.be/']
async def check_domains(link):
    for x in domains:
        if link.startswith(x):
            return True
    return False

@bot.command()
async def play(ctx, *, command = None):
    global server, server_id, name_channel
    author = ctx.author
    if command == None:
        server = ctx.guild
        name_channel = author.voice.channel.name
        voice_channel = discord.utils.get(server.voice_channels, name = name_channel)
    results = command.split(' ')
    if len(results) == 1:
        source = results[0]
        server = ctx.guild
        name_channel = author.voice.channel.name
        voice_channel = discord.utils.get(server.voice_channels, name = name_channel)
        print('result 1')
    elif len(results) ==3:
        server_id = results[0]
        voice_id = results[1]
        source = results[2]
        try:
            server_id = int(server_id)
            voice_id = int(voice_id)
        except:
            await ctx.channel.send(f'{author.mention}, пиздос')
            return
        print('result 3')
        server = bot.get_guild(server_id)
        voice_channel = discord.utils.get(server.voice_channels, id = voice_id)
    else:
        await ctx.channel.send(f'{author.mention}, пиздос 2')
        return

    voice = discord.utils.get(bot.voice_clients, guild = server)
    if voice is None:
        await voice_channel.connect()
        voice = discord.utils.get(bot.voice_clients, guild = server)

    if source == None:
        pass
    elif source.startswitch('http'):
        if not check_domains(source):
            await ctx.channel.send(f'{author.mention}, пиздос 3')
            return

        song_there = os.path.isfile('music/song.mp3')
        try:
            if song_there:
                os.remove('music/song.mp3')
        except PermissionError:
            await ctx.channel.send('пиздос 2.5')
            return

        ydl_os = {
            'format': 'bestaudio/best',
            'postprocessors': [
                {
                    'key': 'FFmpegExtractAudio',
                    'preferredcodec': 'mp3',
                    'preferredquality': '192',
                }
            ],

        }

        with youtube_dl.YoutubeDL(ydl_os) as ydl:
            ydl.download([source])
        for file in os.listdir('music/'):
            if file.endswith('.mp3'):
                os.rename(file, 'music/song.mp3')
        voice.play(discord.FFmpegAudio('song.mp3'))
    else:
        voice.play(discord.FFmpegAudio(f'music/{source}'))


bot.run(token)

我不知道该尝试什么了,我的代码中没有看到任何错误,虽然它引用了第 57 行。但是他在其他地方写了一堆错误。

标签: pythondiscord

解决方案


  1. 安装和导入 PyNaCl
  2. 它应该是startswith而不是startswitch
  3. FFmpegPCMAudio 代替 FFmpegAudio
  4. 安装 ffprobe/avprobe 或 ffmpeg/avconv

推荐阅读