mirror of
https://github.com/Rapptz/discord.py.git
synced 2025-04-20 16:00:29 +00:00
Make VoiceClient.create_ytdl_player a coroutine.
This is a breaking change. The reason to make it a coroutine is so that the info retrieval is not blocking since there are rare instances where it would take an abnormally long time. The player returned is also augmented to have more attributes relating to the stream itself.
This commit is contained in:
parent
b4604fa3f6
commit
1cd3c0b5cb
@ -48,6 +48,8 @@ import struct
|
||||
import threading
|
||||
import subprocess
|
||||
import shlex
|
||||
import functools
|
||||
import datetime
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -124,7 +126,6 @@ class ProcessPlayer(StreamPlayer):
|
||||
self.process.kill()
|
||||
super().stop()
|
||||
|
||||
|
||||
class VoiceClient:
|
||||
"""Represents a Discord voice connection.
|
||||
|
||||
@ -416,8 +417,11 @@ class VoiceClient:
|
||||
raise ClientException('Popen failed: {0.__name__} {1}'.format(type(e), str(e))) from e
|
||||
|
||||
|
||||
@asyncio.coroutine
|
||||
def create_ytdl_player(self, url, *, ytdl_options=None, **kwargs):
|
||||
"""Creates a stream player for youtube or other services that launches
|
||||
"""|coro|
|
||||
|
||||
Creates a stream player for youtube or other services that launches
|
||||
in a separate thread to play the audio.
|
||||
|
||||
The player uses the ``youtube_dl`` python library to get the information
|
||||
@ -429,7 +433,38 @@ class VoiceClient:
|
||||
variable in order for this to work.
|
||||
|
||||
The operations that can be done on the player are the same as those in
|
||||
:meth:`create_stream_player`.
|
||||
:meth:`create_stream_player`. The player has been augmented and enhanced
|
||||
to have some info extracted from the URL. If youtube-dl fails to extract
|
||||
the information then the attribute is ``None``. The ``yt``, ``url``, and
|
||||
``download_url`` attributes are always available.
|
||||
|
||||
+---------------------+---------------------------------------------------------+
|
||||
| Operation | Description |
|
||||
+=====================+=========================================================+
|
||||
| player.yt | The `YoutubeDL <ytdl>` instance. |
|
||||
+---------------------+---------------------------------------------------------+
|
||||
| player.url | The URL that is currently playing. |
|
||||
+---------------------+---------------------------------------------------------+
|
||||
| player.download_url | The URL that is currently being downloaded to ffmpeg. |
|
||||
+---------------------+---------------------------------------------------------+
|
||||
| player.title | The title of the audio stream. |
|
||||
+---------------------+---------------------------------------------------------+
|
||||
| player.description | The description of the audio stream. |
|
||||
+---------------------+---------------------------------------------------------+
|
||||
| player.uploader | The uploader of the audio stream. |
|
||||
+---------------------+---------------------------------------------------------+
|
||||
| player.upload_date | A datetime.date object of when the stream was uploaded. |
|
||||
+---------------------+---------------------------------------------------------+
|
||||
| player.duration | The duration of the audio in seconds. |
|
||||
+---------------------+---------------------------------------------------------+
|
||||
| player.likes | How many likes the audio stream has. |
|
||||
+---------------------+---------------------------------------------------------+
|
||||
| player.dislikes | How many dislikes the audio stream has. |
|
||||
+---------------------+---------------------------------------------------------+
|
||||
| player.is_live | Checks if the audio stream is currently livestreaming. |
|
||||
+---------------------+---------------------------------------------------------+
|
||||
| player.views | How many views the audio stream has. |
|
||||
+---------------------+---------------------------------------------------------+
|
||||
|
||||
.. _ytdl: https://github.com/rg3/youtube-dl/blob/master/youtube_dl/YoutubeDL.py#L117-L265
|
||||
|
||||
@ -438,8 +473,8 @@ class VoiceClient:
|
||||
|
||||
Basic usage: ::
|
||||
|
||||
voice = yield from client.join_voice_channel(channel)
|
||||
player = voice.create_ytdl_player('https://www.youtube.com/watch?v=d62TYemN6MQ')
|
||||
voice = await client.join_voice_channel(channel)
|
||||
player = await voice.create_ytdl_player('https://www.youtube.com/watch?v=d62TYemN6MQ')
|
||||
player.start()
|
||||
|
||||
Parameters
|
||||
@ -462,14 +497,14 @@ class VoiceClient:
|
||||
Returns
|
||||
--------
|
||||
StreamPlayer
|
||||
A stream player with specific operations.
|
||||
See :meth:`create_stream_player`.
|
||||
An augmented StreamPlayer that uses ffmpeg.
|
||||
See :meth:`create_stream_player` for base operations.
|
||||
"""
|
||||
import youtube_dl
|
||||
|
||||
use_avconv = kwargs.get('use_avconv', False)
|
||||
opts = {
|
||||
'format': 'webm[abr>0]' if 'youtube' in url else 'best',
|
||||
'format': 'webm[abr>0]/bestaudio/best',
|
||||
'prefer_ffmpeg': not use_avconv
|
||||
}
|
||||
|
||||
@ -477,9 +512,42 @@ class VoiceClient:
|
||||
opts.update(ytdl_options)
|
||||
|
||||
ydl = youtube_dl.YoutubeDL(opts)
|
||||
info = ydl.extract_info(url, download=False)
|
||||
func = functools.partial(ydl.extract_info, url, download=False)
|
||||
info = yield from self.loop.run_in_executor(None, func)
|
||||
log.info('playing URL {}'.format(url))
|
||||
return self.create_ffmpeg_player(info['url'], **kwargs)
|
||||
download_url = info['url']
|
||||
player = self.create_ffmpeg_player(download_url, **kwargs)
|
||||
|
||||
# set the dynamic attributes from the info extraction
|
||||
player.download_url = download_url
|
||||
player.url = url
|
||||
player.yt = ydl
|
||||
player.views = info.get('view_count')
|
||||
player.is_live = bool(info.get('is_live'))
|
||||
player.likes = info.get('like_count')
|
||||
player.dislikes = info.get('dislike_count')
|
||||
player.duration = info.get('duration')
|
||||
player.uploader = info.get('uploader')
|
||||
|
||||
is_twitch = 'twitch' in url
|
||||
if is_twitch:
|
||||
# twitch has 'title' and 'description' sort of mixed up.
|
||||
player.title = info.get('description')
|
||||
player.description = None
|
||||
else:
|
||||
player.title = info.get('title')
|
||||
player.description = info.get('description')
|
||||
|
||||
# upload date handling
|
||||
date = info.get('upload_date')
|
||||
if date:
|
||||
try:
|
||||
date = datetime.datetime.strptime(date, '%Y%M%d').date()
|
||||
except ValueError:
|
||||
date = None
|
||||
|
||||
player.upload_date = date
|
||||
return player
|
||||
|
||||
def encoder_options(self, *, sample_rate, channels=2):
|
||||
"""Sets the encoder options for the OpusEncoder.
|
||||
|
Loading…
x
Reference in New Issue
Block a user