From 81983e159ad15ddada6fd5a6b4b74b283a8cce46 Mon Sep 17 00:00:00 2001 From: Eerovil Date: Thu, 10 Dec 2020 23:10:06 +0200 Subject: [PATCH] Add support for BubbleUPNP (#428) * Add bubbleupnp media controller * Fix argument names * Linter fixes --- examples/bubbleupnp_example.py | 36 ++++++++++++++++++++++++++ pychromecast/config.py | 1 + pychromecast/controllers/bubbleupnp.py | 20 ++++++++++++++ pychromecast/quick_play.py | 9 +++++++ 4 files changed, 66 insertions(+) create mode 100644 examples/bubbleupnp_example.py create mode 100644 pychromecast/controllers/bubbleupnp.py diff --git a/examples/bubbleupnp_example.py b/examples/bubbleupnp_example.py new file mode 100644 index 000000000..987925f82 --- /dev/null +++ b/examples/bubbleupnp_example.py @@ -0,0 +1,36 @@ +""" +Example on how to use the BubbleUPNP Controller + +""" +import logging +import sys +from time import sleep + +import pychromecast +from pychromecast.controllers.bubbleupnp import BubbleUPNPController + + +# Change to the name of your Chromecast +CAST_NAME = "Kitchen speaker" + +URL = "https://c3.toivon.net/toivon/toivon_3?mp=/stream" + +logging.basicConfig(level=logging.DEBUG) + +# pylint: disable=unbalanced-tuple-unpacking +chromecasts, browser = pychromecast.get_listed_chromecasts(friendly_names=[CAST_NAME]) +if not chromecasts: + print('No chromecast with name "{}" discovered'.format(CAST_NAME)) + sys.exit(1) + +cast = list(chromecasts)[0] +# Start socket client's worker thread and wait for initial status update +cast.wait() + +bubbleupnp = BubbleUPNPController() +cast.register_handler(bubbleupnp) +bubbleupnp.launch() +bubbleupnp.play_media(URL, "audio/mp3", stream_type="LIVE") +cast.wait() + +sleep(10) diff --git a/pychromecast/config.py b/pychromecast/config.py index e0453709b..b9855c645 100644 --- a/pychromecast/config.py +++ b/pychromecast/config.py @@ -14,6 +14,7 @@ APP_HOME_ASSISTANT = "B12CE3CA" APP_SUPLA = "A41B766D" APP_YLEAREENA = "A9BCCB7C" +APP_BUBBLEUPNP = "3927FA74" def get_possible_app_ids(): diff --git a/pychromecast/controllers/bubbleupnp.py b/pychromecast/controllers/bubbleupnp.py new file mode 100644 index 000000000..cbe5798fc --- /dev/null +++ b/pychromecast/controllers/bubbleupnp.py @@ -0,0 +1,20 @@ +""" +Simple Controller to use BubbleUPNP as a media controller. +""" + +from ..config import APP_BUBBLEUPNP +from .media import MediaController + + +class BubbleUPNPController(MediaController): + """ Controller to interact with BubbleUPNP app namespace. """ + + # pylint: disable=useless-super-delegation + def __init__(self): + super(BubbleUPNPController, self).__init__() + self.app_id = APP_BUBBLEUPNP + self.supporting_app_id = APP_BUBBLEUPNP + + def quick_play(self, media_id=None, media_type="video/mp4", **kwargs): + """ Quick Play """ + self.play_media(media_id, media_type, **kwargs) diff --git a/pychromecast/quick_play.py b/pychromecast/quick_play.py index fb36791cf..383508cc6 100644 --- a/pychromecast/quick_play.py +++ b/pychromecast/quick_play.py @@ -3,6 +3,7 @@ from .controllers.youtube import YouTubeController from .controllers.supla import SuplaController from .controllers.yleareena import YleAreenaController +from .controllers.bubbleupnp import BubbleUPNPController def quick_play(cast, app_name, data): @@ -24,6 +25,8 @@ def quick_play(cast, app_name, data): media_type: string Type of the media identified by `media_id`. e.g. "program" if the media is a program name instead of a direct item id. + When using a regular media controller (e.g. BubbleUPNP) this should be the + content_type ('audio/mp3') enqueue: boolean Enqueue the media to the current playlist, if possible. index: string @@ -40,6 +43,10 @@ def quick_play(cast, app_name, data): Supla-specific: is_live: boolean Whether the media is a livestream + + Media controller (BubbleUPNP)-specific: + stream_type: string + "BUFFERED" or "LIVE" """ if app_name == "youtube": @@ -48,6 +55,8 @@ def quick_play(cast, app_name, data): controller = SuplaController() elif app_name == "yleareena": controller = YleAreenaController() + elif app_name == "bubbleupnp": + controller = BubbleUPNPController() else: raise NotImplementedError()