回答編集履歴
10
    
        answer	
    CHANGED
    
    | @@ -10,7 +10,7 @@ | |
| 10 10 | 
             
                    after=lambda _: loop.create_task(play_song(message))
         | 
| 11 11 | 
             
                )
         | 
| 12 12 | 
             
            ```
         | 
| 13 | 
            -
            ※なお、自分の環境ではytdlをインストールせず | 
| 13 | 
            +
            ※なお、自分の環境ではytdlをインストールせずダミーファイルの再生処理で動作するかどうかしか試していません。
         | 
| 14 14 | 
             
            したがってytdlに起因するエラーは対処いたしかねます。
         | 
| 15 15 |  | 
| 16 16 | 
             
            ---
         | 
9
    
        answer	
    CHANGED
    
    | @@ -1,4 +1,4 @@ | |
| 1 | 
            -
            記載の通りasyncio.Queue() で対応でると思います。
         | 
| 1 | 
            +
            記載の通りasyncio.Queue() で対応できると思います。
         | 
| 2 2 | 
             
            「再生が終わったら、次の曲」という動作は、play 関数 の after 引数に、終わった後に実行する関数を指定することで一応実現できるはずです。
         | 
| 3 3 |  | 
| 4 4 | 
             
            ただし今回は実行対象がコルーチンなので少し工夫が必要です。
         | 
8
    
        answer	
    CHANGED
    
    | @@ -1,5 +1,5 @@ | |
| 1 | 
            -
            記載の通りasyncio.Queue() で対応で | 
| 1 | 
            +
            記載の通りasyncio.Queue() で対応でると思います。
         | 
| 2 | 
            -
            「再生が終わったら、次の曲」という動作は、play 関数 の after 引数に、終わった後に実行する関数を指定することで一応実現でき | 
| 2 | 
            +
            「再生が終わったら、次の曲」という動作は、play 関数 の after 引数に、終わった後に実行する関数を指定することで一応実現できるはずです。
         | 
| 3 3 |  | 
| 4 4 | 
             
            ただし今回は実行対象がコルーチンなので少し工夫が必要です。
         | 
| 5 5 | 
             
            (lambda と Eventloop.create_task() を使う。↓の部分です)
         | 
| @@ -10,6 +10,8 @@ | |
| 10 10 | 
             
                    after=lambda _: loop.create_task(play_song(message))
         | 
| 11 11 | 
             
                )
         | 
| 12 12 | 
             
            ```
         | 
| 13 | 
            +
            ※なお、自分の環境ではytdlをインストールせず、ローカルの再生処理でキューのやりとりができるかしか試していません。
         | 
| 14 | 
            +
            したがってytdlに起因するエラーは対処いたしかねます。
         | 
| 13 15 |  | 
| 14 16 | 
             
            ---
         | 
| 15 17 | 
             
            <コード>
         | 
7
    
        answer	
    CHANGED
    
    | @@ -14,12 +14,7 @@ | |
| 14 14 | 
             
            ---
         | 
| 15 15 | 
             
            <コード>
         | 
| 16 16 |  | 
| 17 | 
            -
            ※下記は一応動作はしますがコンセプトであって完璧なものではないことにご注意ください。
         | 
| 18 | 
            -
            再生中のキュー処理や停止時のエラー処理の面で、厳密に考慮すべき点をすっ飛ばしてますので、使ってるうちにどこかでエラーが発生して強制停止する可能性がゼロではありません。
         | 
| 19 | 
            -
             | 
| 20 | 
            -
            安定した高機能なものを作ろうとする場合、discord.py の内部構造や python の非同期処理に対する深い知識が必要になると思います。
         | 
| 21 | 
            -
             | 
| 22 | 
            -
            ※ | 
| 17 | 
            +
            ※
         | 
| 23 18 | 
             
            async def play_song
         | 
| 24 19 | 
             
            async def on_message
         | 
| 25 20 | 
             
            はこの順番に書かないとエラーになると思います。
         | 
6
    
        answer	
    CHANGED
    
    | @@ -52,8 +52,6 @@ | |
| 52 52 | 
             
                msg = await que.get()
         | 
| 53 53 | 
             
                url = msg.content[6:]
         | 
| 54 54 |  | 
| 55 | 
            -
                # youtubeから音楽をダウンロードする
         | 
| 56 | 
            -
                # TODO :TypeError: object NoneType can't be used in 'await' expression
         | 
| 57 55 | 
             
                await message.channel.send("DL now")
         | 
| 58 56 | 
             
                player = await YTDLSource.from_url(url, loop=client.loop)
         | 
| 59 57 | 
             
                # 再生する
         | 
5
修正
    
        answer	
    CHANGED
    
    | @@ -7,7 +7,7 @@ | |
| 7 7 | 
             
                # 再生する
         | 
| 8 8 | 
             
                loop = asyncio.get_event_loop()
         | 
| 9 9 | 
             
                message.guild.voice_client.play(player,
         | 
| 10 | 
            -
                    after=lambda _: loop.create_task( | 
| 10 | 
            +
                    after=lambda _: loop.create_task(play_song(message))
         | 
| 11 11 | 
             
                )
         | 
| 12 12 | 
             
            ```
         | 
| 13 13 |  | 
| @@ -21,7 +21,6 @@ | |
| 21 21 |  | 
| 22 22 | 
             
            ※2
         | 
| 23 23 | 
             
            async def play_song
         | 
| 24 | 
            -
            async def next_play
         | 
| 25 24 | 
             
            async def on_message
         | 
| 26 25 | 
             
            はこの順番に書かないとエラーになると思います。
         | 
| 27 26 |  | 
| @@ -60,15 +59,10 @@ | |
| 60 59 | 
             
                # 再生する
         | 
| 61 60 | 
             
                loop = asyncio.get_event_loop()
         | 
| 62 61 | 
             
                message.guild.voice_client.play(player,
         | 
| 63 | 
            -
                    after=lambda _: loop.create_task( | 
| 62 | 
            +
                    after=lambda _: loop.create_task(play_song(message))
         | 
| 64 63 | 
             
                )
         | 
| 65 64 | 
             
                await message.channel.send('{} を再生します。'.format(player.title))
         | 
| 66 65 |  | 
| 67 | 
            -
            # 再生終了後に実行する処理
         | 
| 68 | 
            -
            async def next_play(message):
         | 
| 69 | 
            -
                if not que.empty() and not message.guild.voice_client.is_playing():
         | 
| 70 | 
            -
                    await play_song(message)
         | 
| 71 | 
            -
             | 
| 72 66 | 
             
            # メッセージ受信時に動作する処理
         | 
| 73 67 | 
             
            @client.event
         | 
| 74 68 | 
             
            async def on_message(message):
         | 
| @@ -87,6 +81,6 @@ | |
| 87 81 | 
             
                    # キューに曲を入れる
         | 
| 88 82 | 
             
                    await que.put(message)
         | 
| 89 83 | 
             
                    await message.channel.send("キューに追加しました")
         | 
| 90 | 
            -
                    await  | 
| 84 | 
            +
                    await play_song(message)
         | 
| 91 85 |  | 
| 92 86 | 
             
            ```
         | 
4
    
        answer	
    CHANGED
    
    | @@ -21,7 +21,7 @@ | |
| 21 21 |  | 
| 22 22 | 
             
            ※2
         | 
| 23 23 | 
             
            async def play_song
         | 
| 24 | 
            -
            async def  | 
| 24 | 
            +
            async def next_play
         | 
| 25 25 | 
             
            async def on_message
         | 
| 26 26 | 
             
            はこの順番に書かないとエラーになると思います。
         | 
| 27 27 |  | 
3
    
        answer	
    CHANGED
    
    | @@ -19,6 +19,12 @@ | |
| 19 19 |  | 
| 20 20 | 
             
            安定した高機能なものを作ろうとする場合、discord.py の内部構造や python の非同期処理に対する深い知識が必要になると思います。
         | 
| 21 21 |  | 
| 22 | 
            +
            ※2
         | 
| 23 | 
            +
            async def play_song
         | 
| 24 | 
            +
            async def after
         | 
| 25 | 
            +
            async def on_message
         | 
| 26 | 
            +
            はこの順番に書かないとエラーになると思います。
         | 
| 27 | 
            +
             
         | 
| 22 28 | 
             
            ```python
         | 
| 23 29 | 
             
            # インストールした discord.py を読み込む
         | 
| 24 30 | 
             
            import asyncio
         | 
2
    
        answer	
    CHANGED
    
    | @@ -1,8 +1,19 @@ | |
| 1 1 | 
             
            記載の通りasyncio.Queue() で対応できます。
         | 
| 2 2 | 
             
            「再生が終わったら、次の曲」という動作は、play 関数 の after 引数に、終わった後に実行する関数を指定することで一応実現できます。
         | 
| 3 3 |  | 
| 4 | 
            +
            ただし今回は実行対象がコルーチンなので少し工夫が必要です。
         | 
| 4 | 
            -
             | 
| 5 | 
            +
            (lambda と Eventloop.create_task() を使う。↓の部分です)
         | 
| 6 | 
            +
            ```python
         | 
| 7 | 
            +
                # 再生する
         | 
| 8 | 
            +
                loop = asyncio.get_event_loop()
         | 
| 9 | 
            +
                message.guild.voice_client.play(player,
         | 
| 10 | 
            +
                    after=lambda _: loop.create_task(next_play(message))
         | 
| 11 | 
            +
                )
         | 
| 12 | 
            +
            ```
         | 
| 5 13 |  | 
| 14 | 
            +
            ---
         | 
| 15 | 
            +
            <コード>
         | 
| 16 | 
            +
             | 
| 6 17 | 
             
            ※下記は一応動作はしますがコンセプトであって完璧なものではないことにご注意ください。
         | 
| 7 18 | 
             
            再生中のキュー処理や停止時のエラー処理の面で、厳密に考慮すべき点をすっ飛ばしてますので、使ってるうちにどこかでエラーが発生して強制停止する可能性がゼロではありません。
         | 
| 8 19 |  | 
1
    
        answer	
    CHANGED
    
    | @@ -13,17 +13,17 @@ | |
| 13 13 | 
             
            import asyncio
         | 
| 14 14 | 
             
            略
         | 
| 15 15 |  | 
| 16 | 
            +
             | 
| 17 | 
            +
            # 追加:曲URLを含むメッセージ(!play https;//www.~~)を入れるキュー
         | 
| 16 | 
            -
            que = asyncio.Queue() | 
| 18 | 
            +
            que = asyncio.Queue() 
         | 
| 19 | 
            +
             | 
| 20 | 
            +
            # 以降 async def play_song(message): まで変えていません。
         | 
| 17 21 | 
             
            # Suppress noise about console usage from errors
         | 
| 18 22 | 
             
            youtube_dl.utils.bug_reports_message = lambda: ''
         | 
| 19 | 
            -
             | 
| 20 | 
            -
             | 
| 23 | 
            +
            .....
         | 
| 24 | 
            +
            ...
         | 
| 21 25 | 
             
            略
         | 
| 22 | 
            -
            ffmpeg_options = {
         | 
| 23 | 
            -
            略
         | 
| 24 26 |  | 
| 25 | 
            -
            class YTDLSource(discord.PCMVolumeTransformer):
         | 
| 26 | 
            -
            略
         | 
| 27 27 |  | 
| 28 28 | 
             
            async def play_song(message):
         | 
| 29 29 | 
             
                # 再生中の場合は再生しない
         | 
