From 7e78f6a8a84effec68e8345c479cb1fa9c42174f Mon Sep 17 00:00:00 2001 From: lersveen <7195448+lersveen@users.noreply.github.com> Date: Mon, 8 Jan 2024 21:37:47 +0100 Subject: [PATCH 1/2] Add support for NRK TV and NRK Radio apps --- examples/nrkradio_example.py | 73 ++++++++++++++++++++++++++++ examples/nrktv_example.py | 73 ++++++++++++++++++++++++++++ pychromecast/config.py | 2 + pychromecast/controllers/nrkradio.py | 21 ++++++++ pychromecast/controllers/nrktv.py | 20 ++++++++ pychromecast/quick_play.py | 6 +++ 6 files changed, 195 insertions(+) create mode 100644 examples/nrkradio_example.py create mode 100644 examples/nrktv_example.py create mode 100644 pychromecast/controllers/nrkradio.py create mode 100644 pychromecast/controllers/nrktv.py diff --git a/examples/nrkradio_example.py b/examples/nrkradio_example.py new file mode 100644 index 000000000..e79cdaac9 --- /dev/null +++ b/examples/nrkradio_example.py @@ -0,0 +1,73 @@ +""" +Example on how to use the NRK Radio Controller +""" +# pylint: disable=invalid-name + +import argparse +import logging +import sys +from time import sleep + +import zeroconf + +import pychromecast +from pychromecast import quick_play + +# Change to the friendly name of your Chromecast +CAST_NAME = "Living Room" + +# Note: Media ID can be found in the URL, e.g: +# For the live channel https://radio.nrk.no/direkte/p1, the media ID is p1 +# For the podcast https://radio.nrk.no/podkast/tazte_priv/l_8457deb0-4f2c-4ef3-97de-b04f2c6ef314, +# the media ID is l_8457deb0-4f2c-4ef3-97de-b04f2c6ef314 +# For the on-demand program https://radio.nrk.no/serie/radiodokumentaren/sesong/201011/MDUP01004510, +# the media id is MDUP01004510 +MEDIA_ID = "l_8457deb0-4f2c-4ef3-97de-b04f2c6ef314" + +parser = argparse.ArgumentParser( + description="Example on how to use the NRK Radio Controller to play a media stream." +) +parser.add_argument( + "--cast", help='Name of cast device (default: "%(default)s")', default=CAST_NAME +) +parser.add_argument( + "--known-host", + help="Add known host (IP), can be used multiple times", + action="append", +) +parser.add_argument("--show-debug", help="Enable debug log", action="store_true") +parser.add_argument( + "--show-zeroconf-debug", help="Enable zeroconf debug log", action="store_true" +) +parser.add_argument( + "--media_id", help='MediaID (default: "%(default)s")', default=MEDIA_ID +) +args = parser.parse_args() + +if args.show_debug: + logging.basicConfig(level=logging.DEBUG) +if args.show_zeroconf_debug: + print("Zeroconf version: " + zeroconf.__version__) + logging.getLogger("zeroconf").setLevel(logging.DEBUG) + +chromecasts, browser = pychromecast.get_listed_chromecasts( + friendly_names=[args.cast], known_hosts=args.known_host +) +if not chromecasts: + print(f'No chromecast with name "{args.cast}" discovered') + sys.exit(1) + +cast = chromecasts[0] +# Start socket client's worker thread and wait for initial status update +cast.wait() +print(f'Found chromecast with name "{args.cast}", attempting to play "{args.media_id}"') + +app_name = "nrkradio" +app_data = { + "media_id": args.media_id, +} +quick_play.quick_play(cast, app_name, app_data) + +sleep(10) + +browser.stop_discovery() diff --git a/examples/nrktv_example.py b/examples/nrktv_example.py new file mode 100644 index 000000000..617bc3888 --- /dev/null +++ b/examples/nrktv_example.py @@ -0,0 +1,73 @@ +""" +Example on how to use the NRK TV Controller +""" +# pylint: disable=invalid-name + +import argparse +import logging +import sys +from time import sleep + +import zeroconf + +import pychromecast +from pychromecast import quick_play + +# Change to the friendly name of your Chromecast +CAST_NAME = "Living Room" + +# Note: Media ID for live programs can be found in the URL +# e.g. for https://tv.nrk.no/direkte/nrk1, the media ID is nrk1 +# Media ID for non-live programs can be found by clicking the share button +# e.g. https://tv.nrk.no/serie/uti-vaar-hage/sesong/2/episode/2 shows: +# "https://tv.nrk.no/se?v=OUHA43000207", the media ID is OUHA43000207 +MEDIA_ID = "OUHA43000207" + +parser = argparse.ArgumentParser( + description="Example on how to use the NRK TV Controller to play a media stream." +) +parser.add_argument( + "--cast", help='Name of cast device (default: "%(default)s")', default=CAST_NAME +) +parser.add_argument( + "--known-host", + help="Add known host (IP), can be used multiple times", + action="append", +) +parser.add_argument("--show-debug", help="Enable debug log", action="store_true") +parser.add_argument( + "--show-zeroconf-debug", help="Enable zeroconf debug log", action="store_true" +) +parser.add_argument( + "--media_id", help='MediaID (default: "%(default)s")', default=MEDIA_ID +) + +args = parser.parse_args() + +if args.show_debug: + logging.basicConfig(level=logging.DEBUG) +if args.show_zeroconf_debug: + print("Zeroconf version: " + zeroconf.__version__) + logging.getLogger("zeroconf").setLevel(logging.DEBUG) + +chromecasts, browser = pychromecast.get_listed_chromecasts( + friendly_names=[args.cast], known_hosts=args.known_host +) +if not chromecasts: + print(f'No chromecast with name "{args.cast}" discovered') + sys.exit(1) + +cast = chromecasts[0] +# Start socket client's worker thread and wait for initial status update +cast.wait() +print(f'Found chromecast with name "{args.cast}", attempting to play "{args.media_id}"') + +app_name = "nrktv" +app_data = { + "media_id": args.media_id, +} +quick_play.quick_play(cast, app_name, app_data) + +sleep(10) + +browser.stop_discovery() diff --git a/pychromecast/config.py b/pychromecast/config.py index 6ee066812..744bb2d5f 100644 --- a/pychromecast/config.py +++ b/pychromecast/config.py @@ -18,6 +18,8 @@ APP_BBCSOUNDS = "D350F6A9" APP_BBCIPLAYER = "5E81F6DB" APP_SHAKA = "07AEE832" +APP_NRKTV = "3AEDF8D1" +APP_NRKRADIO = "A49874B1" def get_possible_app_ids(): diff --git a/pychromecast/controllers/nrkradio.py b/pychromecast/controllers/nrkradio.py new file mode 100644 index 000000000..4c368a8ff --- /dev/null +++ b/pychromecast/controllers/nrkradio.py @@ -0,0 +1,21 @@ +""" +Controller to interface with NRK Radio. +""" +# Note: Media ID can be found in the URL, e.g: +# For the live channel https://radio.nrk.no/direkte/p1, the media ID is p1 +# For the podcast https://radio.nrk.no/podkast/tazte_priv/l_8457deb0-4f2c-4ef3-97de-b04f2c6ef314, +# the Media ID is l_8457deb0-4f2c-4ef3-97de-b04f2c6ef314 +# For the on-demand program https://radio.nrk.no/serie/radiodokumentaren/sesong/201011/MDUP01004510, +# the media id is MDUP01004510 + +from .media import BaseMediaPlayer +from ..config import APP_NRKRADIO + +APP_NAMESPACE = "urn:x-cast:com.google.cast.media" + + +class NrkRadioController(BaseMediaPlayer): + """Controller to interact with NRK Radio.""" + + def __init__(self): + super().__init__(supporting_app_id=APP_NRKRADIO) diff --git a/pychromecast/controllers/nrktv.py b/pychromecast/controllers/nrktv.py new file mode 100644 index 000000000..24ce78c8f --- /dev/null +++ b/pychromecast/controllers/nrktv.py @@ -0,0 +1,20 @@ +""" +Controller to interface with NRK TV. +""" +# Note: Media ID for live programs can be found in the URL +# e.g. for https://tv.nrk.no/direkte/nrk1, the media ID is nrk1 +# Media ID for non-live programs can be found by clicking the share button +# e.g. https://tv.nrk.no/serie/uti-vaar-hage/sesong/2/episode/2 shows: +# "https://tv.nrk.no/se?v=OUHA43000207", the media ID is OUHA43000207 + +from .media import BaseMediaPlayer +from ..config import APP_NRKTV + +APP_NAMESPACE = "urn:x-cast:com.google.cast.media" + + +class NrkTvController(BaseMediaPlayer): + """Controller to interact with NRK TV.""" + + def __init__(self): + super().__init__(supporting_app_id=APP_NRKTV) diff --git a/pychromecast/quick_play.py b/pychromecast/quick_play.py index da712df4d..f4a1d4948 100644 --- a/pychromecast/quick_play.py +++ b/pychromecast/quick_play.py @@ -9,6 +9,8 @@ from .controllers.yleareena import YleAreenaController from .controllers.youtube import YouTubeController from .controllers.shaka import ShakaController +from .controllers.nrktv import NrkTvController +from .controllers.nrkradio import NrkRadioController def quick_play(cast, app_name, data): @@ -72,6 +74,10 @@ def quick_play(cast, app_name, data): controller = YouTubeController() elif app_name == "shaka": controller = ShakaController() + elif app_name == "nrktv": + controller = NrkTvController() + elif app_name == "nrkradio": + controller = NrkRadioController() else: raise NotImplementedError() From c85763a4566af44047f74b98b960033427c7937b Mon Sep 17 00:00:00 2001 From: Erik Montnemery Date: Wed, 10 Jan 2024 17:41:05 +0100 Subject: [PATCH 2/2] Update pychromecast/quick_play.py --- pychromecast/quick_play.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pychromecast/quick_play.py b/pychromecast/quick_play.py index f4a1d4948..bfca73fbc 100644 --- a/pychromecast/quick_play.py +++ b/pychromecast/quick_play.py @@ -13,7 +13,7 @@ from .controllers.nrkradio import NrkRadioController -def quick_play(cast, app_name, data): +def quick_play(cast, app_name, data): # pylint:disable=too-many-branches """ Given a Chromecast connection, launch the app `app_name` and start playing media based on parameters defined in `data`.