向Discord的MusicBot添加新命令


不和谐,这就是我在玩游戏时经常说的话。

不久前,一个在通话中播放音乐的机器人被称为MusicBot,这种机器人很流行,但是最近我放进去并设法用我从未接触过的Python来实现,因为我还想要一个附加的命令。能够移动它,所以我会留下纸条。

注意(附加说明17/12/17)

apl all在此处用作获取播放列表的命令,但如果播放列表包含艺术家的官方PV(尤其是西方音乐),则会陷入DL预防或该保护功能。引发错误并重新启动BOT。
我会在业余时间尝试在该区域中添加错误处理,但是请注意,暂时在此处发布的程序中会发生错误。

环境

Raspberry pi3和OS X
Python3.5.3
MusicBot

推出

简介文章相对较新,并且已经有详细的文章,因此在这里
在Mac上引入带有Discord的音乐机器人

对于Raspberry pi,最好遵循官方文档(仅使用简单的英语)
Raspbian指南(官方指南)

导入注意事项

如果您遵循并遵循OSX上的MusicBot官方信息,则可以使用,但是如果您查看其他站点上的旧信息等,则Python版本可能与MusicBot期望的版本有所不同。
具体来说,当DL结束并且最后一个MusicBot启动时,

1
2
./update_macdeps.command
./runbot_mac.command

执行

,但那时runbot_mac.command中描述的Python版本可能较旧。
将其重命名为runbot_mac.txt等一次,根据您的Python版本在最后一行更改python *。* Run.py,然后再次将其重命名为runbot_mac.command并执行它(强制执行。您不必使用command ,但暂时是...)

1
2
3
4
5
6
7
8
#!/bin/bash

cd "$(dirname "$BASH_SOURCE")" || {
    echo "Python 3.5 doesn't seem to be installed" >&2
exit 1
}

python3.5 run.py

如何添加MusicBot命令

首先,我这次添加的命令是使您能够操作自动播放列表的命令。
如果多个人每次都使用play命令会很麻烦,即使您共享youtube的播放列表并在不一致的情况下播放它,也无法播放Nico Nico视频的声音。
因此,这是一种让所有人都使用autoplaylist.txt播放音乐的方法,以便所有人添加的歌曲将继续自动播放。
具体来说,请在MusicBot / musicbot /下修改.py源代码。
musicbot /下的bot.py是主要源代码,每个命令都是以cmd_开头的函数,可以通过根据格式添加一个函数来实现。

如果函数名称为cmd_apl,则该函数将被调用!
顺便说一句,apl现在甚至可以显示!帮助
スクリーンショット 2017-11-11 11.54.59.png

bot.py

1
2
3
4
5
6
7
8
9
10
11
    #Discordで!aplと実行するとBotが "テスト" と発言する
    async def cmd_apl(self, player, channel, author, option, MES=None):

        """
        Usage:
            {command_prefix}apl [ + | - | add | remove | all] URL

            URLを指定してオートプレイリストに追加、消去、一覧表示ができます
        """

        return Response("テスト",reply=True, delete_after=10)

自从我第一次接触Python以来,我基本上在查看其他功能(例如!黑名单和!帮助)时发出了原始命令,但是我设法完成了它。
我认为没有需求,但我暂时将其发布,因为我优先考虑运动,因此可能会有无用的变量和书写方式,但请通过。

bot.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
    async def cmd_apl(self, player, channel, author, option, MES=None):

        """
        Usage:
            {command_prefix}apl [ + | - | add | remove | all] URL

            URLを指定してオートプレイリストに追加、消去、一覧表示ができます
        """

        if option not in ['+', '-', 'add', 'remove','all']:
            raise exceptions.CommandError(
                '"%s" は無効なオプションです, +, -, add, remove, all を利用して' % option, expire_in=20
            )

        old_len = len(self.blacklist)

        if option in ['+', 'add']:

            if not MES:
                return Response('URLがないお',reply=True, delete_after=10)  
            if MES in self.autoplaylist:
                return Response('もう既にあります', reply=True, delete_after=10)

            self.autoplaylist.append(MES)

            write_file(self.config.auto_playlist_file, self.autoplaylist)

            try:
                entry, position = await player.playlist.add_entry(MES, channel=channel, author=author)
            except exceptions.WrongEntryTypeError as e:
                return await self.cmd_play(player, channel, author, permissions, leftover_args, e.use_url)

            return Response(
            '%s をプレイリストに曲を追加しました'%entry.title,
            reply=True, delete_after=10
            )


        elif option in ['-', 'remove']:

            if not MES:
                return Response('URLがありません',reply=True, delete_after=10)
            if MES not in self.autoplaylist:
                return Response('存在しません', reply=True, delete_after=10)

            self.autoplaylist.remove(MES)
            write_file(self.config.auto_playlist_file, self.autoplaylist)

            try:
                entry, position = await player.playlist.add_entry(MES, channel=channel, author=author)
            except exceptions.WrongEntryTypeError as e:
                return await self.cmd_play(player, channel, author, permissions, leftover_args, e.use_url)

            return Response(
                'プレイリストから %s を消去しました'%entry.title,
                reply=True, delete_after=10
            )

        elif option in ['all']:
            APList = "```"
            for url in self.autoplaylist:
                try:
                    entry = await player.playlist.getEntry(url, channel=channel, author=author)
                except exceptions.WrongEntryTypeError as e:
                    return await self.cmd_play(player, channel, author, permissions, leftover_args, e.use_url)

                APList += '?' + entry.title + '\n  ' + url + '\n'

            APList += "```"

            return Response(
                    APList,
                    reply=True, delete_after=10
                )

playlist.py

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
async def getEntry(self, song_url, **meta):
        """
            Validates and adds a song_url to be played. This does not start the download of the song.

            Returns the entry & the position it is in the queue.

            :param song_url: The song url to add to the playlist.
            :param meta: Any additional metadata to add to the playlist entry.
        """

        try:
            info = await self.downloader.extract_info(self.loop, song_url, download=False)
        except Exception as e:
            raise ExtractionError('Could not extract information from {}\n\n{}'.format(song_url, e))

        if not info:
            raise ExtractionError('Could not extract information from %s' % song_url)

        # TODO: Sort out what happens next when this happens
        if info.get('_type', None) == 'playlist':
            raise WrongEntryTypeError("This is a playlist.", True, info.get('webpage_url', None) or info.get('url', None))

        if info['extractor'] in ['generic', 'Dropbox']:
            try:
                # unfortunately this is literally broken
                # https://github.com/KeepSafe/aiohttp/issues/758
                # https://github.com/KeepSafe/aiohttp/issues/852
                content_type = await get_header(self.bot.aiosession, info['url'], 'CONTENT-TYPE')
                print("Got content type", content_type)

            except Exception as e:
                print("[Warning] Failed to get content type for url %s (%s)" % (song_url, e))
                content_type = None

            if content_type:
                if content_type.startswith(('application/', 'image/')):
                    if '/ogg' not in content_type:  # How does a server say `application/ogg` what the actual fuck
                        raise ExtractionError("Invalid content type "%s" for url %s" % (content_type, song_url))

                elif not content_type.startswith(('audio/', 'video/')):
                    print("[Warning] Questionable content type "%s" for url %s" % (content_type, song_url))

        entry = URLPlaylistEntry(
            self,
            song_url,
            info.get('title', 'Untitled'),
            info.get('duration', 0) or 0,
            self.downloader.ytdl.prepare_filename(info),
            **meta
        )
        return entry

!apl all是列出当前注册的autoplaylist.txt的URL和标题的命令。

执行的屏幕
スクリーンショット 2017-11-11 11.53.10.png

结束