Discord Musi c Ошибка бота discord.ext.commands.errors.CommandInvokeError: команда вызвала исключение: KeyError: 'videoId' - PullRequest
1 голос
/ 25 мая 2020

Я пытаюсь создать бота disord musi c и, используя API данных YouTube, я пытаюсь получить песню, просто набрав ее имя вместо URL-адреса, и у меня возникли некоторые интересные проблемы.

Функция выборки песен с использованием слов изначально работала с серьезным недостатком: она могла принимать сообщения только с одним словом. Вот код для всей последовательности, которая сработала.

@client.command(pass_context = True, aliases = ['p'])
async def play(ctx, song_name: str):
    song_pack = rq.get("https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q={}&key={}".format(final_song_name, YOUTUBE_API)).json()
    song_url = "https://www.youtube.com/watch?v={}".format(song_pack['items'][0]['id']['videoId'])

    def check_queue():
        Queue_infile = os.path.isdir("./Queue")
        if Queue_infile is True:
            DIR = os.path.abspath(os.path.realpath("Queue"))
            length = len(os.listdir(DIR))
            still_q = length - 1

            try:
                first_file = os.listdir(DIR)[0]
            except:
                print("No more queued song(s)\n")
                queues.clear()
                return

            main_location = os.path.dirname(os.path.realpath(__file__))
            song_path = os.path.abspath(os.path.realpath("Queue") + "\\" + first_file)

            if length != 0:
                print("Song done, playing next queued\n")
                print(f"Songs still in queue: {still_q}")
                song_there = os.path.isfile("song.mp3")

                if song_there:
                    os.remove("song.mp3")
                shutil.move(song_path, main_location)

                for file in os.listdir("./"):
                    if file.endswith("mp3"):
                        os.rename(file, 'song.mp3')

                voice.play(discord.FFmpegPCMAudio("song.mp3"), after = lambda e: check_queue())
                voice.source = discord.PCMVolumeTransformer(voice.source)
                voice.source.volume = 0.7

            else:
                queues.clear()
                return

        else:
            queues.clear()
            print("No songs were queued before the ending of the last song\n")

    song_there = os.path.isfile("song.mp3")
    try:
        if song_there:
            os.remove("song.mp3")
            queues.clear()
            print('Removed old song file')
    except PermissionError:
        print("Trying to delete song file, but, it is being played.")
        await ctx.send("ERROR: Music Playing")
        return


    Queue_infile = os.path.isdir("./Queue")
    try:
        Queue_folder = "./Queue"
        if Queue_infile is True:
            print("Removed old Queue folder")
            shutil.rmtree(Queue_folder)
    except:
        print("No old queue folder")

    await ctx.send("**Searching for** `{}` :mag_right:".format(song_name))

    voice = get(client.voice_clients, guild = ctx.guild)

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

    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
        print("Downloading audio now\n")
        ydl.download([song_url])

    for file in os.listdir("./"):
        if file.endswith(".mp3"):
            name = file
            print(f"Renamed File: {file}\n")
            os.rename(file, "song.mp3")

    voice.play(discord.FFmpegPCMAudio("song.mp3"), after = lambda e: check_queue())
    voice.source = discord.PCMVolumeTransformer(voice.source)
    voice.source.volume = 0.7

    nname = name[:-16]
    await ctx.send(f"**Playing** :musical_note: : `{nname}`")
    print("Playing\n")

Но когда я пытаюсь исправить ошибку, просто добавляя это в 4-ю строку с правильным отступом

    final_song_name = song_name.replace(" ", "_")

, я получаю Ошибка.

Вот пример JSON из API YouTube.

{
  "kind": "youtube#searchListResponse",
  "etag": "OvvXoVaLuxf9xsl2hEiI-iG1Hs4",
  "nextPageToken": "CAEQAA",
  "regionCode": "IN",
  "pageInfo": {
    "totalResults": 3994,
    "resultsPerPage": 1
  },
  "items": [
    {
      "kind": "youtube#searchResult",
      "etag": "6ooIFJrvuNFu7tLWPM_CbRXyp4s",
      "id": {
        "kind": "youtube#video",
        "videoId": "TfdHSJxVPCk"
      },
      "snippet": {
        "publishedAt": "2013-02-05T00:17:42Z",
        "channelId": "UCJLX0B8m1KrS6oe3xageAbQ",
        "title": "Archie - Famous (Original Mix) [Monstercat Release]",
        "description": "Archie - Famous (Original Mix) [Monstercat Release] Hope you enjoy & don't forget to subscribe! :D.",
        "thumbnails": {
          "default": {
            "url": "https://i.ytimg.com/vi/TfdHSJxVPCk/default.jpg",
            "width": 120,
            "height": 90
          },
          "medium": {
            "url": "https://i.ytimg.com/vi/TfdHSJxVPCk/mqdefault.jpg",
            "width": 320,
            "height": 180
          },
          "high": {
            "url": "https://i.ytimg.com/vi/TfdHSJxVPCk/hqdefault.jpg",
            "width": 480,
            "height": 360
          }
        },
        "channelTitle": "Domsn House",
        "liveBroadcastContent": "none",
        "publishTime": "2013-02-05T00:17:42Z"
      }
    }
  ]
}

Думаю, что я сделал правильно. Я даже создал новую программу со следующим кодом

song_name = str(input('Enter Song Name:'))
final_song_name = song_name.replace(" ", "_")
song_pack = rq.get("https://www.googleapis.com/youtube/v3/search?part=snippet&maxResults=1&q={}&key={}".format(final_song_name, YOUTUBE_API)).json()
song_url = "https://www.youtube.com/watch?v={}".format(song_pack['items'][0]['id']['videoId'])
print(song_url)

И она работала нормально, получая мне URL-адрес после ввода большого количества слов. Это один из моих первых вопросов. Извините за мою некомпетентность или (ожидаемую) глупость.

Также rq = запрашивает модуль

...