From 6fcc3a2397dc23b595f46c34a9d3482f8809046f Mon Sep 17 00:00:00 2001 From: Fabio Manganiello Date: Tue, 13 Nov 2018 20:20:55 +0100 Subject: [PATCH] Support for YouTube media in Chromecast plugin --- platypush/plugins/media/chromecast.py | 60 +++++++++++++++++++++++---- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/platypush/plugins/media/chromecast.py b/platypush/plugins/media/chromecast.py index 32ba7f04..ae8c80d2 100644 --- a/platypush/plugins/media/chromecast.py +++ b/platypush/plugins/media/chromecast.py @@ -1,5 +1,8 @@ +import re import pychromecast +from pychromecast.controllers.youtube import YouTubeController + from platypush.plugins import Plugin, action @@ -7,6 +10,11 @@ class MediaChromecastPlugin(Plugin): """ Plugin to interact with Chromecast devices + Supported formats: + + * YouTube URLs + * Plex (through ``media.plex`` plugin, experimental) + Requires: * **pychromecast** (``pip install pychromecast``) @@ -67,16 +75,19 @@ class MediaChromecastPlugin(Plugin): if chromecast not in self.chromecasts: - self.chromecasts = pychromecast.get_chromecasts() - cast = next(cc for cc in self.chromecasts - if cc.device.friendly_name == chromecast) - else: - cast = self.chromecasts[chromecast] + self.chromecasts = { + cast.device.friendly_name: cast + for cast in pychromecast.get_chromecasts() + } + + if chromecast not in self.chromecasts: + raise RuntimeError('Device {} not found'.format(chromecast)) + + return self.chromecasts[chromecast] - return cast @action - def cast_media(self, media, content_type, chromecast=None, title=None, + def cast_media(self, media, content_type=None, chromecast=None, title=None, image_url=None, autoplay=True, current_time=0, stream_type=STREAM_TYPE_BUFFERED, subtitles=None, subtitles_lang='en-US', subtitles_mime='text/vtt', @@ -121,10 +132,29 @@ class MediaChromecastPlugin(Plugin): :type subtitle_id: int """ + if not chromecast: + chromecast = self.chromecast + cast = self.get_chromecast(chromecast) cast.wait() + mc = cast.media_controller - mc.namespace = 'urn:x-cast:com.google.cast.sse' + yt = self._get_youtube_url(media) + + if yt: + self.logger.info('Playing YouTube video {} on {}'.format( + yt, chromecast)) + + hndl = YouTubeController() + cast.register_handler(hndl) + hndl.update_screen_id() + return hndl.play_video(yt) + + if not content_type: + raise RuntimeError('content_type required to process media {}'. + format(media)) + + self.logger.info('Playing {} on {}'.format(media, chromecast)) mc.play_media(media, content_type, title=title, thumb=image_url, current_time=current_time, autoplay=autoplay, @@ -134,6 +164,20 @@ class MediaChromecastPlugin(Plugin): mc.block_until_active() + + @classmethod + def _get_youtube_url(cls, url): + m = re.match('https?://www.youtube.com/watch\?v=([^&]+).*', url) + if m: + return m.group(1) + + m = re.match('youtube:video:(.*)', url) + if m: + return m.group(1) + + return None + + @action def disconnect(self, chromecast=None, timeout=None, blocking=True): """